diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 82b90e1660a95..551930975b402 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -197,6 +197,7 @@ lint_drop_trait_constraints = lint_dropping_copy_types = calls to `std::mem::drop` with a value that implements `Copy` does nothing .label = argument has type `{$arg_ty}` .note = use `let _ = ...` to ignore the expression or result + .suggestion = ignore the value lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 78ac7f9b2354d..90063a3e66f9e 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -1,4 +1,4 @@ -use rustc_hir::{Arm, Expr, ExprKind, Node}; +use rustc_hir::{Arm, Expr, ExprKind, Node, StmtKind}; use rustc_middle::ty; use rustc_span::sym; @@ -163,10 +163,22 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { ); } sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { + let (sugg, replace) = if let Some((_, node)) = + cx.tcx.hir().parent_iter(expr.hir_id).nth(0) + && let Node::Stmt(stmt) = node + && let StmtKind::Semi(e) = stmt.kind + && e.hir_id == expr.hir_id + && let Ok(value) = cx.sess().source_map().span_to_snippet(arg.span) + { + (Some(expr.span), format!("let _ = {}", value)) + } else { + (None, "".to_string()) + }; + cx.emit_span_lint( DROPPING_COPY_TYPES, expr.span, - DropCopyDiag { arg_ty, label: arg.span }, + DropCopyDiag { arg_ty, label: arg.span, sugg, replace }, ); } sym::mem_forget if is_copy => { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index a034bebc85ec0..bdefbfd9b1a0f 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -674,6 +674,9 @@ pub struct DropCopyDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, + #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")] + pub sugg: Option, + pub replace: String, } #[derive(LintDiagnostic)] diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr index 834ae00a8d85b..f110e22de955c 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr @@ -8,6 +8,10 @@ LL | drop(origin); | = note: use `let _ = ...` to ignore the expression or result = note: `#[warn(dropping_copy_types)]` on by default +help: ignore the value + | +LL | let _ = origin; + | ~~~~~~~~~~~~~~ warning: 1 warning emitted diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr index 0f944a18ed58b..e54119e1e13c4 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr @@ -8,6 +8,10 @@ LL | drop(origin); | = note: use `let _ = ...` to ignore the expression or result = note: `#[warn(dropping_copy_types)]` on by default +help: ignore the value + | +LL | let _ = origin; + | ~~~~~~~~~~~~~~ warning: 1 warning emitted diff --git a/tests/ui/lint/dropping_copy_types-issue-125189.rs b/tests/ui/lint/dropping_copy_types-issue-125189.rs new file mode 100644 index 0000000000000..60d2051c89948 --- /dev/null +++ b/tests/ui/lint/dropping_copy_types-issue-125189.rs @@ -0,0 +1,17 @@ +//@ check-fail + +#![deny(dropping_copy_types)] + +fn main() { + let y = 1; + let z = 2; + match y { + 1 => drop(3), //~ ERROR calls to `std::mem::drop` + 2 => drop(y), //~ ERROR calls to `std::mem::drop` + 3 => if drop(z) == () {}, //~ ERROR calls to `std::mem::drop` + _ => (), + } + + drop(3.2); //~ ERROR calls to `std::mem::drop` + drop(y); //~ ERROR calls to `std::mem::drop` +} diff --git a/tests/ui/lint/dropping_copy_types-issue-125189.stderr b/tests/ui/lint/dropping_copy_types-issue-125189.stderr new file mode 100644 index 0000000000000..2a00892986353 --- /dev/null +++ b/tests/ui/lint/dropping_copy_types-issue-125189.stderr @@ -0,0 +1,65 @@ +error: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types-issue-125189.rs:9:14 + | +LL | 1 => drop(3), + | ^^^^^-^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result +note: the lint level is defined here + --> $DIR/dropping_copy_types-issue-125189.rs:3:9 + | +LL | #![deny(dropping_copy_types)] + | ^^^^^^^^^^^^^^^^^^^ + +error: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types-issue-125189.rs:10:14 + | +LL | 2 => drop(y), + | ^^^^^-^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + +error: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types-issue-125189.rs:11:17 + | +LL | 3 => if drop(z) == () {}, + | ^^^^^-^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + +error: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types-issue-125189.rs:15:5 + | +LL | drop(3.2); + | ^^^^^---^ + | | + | argument has type `f64` + | + = note: use `let _ = ...` to ignore the expression or result +help: ignore the value + | +LL | let _ = 3.2; + | ~~~~~~~~~~~ + +error: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types-issue-125189.rs:16:5 + | +LL | drop(y); + | ^^^^^-^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result +help: ignore the value + | +LL | let _ = y; + | ~~~~~~~~~ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/lint/dropping_copy_types.stderr b/tests/ui/lint/dropping_copy_types.stderr index b6291aa5ed634..c7f6c00be6b38 100644 --- a/tests/ui/lint/dropping_copy_types.stderr +++ b/tests/ui/lint/dropping_copy_types.stderr @@ -12,6 +12,10 @@ note: the lint level is defined here | LL | #![warn(dropping_copy_types)] | ^^^^^^^^^^^^^^^^^^^ +help: ignore the value + | +LL | let _ = s1; + | ~~~~~~~~~~ warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/dropping_copy_types.rs:35:5 @@ -22,6 +26,10 @@ LL | drop(s2); | argument has type `SomeStruct` | = note: use `let _ = ...` to ignore the expression or result +help: ignore the value + | +LL | let _ = s2; + | ~~~~~~~~~~ warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_copy_types.rs:36:5 @@ -43,6 +51,10 @@ LL | drop(s4); | argument has type `SomeStruct` | = note: use `let _ = ...` to ignore the expression or result +help: ignore the value + | +LL | let _ = s4; + | ~~~~~~~~~~ warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_copy_types.rs:38:5 @@ -83,6 +95,10 @@ LL | drop(println_and(13)); | argument has type `i32` | = note: use `let _ = ...` to ignore the expression or result +help: ignore the value + | +LL | let _ = println_and(13); + | ~~~~~~~~~~~~~~~~~~~~~~~ warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/dropping_copy_types.rs:74:14