Skip to content

Commit 8a25ec0

Browse files
Rollup merge of #44103 - zackmdavis:cmp_op_must_use, r=arielb1
add comparison operators to must-use lint (under `fn_must_use` feature) Although RFC 1940 is about annotating functions with `#[must_use]`, a key part of the motivation was linting unused equality operators. (See https://github.com/rust-lang/rfcs/pull/1812#issuecomment-265695898—it seems to have not been clear to discussants at the time that marking the comparison methods as `must_use` would not give us the lints on comparison operators, at least in (what the present author understood as) the most straightforward implementation, as landed in #43728 (3645b06).) To rectify the situation, we here lint unused comparison operators as part of the unused-must-use lint (feature gated by the `fn_must_use` feature flag, which now arguably becomes a slight (tolerable in the opinion of the present author) misnomer). This is in the matter of #43302. cc @crumblingstatue
2 parents 6f90787 + 6734d39 commit 8a25ec0

File tree

4 files changed

+52
-12
lines changed

4 files changed

+52
-12
lines changed

src/librustc_lint/unused.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
153153
};
154154

155155
let mut fn_warned = false;
156+
let mut op_warned = false;
156157
if cx.tcx.sess.features.borrow().fn_must_use {
157158
let maybe_def = match expr.node {
158159
hir::ExprCall(ref callee, _) => {
@@ -172,9 +173,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
172173
let def_id = def.def_id();
173174
fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
174175
}
176+
177+
if let hir::ExprBinary(bin_op, ..) = expr.node {
178+
match bin_op.node {
179+
// Hardcoding the comparison operators here seemed more
180+
// expedient than the refactoring that would be needed to
181+
// look up the `#[must_use]` attribute which does exist on
182+
// the comparison trait methods
183+
hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => {
184+
let msg = "unused comparison which must be used";
185+
cx.span_lint(UNUSED_MUST_USE, expr.span, msg);
186+
op_warned = true;
187+
},
188+
_ => {},
189+
}
190+
}
175191
}
176192

177-
if !(ty_warned || fn_warned) {
193+
if !(ty_warned || fn_warned || op_warned) {
178194
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
179195
}
180196

src/libsyntax/feature_gate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ declare_features! (
380380
// #[doc(masked)]
381381
(active, doc_masked, "1.21.0", None),
382382

383-
// allow `#[must_use]` on functions (RFC 1940)
383+
// allow `#[must_use]` on functions and comparison operators (RFC 1940)
384384
(active, fn_must_use, "1.21.0", Some(43302)),
385385

386386
// allow '|' at beginning of match arms (RFC 1925)

src/test/ui/rfc_1940-must_use_on_functions/fn_must_use.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![feature(fn_must_use)]
1212
#![warn(unused_must_use)]
1313

14+
#[derive(PartialEq, Eq)]
1415
struct MyStruct {
1516
n: usize,
1617
}
@@ -58,13 +59,18 @@ fn main() {
5859
need_to_use_this_value();
5960

6061
let mut m = MyStruct { n: 2 };
62+
let n = MyStruct { n: 3 };
63+
6164
m.need_to_use_this_method_value();
6265
m.is_even(); // trait method!
6366

64-
m.replace(3);
67+
m.replace(3); // won't warn (annotation needs to be in trait definition)
6568

69+
// comparison methods are `must_use`
6670
2.eq(&3);
71+
m.eq(&n);
6772

68-
// FIXME: operators should probably be `must_use` if underlying method is
73+
// lint includes comparison operators
6974
2 == 3;
75+
m == n;
7076
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
warning: unused return value of `need_to_use_this_value` which must be used: it's important
2-
--> $DIR/fn_must_use.rs:58:5
2+
--> $DIR/fn_must_use.rs:59:5
33
|
4-
58 | need_to_use_this_value();
4+
59 | need_to_use_this_value();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: lint level defined here
@@ -11,20 +11,38 @@ note: lint level defined here
1111
| ^^^^^^^^^^^^^^^
1212

1313
warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
14-
--> $DIR/fn_must_use.rs:61:5
14+
--> $DIR/fn_must_use.rs:64:5
1515
|
16-
61 | m.need_to_use_this_method_value();
16+
64 | m.need_to_use_this_method_value();
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
warning: unused return value of `EvenNature::is_even` which must be used: no side effects
20-
--> $DIR/fn_must_use.rs:62:5
20+
--> $DIR/fn_must_use.rs:65:5
2121
|
22-
62 | m.is_even(); // trait method!
22+
65 | m.is_even(); // trait method!
2323
| ^^^^^^^^^^^^
2424

2525
warning: unused return value of `std::cmp::PartialEq::eq` which must be used
26-
--> $DIR/fn_must_use.rs:66:5
26+
--> $DIR/fn_must_use.rs:70:5
2727
|
28-
66 | 2.eq(&3);
28+
70 | 2.eq(&3);
2929
| ^^^^^^^^^
3030

31+
warning: unused return value of `std::cmp::PartialEq::eq` which must be used
32+
--> $DIR/fn_must_use.rs:71:5
33+
|
34+
71 | m.eq(&n);
35+
| ^^^^^^^^^
36+
37+
warning: unused comparison which must be used
38+
--> $DIR/fn_must_use.rs:74:5
39+
|
40+
74 | 2 == 3;
41+
| ^^^^^^
42+
43+
warning: unused comparison which must be used
44+
--> $DIR/fn_must_use.rs:75:5
45+
|
46+
75 | m == n;
47+
| ^^^^^^
48+

0 commit comments

Comments
 (0)