From cb55d10eb2b11ea6aee96c111b0996519af1fdf5 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 29 Oct 2022 21:14:02 +0800 Subject: [PATCH] Fix #103320, add explanatory message for [#must_use] --- .../locales/en-US/borrowck.ftl | 2 +- .../locales/en-US/lint.ftl | 1 + compiler/rustc_lint/src/lints.rs | 18 +++++ compiler/rustc_lint/src/unused.rs | 18 ++++- library/core/src/ops/arith.rs | 18 +++-- .../lint/unused/issue-103320-must-use-ops.rs | 27 ++++++++ .../unused/issue-103320-must-use-ops.stderr | 67 +++++++++++++++++++ 7 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 tests/ui/lint/unused/issue-103320-must-use-ops.rs create mode 100644 tests/ui/lint/unused/issue-103320-must-use-ops.stderr diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index 0021638c10268..fe77cf23e8f94 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -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 diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index dca678dff7a79..b1e7cc69a809b 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -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 diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 0c1019545f382..2e447b900e117 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1402,6 +1402,21 @@ pub struct UnusedDef<'a, 'b> { pub cx: &'a LateContext<'b>, pub def_id: DefId, pub note: Option, + pub suggestion: Option, +} + +#[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 @@ impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> { if let Some(note) = self.note { diag.note(note.as_str()); } + if let Some(sugg) = self.suggestion { + diag.subdiagnostic(sugg); + } diag } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 4c9b3df2dbd33..622601224ff92 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -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 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { ); } 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 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { cx, def_id: *def_id, note: *reason, + suggestion, }, ); } diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index cc13db5c9565b..0c7ee9630c6ee 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -86,7 +86,8 @@ pub trait Add { /// ``` /// 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 { /// ``` /// 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 { /// ``` /// 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 { /// ``` /// 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 { /// ``` /// 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; } diff --git a/tests/ui/lint/unused/issue-103320-must-use-ops.rs b/tests/ui/lint/unused/issue-103320-must-use-ops.rs new file mode 100644 index 0000000000000..597d312fa5ecb --- /dev/null +++ b/tests/ui/lint/unused/issue-103320-must-use-ops.rs @@ -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); +} diff --git a/tests/ui/lint/unused/issue-103320-must-use-ops.stderr b/tests/ui/lint/unused/issue-103320-must-use-ops.stderr new file mode 100644 index 0000000000000..57439ec6a8fdb --- /dev/null +++ b/tests/ui/lint/unused/issue-103320-must-use-ops.stderr @@ -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 +