Skip to content

Commit 91aa267

Browse files
committed
Make must_use lint cover all binary/unary operators
1 parent 222551f commit 91aa267

File tree

6 files changed

+224
-15
lines changed

6 files changed

+224
-15
lines changed

src/libcore/ops/arith.rs

+6
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub trait Add<RHS=Self> {
9393
type Output;
9494

9595
/// Performs the `+` operation.
96+
#[must_use]
9697
#[stable(feature = "rust1", since = "1.0.0")]
9798
fn add(self, rhs: RHS) -> Self::Output;
9899
}
@@ -189,6 +190,7 @@ pub trait Sub<RHS=Self> {
189190
type Output;
190191

191192
/// Performs the `-` operation.
193+
#[must_use]
192194
#[stable(feature = "rust1", since = "1.0.0")]
193195
fn sub(self, rhs: RHS) -> Self::Output;
194196
}
@@ -307,6 +309,7 @@ pub trait Mul<RHS=Self> {
307309
type Output;
308310

309311
/// Performs the `*` operation.
312+
#[must_use]
310313
#[stable(feature = "rust1", since = "1.0.0")]
311314
fn mul(self, rhs: RHS) -> Self::Output;
312315
}
@@ -429,6 +432,7 @@ pub trait Div<RHS=Self> {
429432
type Output;
430433

431434
/// Performs the `/` operation.
435+
#[must_use]
432436
#[stable(feature = "rust1", since = "1.0.0")]
433437
fn div(self, rhs: RHS) -> Self::Output;
434438
}
@@ -512,6 +516,7 @@ pub trait Rem<RHS=Self> {
512516
type Output = Self;
513517

514518
/// Performs the `%` operation.
519+
#[must_use]
515520
#[stable(feature = "rust1", since = "1.0.0")]
516521
fn rem(self, rhs: RHS) -> Self::Output;
517522
}
@@ -595,6 +600,7 @@ pub trait Neg {
595600
type Output;
596601

597602
/// Performs the unary `-` operation.
603+
#[must_use]
598604
#[stable(feature = "rust1", since = "1.0.0")]
599605
fn neg(self) -> Self::Output;
600606
}

src/libcore/ops/bit.rs

+6
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub trait Not {
4646
type Output;
4747

4848
/// Performs the unary `!` operation.
49+
#[must_use]
4950
#[stable(feature = "rust1", since = "1.0.0")]
5051
fn not(self) -> Self::Output;
5152
}
@@ -128,6 +129,7 @@ pub trait BitAnd<RHS=Self> {
128129
type Output;
129130

130131
/// Performs the `&` operation.
132+
#[must_use]
131133
#[stable(feature = "rust1", since = "1.0.0")]
132134
fn bitand(self, rhs: RHS) -> Self::Output;
133135
}
@@ -210,6 +212,7 @@ pub trait BitOr<RHS=Self> {
210212
type Output;
211213

212214
/// Performs the `|` operation.
215+
#[must_use]
213216
#[stable(feature = "rust1", since = "1.0.0")]
214217
fn bitor(self, rhs: RHS) -> Self::Output;
215218
}
@@ -295,6 +298,7 @@ pub trait BitXor<RHS=Self> {
295298
type Output;
296299

297300
/// Performs the `^` operation.
301+
#[must_use]
298302
#[stable(feature = "rust1", since = "1.0.0")]
299303
fn bitxor(self, rhs: RHS) -> Self::Output;
300304
}
@@ -381,6 +385,7 @@ pub trait Shl<RHS=Self> {
381385
type Output;
382386

383387
/// Performs the `<<` operation.
388+
#[must_use]
384389
#[stable(feature = "rust1", since = "1.0.0")]
385390
fn shl(self, rhs: RHS) -> Self::Output;
386391
}
@@ -488,6 +493,7 @@ pub trait Shr<RHS=Self> {
488493
type Output;
489494

490495
/// Performs the `>>` operation.
496+
#[must_use]
491497
#[stable(feature = "rust1", since = "1.0.0")]
492498
fn shr(self, rhs: RHS) -> Self::Output;
493499
}

src/libcore/ops/deref.rs

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub trait Deref {
7575
type Target: ?Sized;
7676

7777
/// Dereferences the value.
78+
#[must_use]
7879
#[stable(feature = "rust1", since = "1.0.0")]
7980
fn deref(&self) -> &Self::Target;
8081
}

src/librustc_lint/unused.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,35 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
9191
let def_id = def.def_id();
9292
fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
9393
}
94-
95-
if let hir::ExprBinary(bin_op, ..) = expr.node {
96-
match bin_op.node {
97-
// Hardcoding the comparison operators here seemed more
98-
// expedient than the refactoring that would be needed to
99-
// look up the `#[must_use]` attribute which does exist on
100-
// the comparison trait methods
101-
hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
102-
let msg = "unused comparison which must be used";
103-
cx.span_lint(UNUSED_MUST_USE, expr.span, msg);
104-
op_warned = true;
105-
},
106-
_ => {},
107-
}
94+
let must_use_op = match expr.node {
95+
// Hardcoding operators here seemed more expedient than the
96+
// refactoring that would be needed to look up the `#[must_use]`
97+
// attribute which does exist on the comparison trait methods
98+
hir::ExprBinary(bin_op, ..) => {
99+
match bin_op.node {
100+
hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
101+
Some("comparison")
102+
},
103+
hir::BiAdd | hir::BiSub | hir::BiDiv | hir::BiMul | hir::BiRem => {
104+
Some("arithmetic operation")
105+
},
106+
hir::BiAnd | hir::BiOr => {
107+
Some("logical operation")
108+
},
109+
hir::BiBitXor | hir::BiBitAnd | hir::BiBitOr | hir::BiShl | hir::BiShr => {
110+
Some("bitwise operation")
111+
},
112+
}
113+
},
114+
hir::ExprUnary(..) => Some("unary operation"),
115+
_ => None
116+
};
117+
if let Some(must_use_op) = must_use_op {
118+
cx.span_lint(UNUSED_MUST_USE, expr.span,
119+
&format!("unused {} which must be used", must_use_op));
120+
op_warned = true;
108121
}
109122
}
110-
111123
if !(ty_warned || fn_warned || op_warned) {
112124
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
113125
}

src/test/ui/lint/must-use-ops.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #50124 - Test warning for unused operator expressions
12+
13+
// compile-pass
14+
15+
#![feature(fn_must_use)]
16+
#![warn(unused_must_use)]
17+
18+
fn main() {
19+
let val = 1;
20+
let val_pointer = &val;
21+
22+
// Comparison Operators
23+
val == 1;
24+
val < 1;
25+
val <= 1;
26+
val != 1;
27+
val >= 1;
28+
val > 1;
29+
30+
// Arithmetic Operators
31+
val + 2;
32+
val - 2;
33+
val / 2;
34+
val * 2;
35+
val % 2;
36+
37+
// Logical Operators
38+
true && true;
39+
false || true;
40+
41+
// Bitwise Operators
42+
5 ^ val;
43+
5 & val;
44+
5 | val;
45+
5 << val;
46+
5 >> val;
47+
48+
// Unary Operators
49+
!val;
50+
-val;
51+
*val_pointer;
52+
}

src/test/ui/lint/must-use-ops.stderr

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
warning: unused comparison which must be used
2+
--> $DIR/must-use-ops.rs:23:5
3+
|
4+
LL | val == 1;
5+
| ^^^^^^^^
6+
|
7+
note: lint level defined here
8+
--> $DIR/must-use-ops.rs:16:9
9+
|
10+
LL | #![warn(unused_must_use)]
11+
| ^^^^^^^^^^^^^^^
12+
13+
warning: unused comparison which must be used
14+
--> $DIR/must-use-ops.rs:24:5
15+
|
16+
LL | val < 1;
17+
| ^^^^^^^
18+
19+
warning: unused comparison which must be used
20+
--> $DIR/must-use-ops.rs:25:5
21+
|
22+
LL | val <= 1;
23+
| ^^^^^^^^
24+
25+
warning: unused comparison which must be used
26+
--> $DIR/must-use-ops.rs:26:5
27+
|
28+
LL | val != 1;
29+
| ^^^^^^^^
30+
31+
warning: unused comparison which must be used
32+
--> $DIR/must-use-ops.rs:27:5
33+
|
34+
LL | val >= 1;
35+
| ^^^^^^^^
36+
37+
warning: unused comparison which must be used
38+
--> $DIR/must-use-ops.rs:28:5
39+
|
40+
LL | val > 1;
41+
| ^^^^^^^
42+
43+
warning: unused arithmetic operation which must be used
44+
--> $DIR/must-use-ops.rs:31:5
45+
|
46+
LL | val + 2;
47+
| ^^^^^^^
48+
49+
warning: unused arithmetic operation which must be used
50+
--> $DIR/must-use-ops.rs:32:5
51+
|
52+
LL | val - 2;
53+
| ^^^^^^^
54+
55+
warning: unused arithmetic operation which must be used
56+
--> $DIR/must-use-ops.rs:33:5
57+
|
58+
LL | val / 2;
59+
| ^^^^^^^
60+
61+
warning: unused arithmetic operation which must be used
62+
--> $DIR/must-use-ops.rs:34:5
63+
|
64+
LL | val * 2;
65+
| ^^^^^^^
66+
67+
warning: unused arithmetic operation which must be used
68+
--> $DIR/must-use-ops.rs:35:5
69+
|
70+
LL | val % 2;
71+
| ^^^^^^^
72+
73+
warning: unused logical operation which must be used
74+
--> $DIR/must-use-ops.rs:38:5
75+
|
76+
LL | true && true;
77+
| ^^^^^^^^^^^^
78+
79+
warning: unused logical operation which must be used
80+
--> $DIR/must-use-ops.rs:39:5
81+
|
82+
LL | false || true;
83+
| ^^^^^^^^^^^^^
84+
85+
warning: unused bitwise operation which must be used
86+
--> $DIR/must-use-ops.rs:42:5
87+
|
88+
LL | 5 ^ val;
89+
| ^^^^^^^
90+
91+
warning: unused bitwise operation which must be used
92+
--> $DIR/must-use-ops.rs:43:5
93+
|
94+
LL | 5 & val;
95+
| ^^^^^^^
96+
97+
warning: unused bitwise operation which must be used
98+
--> $DIR/must-use-ops.rs:44:5
99+
|
100+
LL | 5 | val;
101+
| ^^^^^^^
102+
103+
warning: unused bitwise operation which must be used
104+
--> $DIR/must-use-ops.rs:45:5
105+
|
106+
LL | 5 << val;
107+
| ^^^^^^^^
108+
109+
warning: unused bitwise operation which must be used
110+
--> $DIR/must-use-ops.rs:46:5
111+
|
112+
LL | 5 >> val;
113+
| ^^^^^^^^
114+
115+
warning: unused unary operation which must be used
116+
--> $DIR/must-use-ops.rs:49:5
117+
|
118+
LL | !val;
119+
| ^^^^
120+
121+
warning: unused unary operation which must be used
122+
--> $DIR/must-use-ops.rs:50:5
123+
|
124+
LL | -val;
125+
| ^^^^
126+
127+
warning: unused unary operation which must be used
128+
--> $DIR/must-use-ops.rs:51:5
129+
|
130+
LL | *val_pointer;
131+
| ^^^^^^^^^^^^
132+

0 commit comments

Comments
 (0)