Fix #103320, add explanatory message for [#must_use]

This commit is contained in:
yukang 2022-10-29 21:14:02 +08:00
parent a94b9fd0ac
commit cb55d10eb2
7 changed files with 142 additions and 9 deletions

View File

@ -33,7 +33,7 @@ borrowck_var_here_defined = variable defined here
borrowck_var_here_captured = variable captured here
borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
borrowck_returned_closure_escaped =
returns a closure that contains a reference to a captured variable, which then escapes the closure body

View File

@ -309,6 +309,7 @@ lint_unused_generator =
.note = generators are lazy and do nothing unless resumed
lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
.suggestion = use `let _ = ...` to ignore the resulting value
lint_path_statement_drop = path statement drops value
.suggestion = use `drop` to clarify the intent

View File

@ -1402,6 +1402,21 @@ pub struct UnusedDef<'a, 'b> {
pub cx: &'a LateContext<'b>,
pub def_id: DefId,
pub note: Option<Symbol>,
pub suggestion: Option<UnusedDefSuggestion>,
}
#[derive(Subdiagnostic)]
pub enum UnusedDefSuggestion {
#[suggestion(
suggestion,
style = "verbose",
code = "let _ = ",
applicability = "machine-applicable"
)]
Default {
#[primary_span]
span: Span,
},
}
// Needed because of def_path_str
@ -1417,6 +1432,9 @@ fn decorate_lint<'b>(
if let Some(note) = self.note {
diag.note(note.as_str());
}
if let Some(sugg) = self.suggestion {
diag.subdiagnostic(sugg);
}
diag
}

View File

@ -1,7 +1,7 @@
use crate::lints::{
PathStatementDrop, PathStatementDropSub, PathStatementNoEffect, UnusedAllocationDiag,
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDelim, UnusedDelimSuggestion,
UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDefSuggestion, UnusedDelim,
UnusedDelimSuggestion, UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
};
use crate::Lint;
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
@ -418,6 +418,19 @@ fn emit_must_use_untranslated(
);
}
MustUsePath::Def(span, def_id, reason) => {
let suggestion = if matches!(
cx.tcx.get_diagnostic_name(*def_id),
Some(sym::add)
| Some(sym::sub)
| Some(sym::mul)
| Some(sym::div)
| Some(sym::rem)
| Some(sym::neg),
) {
Some(UnusedDefSuggestion::Default { span: span.shrink_to_lo() })
} else {
None
};
cx.emit_spanned_lint(
UNUSED_MUST_USE,
*span,
@ -427,6 +440,7 @@ fn emit_must_use_untranslated(
cx,
def_id: *def_id,
note: *reason,
suggestion,
},
);
}

View File

@ -86,7 +86,8 @@ pub trait Add<Rhs = Self> {
/// ```
/// assert_eq!(12 + 1, 13);
/// ```
#[must_use]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[rustc_diagnostic_item = "add"]
#[stable(feature = "rust1", since = "1.0.0")]
fn add(self, rhs: Rhs) -> Self::Output;
}
@ -195,7 +196,8 @@ pub trait Sub<Rhs = Self> {
/// ```
/// assert_eq!(12 - 1, 11);
/// ```
#[must_use]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[rustc_diagnostic_item = "sub"]
#[stable(feature = "rust1", since = "1.0.0")]
fn sub(self, rhs: Rhs) -> Self::Output;
}
@ -325,7 +327,8 @@ pub trait Mul<Rhs = Self> {
/// ```
/// assert_eq!(12 * 2, 24);
/// ```
#[must_use]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[rustc_diagnostic_item = "mul"]
#[stable(feature = "rust1", since = "1.0.0")]
fn mul(self, rhs: Rhs) -> Self::Output;
}
@ -459,7 +462,8 @@ pub trait Div<Rhs = Self> {
/// ```
/// assert_eq!(12 / 2, 6);
/// ```
#[must_use]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[rustc_diagnostic_item = "div"]
#[stable(feature = "rust1", since = "1.0.0")]
fn div(self, rhs: Rhs) -> Self::Output;
}
@ -562,7 +566,8 @@ pub trait Rem<Rhs = Self> {
/// ```
/// assert_eq!(12 % 10, 2);
/// ```
#[must_use]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[rustc_diagnostic_item = "rem"]
#[stable(feature = "rust1", since = "1.0.0")]
fn rem(self, rhs: Rhs) -> Self::Output;
}
@ -678,7 +683,8 @@ pub trait Neg {
/// let x: i32 = 12;
/// assert_eq!(-x, -12);
/// ```
#[must_use]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[rustc_diagnostic_item = "neg"]
#[stable(feature = "rust1", since = "1.0.0")]
fn neg(self) -> Self::Output;
}

View File

@ -0,0 +1,27 @@
// check-pass
#![warn(unused_must_use)]
#![feature(never_type)]
use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use std::ops::Rem;
fn main() {
let x = 2_u32;
(x.add(4), x.sub(4), x.mul(4), x.div(4), x.rem(4));
x.add(4); //~ WARN unused return value of `add` that must be used
x.sub(4); //~ WARN unused return value of `sub` that must be used
x.mul(4); //~ WARN unused return value of `mul` that must be used
x.div(4); //~ WARN unused return value of `div` that must be used
x.rem(4); //~ WARN unused return value of `rem` that must be used
println!("{}", x);
}

View File

@ -0,0 +1,67 @@
warning: unused return value of `add` that must be used
--> $DIR/issue-103320-must-use-ops.rs:16:5
|
LL | x.add(4);
| ^^^^^^^^
|
= note: this returns the result of the operation, without modifying the original
note: the lint level is defined here
--> $DIR/issue-103320-must-use-ops.rs:3:9
|
LL | #![warn(unused_must_use)]
| ^^^^^^^^^^^^^^^
help: use `let _ = ...` to ignore the resulting value
|
LL | let _ = x.add(4);
| +++++++
warning: unused return value of `sub` that must be used
--> $DIR/issue-103320-must-use-ops.rs:18:5
|
LL | x.sub(4);
| ^^^^^^^^
|
= note: this returns the result of the operation, without modifying the original
help: use `let _ = ...` to ignore the resulting value
|
LL | let _ = x.sub(4);
| +++++++
warning: unused return value of `mul` that must be used
--> $DIR/issue-103320-must-use-ops.rs:20:5
|
LL | x.mul(4);
| ^^^^^^^^
|
= note: this returns the result of the operation, without modifying the original
help: use `let _ = ...` to ignore the resulting value
|
LL | let _ = x.mul(4);
| +++++++
warning: unused return value of `div` that must be used
--> $DIR/issue-103320-must-use-ops.rs:22:5
|
LL | x.div(4);
| ^^^^^^^^
|
= note: this returns the result of the operation, without modifying the original
help: use `let _ = ...` to ignore the resulting value
|
LL | let _ = x.div(4);
| +++++++
warning: unused return value of `rem` that must be used
--> $DIR/issue-103320-must-use-ops.rs:24:5
|
LL | x.rem(4);
| ^^^^^^^^
|
= note: this returns the result of the operation, without modifying the original
help: use `let _ = ...` to ignore the resulting value
|
LL | let _ = x.rem(4);
| +++++++
warning: 5 warnings emitted