Skip to content

Commit 044a28a

Browse files
committed
Auto merge of rust-lang#103761 - chenyukang:yukang/fix-103320-must-use, r=compiler-errors
Add explanatory message for [#must_use] in ops Fixes rust-lang#103320
2 parents e7813fe + cb55d10 commit 044a28a

File tree

7 files changed

+142
-9
lines changed

7 files changed

+142
-9
lines changed

compiler/rustc_error_messages/locales/en-US/borrowck.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ borrowck_var_here_defined = variable defined here
3333
3434
borrowck_var_here_captured = variable captured here
3535
36-
borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
36+
borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
3737
3838
borrowck_returned_closure_escaped =
3939
returns a closure that contains a reference to a captured variable, which then escapes the closure body

compiler/rustc_error_messages/locales/en-US/lint.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ lint_unused_generator =
309309
.note = generators are lazy and do nothing unless resumed
310310
311311
lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
312+
.suggestion = use `let _ = ...` to ignore the resulting value
312313
313314
lint_path_statement_drop = path statement drops value
314315
.suggestion = use `drop` to clarify the intent

compiler/rustc_lint/src/lints.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,21 @@ pub struct UnusedDef<'a, 'b> {
14021402
pub cx: &'a LateContext<'b>,
14031403
pub def_id: DefId,
14041404
pub note: Option<Symbol>,
1405+
pub suggestion: Option<UnusedDefSuggestion>,
1406+
}
1407+
1408+
#[derive(Subdiagnostic)]
1409+
pub enum UnusedDefSuggestion {
1410+
#[suggestion(
1411+
suggestion,
1412+
style = "verbose",
1413+
code = "let _ = ",
1414+
applicability = "machine-applicable"
1415+
)]
1416+
Default {
1417+
#[primary_span]
1418+
span: Span,
1419+
},
14051420
}
14061421

14071422
// Needed because of def_path_str
@@ -1417,6 +1432,9 @@ impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
14171432
if let Some(note) = self.note {
14181433
diag.note(note.as_str());
14191434
}
1435+
if let Some(sugg) = self.suggestion {
1436+
diag.subdiagnostic(sugg);
1437+
}
14201438
diag
14211439
}
14221440

compiler/rustc_lint/src/unused.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::lints::{
22
PathStatementDrop, PathStatementDropSub, PathStatementNoEffect, UnusedAllocationDiag,
3-
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDelim, UnusedDelimSuggestion,
4-
UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
3+
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDefSuggestion, UnusedDelim,
4+
UnusedDelimSuggestion, UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
55
};
66
use crate::Lint;
77
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
@@ -418,6 +418,19 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
418418
);
419419
}
420420
MustUsePath::Def(span, def_id, reason) => {
421+
let suggestion = if matches!(
422+
cx.tcx.get_diagnostic_name(*def_id),
423+
Some(sym::add)
424+
| Some(sym::sub)
425+
| Some(sym::mul)
426+
| Some(sym::div)
427+
| Some(sym::rem)
428+
| Some(sym::neg),
429+
) {
430+
Some(UnusedDefSuggestion::Default { span: span.shrink_to_lo() })
431+
} else {
432+
None
433+
};
421434
cx.emit_spanned_lint(
422435
UNUSED_MUST_USE,
423436
*span,
@@ -427,6 +440,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
427440
cx,
428441
def_id: *def_id,
429442
note: *reason,
443+
suggestion,
430444
},
431445
);
432446
}

library/core/src/ops/arith.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ pub trait Add<Rhs = Self> {
8686
/// ```
8787
/// assert_eq!(12 + 1, 13);
8888
/// ```
89-
#[must_use]
89+
#[must_use = "this returns the result of the operation, without modifying the original"]
90+
#[rustc_diagnostic_item = "add"]
9091
#[stable(feature = "rust1", since = "1.0.0")]
9192
fn add(self, rhs: Rhs) -> Self::Output;
9293
}
@@ -195,7 +196,8 @@ pub trait Sub<Rhs = Self> {
195196
/// ```
196197
/// assert_eq!(12 - 1, 11);
197198
/// ```
198-
#[must_use]
199+
#[must_use = "this returns the result of the operation, without modifying the original"]
200+
#[rustc_diagnostic_item = "sub"]
199201
#[stable(feature = "rust1", since = "1.0.0")]
200202
fn sub(self, rhs: Rhs) -> Self::Output;
201203
}
@@ -325,7 +327,8 @@ pub trait Mul<Rhs = Self> {
325327
/// ```
326328
/// assert_eq!(12 * 2, 24);
327329
/// ```
328-
#[must_use]
330+
#[must_use = "this returns the result of the operation, without modifying the original"]
331+
#[rustc_diagnostic_item = "mul"]
329332
#[stable(feature = "rust1", since = "1.0.0")]
330333
fn mul(self, rhs: Rhs) -> Self::Output;
331334
}
@@ -459,7 +462,8 @@ pub trait Div<Rhs = Self> {
459462
/// ```
460463
/// assert_eq!(12 / 2, 6);
461464
/// ```
462-
#[must_use]
465+
#[must_use = "this returns the result of the operation, without modifying the original"]
466+
#[rustc_diagnostic_item = "div"]
463467
#[stable(feature = "rust1", since = "1.0.0")]
464468
fn div(self, rhs: Rhs) -> Self::Output;
465469
}
@@ -562,7 +566,8 @@ pub trait Rem<Rhs = Self> {
562566
/// ```
563567
/// assert_eq!(12 % 10, 2);
564568
/// ```
565-
#[must_use]
569+
#[must_use = "this returns the result of the operation, without modifying the original"]
570+
#[rustc_diagnostic_item = "rem"]
566571
#[stable(feature = "rust1", since = "1.0.0")]
567572
fn rem(self, rhs: Rhs) -> Self::Output;
568573
}
@@ -678,7 +683,8 @@ pub trait Neg {
678683
/// let x: i32 = 12;
679684
/// assert_eq!(-x, -12);
680685
/// ```
681-
#[must_use]
686+
#[must_use = "this returns the result of the operation, without modifying the original"]
687+
#[rustc_diagnostic_item = "neg"]
682688
#[stable(feature = "rust1", since = "1.0.0")]
683689
fn neg(self) -> Self::Output;
684690
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// check-pass
2+
3+
#![warn(unused_must_use)]
4+
#![feature(never_type)]
5+
6+
use std::ops::Add;
7+
use std::ops::Sub;
8+
use std::ops::Mul;
9+
use std::ops::Div;
10+
use std::ops::Rem;
11+
12+
fn main() {
13+
let x = 2_u32;
14+
(x.add(4), x.sub(4), x.mul(4), x.div(4), x.rem(4));
15+
16+
x.add(4); //~ WARN unused return value of `add` that must be used
17+
18+
x.sub(4); //~ WARN unused return value of `sub` that must be used
19+
20+
x.mul(4); //~ WARN unused return value of `mul` that must be used
21+
22+
x.div(4); //~ WARN unused return value of `div` that must be used
23+
24+
x.rem(4); //~ WARN unused return value of `rem` that must be used
25+
26+
println!("{}", x);
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
warning: unused return value of `add` that must be used
2+
--> $DIR/issue-103320-must-use-ops.rs:16:5
3+
|
4+
LL | x.add(4);
5+
| ^^^^^^^^
6+
|
7+
= note: this returns the result of the operation, without modifying the original
8+
note: the lint level is defined here
9+
--> $DIR/issue-103320-must-use-ops.rs:3:9
10+
|
11+
LL | #![warn(unused_must_use)]
12+
| ^^^^^^^^^^^^^^^
13+
help: use `let _ = ...` to ignore the resulting value
14+
|
15+
LL | let _ = x.add(4);
16+
| +++++++
17+
18+
warning: unused return value of `sub` that must be used
19+
--> $DIR/issue-103320-must-use-ops.rs:18:5
20+
|
21+
LL | x.sub(4);
22+
| ^^^^^^^^
23+
|
24+
= note: this returns the result of the operation, without modifying the original
25+
help: use `let _ = ...` to ignore the resulting value
26+
|
27+
LL | let _ = x.sub(4);
28+
| +++++++
29+
30+
warning: unused return value of `mul` that must be used
31+
--> $DIR/issue-103320-must-use-ops.rs:20:5
32+
|
33+
LL | x.mul(4);
34+
| ^^^^^^^^
35+
|
36+
= note: this returns the result of the operation, without modifying the original
37+
help: use `let _ = ...` to ignore the resulting value
38+
|
39+
LL | let _ = x.mul(4);
40+
| +++++++
41+
42+
warning: unused return value of `div` that must be used
43+
--> $DIR/issue-103320-must-use-ops.rs:22:5
44+
|
45+
LL | x.div(4);
46+
| ^^^^^^^^
47+
|
48+
= note: this returns the result of the operation, without modifying the original
49+
help: use `let _ = ...` to ignore the resulting value
50+
|
51+
LL | let _ = x.div(4);
52+
| +++++++
53+
54+
warning: unused return value of `rem` that must be used
55+
--> $DIR/issue-103320-must-use-ops.rs:24:5
56+
|
57+
LL | x.rem(4);
58+
| ^^^^^^^^
59+
|
60+
= note: this returns the result of the operation, without modifying the original
61+
help: use `let _ = ...` to ignore the resulting value
62+
|
63+
LL | let _ = x.rem(4);
64+
| +++++++
65+
66+
warning: 5 warnings emitted
67+

0 commit comments

Comments
 (0)