From 91aa267eda21be36d7cae43b6809eba63f1aac4c Mon Sep 17 00:00:00 2001 From: Aaron Aaeng Date: Sat, 21 Apr 2018 16:06:48 -0600 Subject: [PATCH] Make must_use lint cover all binary/unary operators --- src/libcore/ops/arith.rs | 6 ++ src/libcore/ops/bit.rs | 6 ++ src/libcore/ops/deref.rs | 1 + src/librustc_lint/unused.rs | 42 ++++++--- src/test/ui/lint/must-use-ops.rs | 52 +++++++++++ src/test/ui/lint/must-use-ops.stderr | 132 +++++++++++++++++++++++++++ 6 files changed, 224 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/lint/must-use-ops.rs create mode 100644 src/test/ui/lint/must-use-ops.stderr diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 88db019b02f07..8fd06e7bb4b9b 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -93,6 +93,7 @@ pub trait Add { type Output; /// Performs the `+` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn add(self, rhs: RHS) -> Self::Output; } @@ -189,6 +190,7 @@ pub trait Sub { type Output; /// Performs the `-` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn sub(self, rhs: RHS) -> Self::Output; } @@ -307,6 +309,7 @@ pub trait Mul { type Output; /// Performs the `*` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn mul(self, rhs: RHS) -> Self::Output; } @@ -429,6 +432,7 @@ pub trait Div { type Output; /// Performs the `/` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn div(self, rhs: RHS) -> Self::Output; } @@ -512,6 +516,7 @@ pub trait Rem { type Output = Self; /// Performs the `%` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn rem(self, rhs: RHS) -> Self::Output; } @@ -595,6 +600,7 @@ pub trait Neg { type Output; /// Performs the unary `-` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn neg(self) -> Self::Output; } diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs index 81c4455cef4d9..9bde02abe6471 100644 --- a/src/libcore/ops/bit.rs +++ b/src/libcore/ops/bit.rs @@ -46,6 +46,7 @@ pub trait Not { type Output; /// Performs the unary `!` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn not(self) -> Self::Output; } @@ -128,6 +129,7 @@ pub trait BitAnd { type Output; /// Performs the `&` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn bitand(self, rhs: RHS) -> Self::Output; } @@ -210,6 +212,7 @@ pub trait BitOr { type Output; /// Performs the `|` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn bitor(self, rhs: RHS) -> Self::Output; } @@ -295,6 +298,7 @@ pub trait BitXor { type Output; /// Performs the `^` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn bitxor(self, rhs: RHS) -> Self::Output; } @@ -381,6 +385,7 @@ pub trait Shl { type Output; /// Performs the `<<` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn shl(self, rhs: RHS) -> Self::Output; } @@ -488,6 +493,7 @@ pub trait Shr { type Output; /// Performs the `>>` operation. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn shr(self, rhs: RHS) -> Self::Output; } diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs index 4ce0740130b98..3903e85768c3c 100644 --- a/src/libcore/ops/deref.rs +++ b/src/libcore/ops/deref.rs @@ -75,6 +75,7 @@ pub trait Deref { type Target: ?Sized; /// Dereferences the value. + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn deref(&self) -> &Self::Target; } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index bf86f6a69522f..5ec8305de788c 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -91,23 +91,35 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let def_id = def.def_id(); fn_warned = check_must_use(cx, def_id, s.span, "return value of "); } - - if let hir::ExprBinary(bin_op, ..) = expr.node { - match bin_op.node { - // Hardcoding the comparison operators here seemed more - // expedient than the refactoring that would be needed to - // look up the `#[must_use]` attribute which does exist on - // the comparison trait methods - hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => { - let msg = "unused comparison which must be used"; - cx.span_lint(UNUSED_MUST_USE, expr.span, msg); - op_warned = true; - }, - _ => {}, - } + let must_use_op = match expr.node { + // Hardcoding operators here seemed more expedient than the + // refactoring that would be needed to look up the `#[must_use]` + // attribute which does exist on the comparison trait methods + hir::ExprBinary(bin_op, ..) => { + match bin_op.node { + hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => { + Some("comparison") + }, + hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => { + Some("arithmetic operation") + }, + hir::BiAnd | hir::BiOr => { + Some("logical operation") + }, + hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => { + Some("bitwise operation") + }, + } + }, + hir::ExprUnary(..) => Some("unary operation"), + _ => None + }; + if let Some(must_use_op) = must_use_op { + cx.span_lint(UNUSED_MUST_USE, expr.span, + &format!("unused {} which must be used", must_use_op)); + op_warned = true; } } - if !(ty_warned || fn_warned || op_warned) { cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/must-use-ops.rs new file mode 100644 index 0000000000000..4ed82ab3b4025 --- /dev/null +++ b/src/test/ui/lint/must-use-ops.rs @@ -0,0 +1,52 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Issue #50124 - Test warning for unused operator expressions + +// compile-pass + +#![feature(fn_must_use)] +#![warn(unused_must_use)] + +fn main() { + let val = 1; + let val_pointer = &val; + +// Comparison Operators + val == 1; + val < 1; + val <= 1; + val != 1; + val >= 1; + val > 1; + +// Arithmetic Operators + val + 2; + val - 2; + val / 2; + val * 2; + val % 2; + +// Logical Operators + true && true; + false || true; + +// Bitwise Operators + 5 ^ val; + 5 & val; + 5 | val; + 5 << val; + 5 >> val; + +// Unary Operators + !val; + -val; + *val_pointer; +} diff --git a/src/test/ui/lint/must-use-ops.stderr b/src/test/ui/lint/must-use-ops.stderr new file mode 100644 index 0000000000000..f444ef0907575 --- /dev/null +++ b/src/test/ui/lint/must-use-ops.stderr @@ -0,0 +1,132 @@ +warning: unused comparison which must be used + --> $DIR/must-use-ops.rs:23:5 + | +LL | val == 1; + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/must-use-ops.rs:16:9 + | +LL | #![warn(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +warning: unused comparison which must be used + --> $DIR/must-use-ops.rs:24:5 + | +LL | val < 1; + | ^^^^^^^ + +warning: unused comparison which must be used + --> $DIR/must-use-ops.rs:25:5 + | +LL | val <= 1; + | ^^^^^^^^ + +warning: unused comparison which must be used + --> $DIR/must-use-ops.rs:26:5 + | +LL | val != 1; + | ^^^^^^^^ + +warning: unused comparison which must be used + --> $DIR/must-use-ops.rs:27:5 + | +LL | val >= 1; + | ^^^^^^^^ + +warning: unused comparison which must be used + --> $DIR/must-use-ops.rs:28:5 + | +LL | val > 1; + | ^^^^^^^ + +warning: unused arithmetic operation which must be used + --> $DIR/must-use-ops.rs:31:5 + | +LL | val + 2; + | ^^^^^^^ + +warning: unused arithmetic operation which must be used + --> $DIR/must-use-ops.rs:32:5 + | +LL | val - 2; + | ^^^^^^^ + +warning: unused arithmetic operation which must be used + --> $DIR/must-use-ops.rs:33:5 + | +LL | val / 2; + | ^^^^^^^ + +warning: unused arithmetic operation which must be used + --> $DIR/must-use-ops.rs:34:5 + | +LL | val * 2; + | ^^^^^^^ + +warning: unused arithmetic operation which must be used + --> $DIR/must-use-ops.rs:35:5 + | +LL | val % 2; + | ^^^^^^^ + +warning: unused logical operation which must be used + --> $DIR/must-use-ops.rs:38:5 + | +LL | true && true; + | ^^^^^^^^^^^^ + +warning: unused logical operation which must be used + --> $DIR/must-use-ops.rs:39:5 + | +LL | false || true; + | ^^^^^^^^^^^^^ + +warning: unused bitwise operation which must be used + --> $DIR/must-use-ops.rs:42:5 + | +LL | 5 ^ val; + | ^^^^^^^ + +warning: unused bitwise operation which must be used + --> $DIR/must-use-ops.rs:43:5 + | +LL | 5 & val; + | ^^^^^^^ + +warning: unused bitwise operation which must be used + --> $DIR/must-use-ops.rs:44:5 + | +LL | 5 | val; + | ^^^^^^^ + +warning: unused bitwise operation which must be used + --> $DIR/must-use-ops.rs:45:5 + | +LL | 5 << val; + | ^^^^^^^^ + +warning: unused bitwise operation which must be used + --> $DIR/must-use-ops.rs:46:5 + | +LL | 5 >> val; + | ^^^^^^^^ + +warning: unused unary operation which must be used + --> $DIR/must-use-ops.rs:49:5 + | +LL | !val; + | ^^^^ + +warning: unused unary operation which must be used + --> $DIR/must-use-ops.rs:50:5 + | +LL | -val; + | ^^^^ + +warning: unused unary operation which must be used + --> $DIR/must-use-ops.rs:51:5 + | +LL | *val_pointer; + | ^^^^^^^^^^^^ +