diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d2b1f50d79cbc..fb71cb6014026 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -232,12 +232,9 @@ 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 = use `let _ = ...` to ignore the expression or result lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` - .note = use `let _ = ...` to ignore the expression or result lint_duplicate_macro_attribute = duplicated attribute @@ -272,10 +269,9 @@ lint_for_loops_over_fallibles = lint_forgetting_copy_types = calls to `std::mem::forget` with a value that implements `Copy` does nothing .label = argument has type `{$arg_ty}` - .note = use `let _ = ...` to ignore the expression or result + lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` - .note = use `let _ = ...` to ignore the expression or result lint_hidden_glob_reexport = private item shadows public glob re-export .note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here @@ -894,6 +890,8 @@ lint_unused_op = unused {$op} that must be used lint_unused_result = unused result of type `{$ty}` +lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result + lint_variant_size_differences = enum variant is more than three times larger ({$largest} bytes) than the next largest diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 02d324520b859..eea0898d83fa6 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -5,8 +5,8 @@ use rustc_span::sym; use crate::{ lints::{ - DropCopyDiag, DropCopySuggestion, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, - UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion, + DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag, + UndroppedManuallyDropsSuggestion, UseLetUnderscoreIgnoreSuggestion, }, LateContext, LateLintPass, LintContext, }; @@ -148,46 +148,59 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { let arg_ty = cx.typeck_results().expr_ty(arg); let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); + let let_underscore_ignore_sugg = || { + 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 + { + UseLetUnderscoreIgnoreSuggestion::Suggestion { + start_span: expr.span.shrink_to_lo().until(arg.span), + end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()), + } + } else { + UseLetUnderscoreIgnoreSuggestion::Note + } + }; match fn_name { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { cx.emit_span_lint( DROPPING_REFERENCES, expr.span, - DropRefDiag { arg_ty, label: arg.span }, + DropRefDiag { arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg() }, ); } sym::mem_forget if arg_ty.is_ref() => { cx.emit_span_lint( FORGETTING_REFERENCES, expr.span, - ForgetRefDiag { arg_ty, label: arg.span }, + ForgetRefDiag { + arg_ty, + label: arg.span, + sugg: let_underscore_ignore_sugg(), + }, ); } sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { - let sugg = 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 - { - DropCopySuggestion::Suggestion { - start_span: expr.span.shrink_to_lo().until(arg.span), - end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()), - } - } else { - DropCopySuggestion::Note - }; - cx.emit_span_lint( DROPPING_COPY_TYPES, expr.span, - DropCopyDiag { arg_ty, label: arg.span, sugg }, + DropCopyDiag { + arg_ty, + label: arg.span, + sugg: let_underscore_ignore_sugg(), + }, ); } sym::mem_forget if is_copy => { cx.emit_span_lint( FORGETTING_COPY_TYPES, expr.span, - ForgetCopyDiag { arg_ty, label: arg.span }, + ForgetCopyDiag { + arg_ty, + label: arg.span, + sugg: let_underscore_ignore_sugg(), + }, ); } sym::mem_drop diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index c365e68ba44dc..84d46ef3b65d5 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -656,14 +656,32 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> { pub end_span: Span, } +#[derive(Subdiagnostic)] +pub enum UseLetUnderscoreIgnoreSuggestion { + #[note(lint_use_let_underscore_ignore_suggestion)] + Note, + #[multipart_suggestion( + lint_use_let_underscore_ignore_suggestion, + style = "verbose", + applicability = "maybe-incorrect" + )] + Suggestion { + #[suggestion_part(code = "let _ = ")] + start_span: Span, + #[suggestion_part(code = "")] + end_span: Span, + }, +} + // drop_forget_useless.rs #[derive(LintDiagnostic)] #[diag(lint_dropping_references)] -#[note] pub struct DropRefDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, + #[subdiagnostic] + pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] @@ -673,38 +691,27 @@ pub struct DropCopyDiag<'a> { #[label] pub label: Span, #[subdiagnostic] - pub sugg: DropCopySuggestion, -} - -#[derive(Subdiagnostic)] -pub enum DropCopySuggestion { - #[note(lint_note)] - Note, - #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")] - Suggestion { - #[suggestion_part(code = "let _ = ")] - start_span: Span, - #[suggestion_part(code = "")] - end_span: Span, - }, + pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] #[diag(lint_forgetting_references)] -#[note] pub struct ForgetRefDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, + #[subdiagnostic] + pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] #[diag(lint_forgetting_copy_types)] -#[note] pub struct ForgetCopyDiag<'a> { pub arg_ty: Ty<'a>, #[label] pub label: Span, + #[subdiagnostic] + pub sugg: UseLetUnderscoreIgnoreSuggestion, } #[derive(LintDiagnostic)] diff --git a/tests/ui/lint/dropping_copy_types.stderr b/tests/ui/lint/dropping_copy_types.stderr index bdeb0c290fe93..41aa66a4efc68 100644 --- a/tests/ui/lint/dropping_copy_types.stderr +++ b/tests/ui/lint/dropping_copy_types.stderr @@ -39,8 +39,12 @@ LL | drop(s3); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result = note: `#[warn(dropping_references)]` on by default +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(s3); +LL + let _ = s3; + | warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/dropping_copy_types.rs:37:5 @@ -64,7 +68,11 @@ LL | drop(s5); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(s5); +LL + let _ = s5; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_copy_types.rs:50:5 @@ -74,7 +82,11 @@ LL | drop(a2); | | | argument has type `&AnotherStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(a2); +LL + let _ = a2; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_copy_types.rs:52:5 @@ -84,7 +96,11 @@ LL | drop(a4); | | | argument has type `&AnotherStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(a4); +LL + let _ = a4; + | warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/dropping_copy_types.rs:71:13 diff --git a/tests/ui/lint/dropping_references-can-fixed.fixed b/tests/ui/lint/dropping_references-can-fixed.fixed new file mode 100644 index 0000000000000..f704d3c72df7d --- /dev/null +++ b/tests/ui/lint/dropping_references-can-fixed.fixed @@ -0,0 +1,31 @@ +//@ check-fail +//@ run-rustfix + +#![deny(dropping_references)] + +struct SomeStruct; + +fn main() { + let _ = &SomeStruct; //~ ERROR calls to `std::mem::drop` + + let mut owned1 = SomeStruct; + let _ = &owned1; //~ ERROR calls to `std::mem::drop` + let _ = &&owned1; //~ ERROR calls to `std::mem::drop` + let _ = &mut owned1; //~ ERROR calls to `std::mem::drop` + drop(owned1); + + let reference1 = &SomeStruct; + let _ = reference1; //~ ERROR calls to `std::mem::drop` + + let reference2 = &mut SomeStruct; + let _ = reference2; //~ ERROR calls to `std::mem::drop` + + let ref reference3 = SomeStruct; + let _ = reference3; //~ ERROR calls to `std::mem::drop` +} + +#[allow(dead_code)] +fn test_generic_fn_drop(val: T) { + let _ = &val; //~ ERROR calls to `std::mem::drop` + drop(val); +} diff --git a/tests/ui/lint/dropping_references-can-fixed.rs b/tests/ui/lint/dropping_references-can-fixed.rs new file mode 100644 index 0000000000000..70d1c16d66b4f --- /dev/null +++ b/tests/ui/lint/dropping_references-can-fixed.rs @@ -0,0 +1,31 @@ +//@ check-fail +//@ run-rustfix + +#![deny(dropping_references)] + +struct SomeStruct; + +fn main() { + drop(&SomeStruct); //~ ERROR calls to `std::mem::drop` + + let mut owned1 = SomeStruct; + drop(&owned1); //~ ERROR calls to `std::mem::drop` + drop(&&owned1); //~ ERROR calls to `std::mem::drop` + drop(&mut owned1); //~ ERROR calls to `std::mem::drop` + drop(owned1); + + let reference1 = &SomeStruct; + drop(reference1); //~ ERROR calls to `std::mem::drop` + + let reference2 = &mut SomeStruct; + drop(reference2); //~ ERROR calls to `std::mem::drop` + + let ref reference3 = SomeStruct; + drop(reference3); //~ ERROR calls to `std::mem::drop` +} + +#[allow(dead_code)] +fn test_generic_fn_drop(val: T) { + drop(&val); //~ ERROR calls to `std::mem::drop` + drop(val); +} diff --git a/tests/ui/lint/dropping_references-can-fixed.stderr b/tests/ui/lint/dropping_references-can-fixed.stderr new file mode 100644 index 0000000000000..42cdb81b524a1 --- /dev/null +++ b/tests/ui/lint/dropping_references-can-fixed.stderr @@ -0,0 +1,119 @@ +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:9:5 + | +LL | drop(&SomeStruct); + | ^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | +note: the lint level is defined here + --> $DIR/dropping_references-can-fixed.rs:4:9 + | +LL | #![deny(dropping_references)] + | ^^^^^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&SomeStruct); +LL + let _ = &SomeStruct; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:12:5 + | +LL | drop(&owned1); + | ^^^^^-------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&owned1); +LL + let _ = &owned1; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:13:5 + | +LL | drop(&&owned1); + | ^^^^^--------^ + | | + | argument has type `&&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&&owned1); +LL + let _ = &&owned1; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:14:5 + | +LL | drop(&mut owned1); + | ^^^^^-----------^ + | | + | argument has type `&mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&mut owned1); +LL + let _ = &mut owned1; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:18:5 + | +LL | drop(reference1); + | ^^^^^----------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(reference1); +LL + let _ = reference1; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:21:5 + | +LL | drop(reference2); + | ^^^^^----------^ + | | + | argument has type `&mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(reference2); +LL + let _ = reference2; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:24:5 + | +LL | drop(reference3); + | ^^^^^----------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(reference3); +LL + let _ = reference3; + | + +error: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/dropping_references-can-fixed.rs:29:5 + | +LL | drop(&val); + | ^^^^^----^ + | | + | argument has type `&T` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&val); +LL + let _ = &val; + | + +error: aborting due to 8 previous errors + diff --git a/tests/ui/lint/dropping_references.stderr b/tests/ui/lint/dropping_references.stderr index 7e25a46216ecf..312334b82ad4b 100644 --- a/tests/ui/lint/dropping_references.stderr +++ b/tests/ui/lint/dropping_references.stderr @@ -6,12 +6,16 @@ LL | drop(&SomeStruct); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/dropping_references.rs:3:9 | LL | #![warn(dropping_references)] | ^^^^^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&SomeStruct); +LL + let _ = &SomeStruct; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:11:5 @@ -21,7 +25,11 @@ LL | drop(&owned1); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&owned1); +LL + let _ = &owned1; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:12:5 @@ -31,7 +39,11 @@ LL | drop(&&owned1); | | | argument has type `&&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&&owned1); +LL + let _ = &&owned1; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:13:5 @@ -41,7 +53,11 @@ LL | drop(&mut owned1); | | | argument has type `&mut SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&mut owned1); +LL + let _ = &mut owned1; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:17:5 @@ -51,7 +67,11 @@ LL | drop(reference1); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(reference1); +LL + let _ = reference1; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:20:5 @@ -61,7 +81,11 @@ LL | drop(reference2); | | | argument has type `&mut SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(reference2); +LL + let _ = reference2; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:23:5 @@ -71,7 +95,11 @@ LL | drop(reference3); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(reference3); +LL + let _ = reference3; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:28:5 @@ -81,7 +109,11 @@ LL | drop(&val); | | | argument has type `&T` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(&val); +LL + let _ = &val; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:36:5 @@ -91,7 +123,11 @@ LL | std::mem::drop(&SomeStruct); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - std::mem::drop(&SomeStruct); +LL + let _ = &SomeStruct; + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:91:13 @@ -101,7 +137,11 @@ LL | drop(println_and(&13)); | | | argument has type `&i32` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - drop(println_and(&13)); +LL + let _ = println_and(&13); + | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/dropping_references.rs:94:14 diff --git a/tests/ui/lint/forgetting_copy_types-can-fixed.fixed b/tests/ui/lint/forgetting_copy_types-can-fixed.fixed new file mode 100644 index 0000000000000..c5d65ecc1d42b --- /dev/null +++ b/tests/ui/lint/forgetting_copy_types-can-fixed.fixed @@ -0,0 +1,22 @@ +//@ check-fail +//@ run-rustfix + +#![deny(forgetting_copy_types)] +#![allow(unused_mut)] +#![allow(unused_imports)] + +use std::vec::Vec; +use std::mem::forget; + +#[derive(Copy, Clone)] +struct SomeStruct; + +fn main() { + let s1 = SomeStruct {}; + let s2 = s1; + let mut s3 = s1; + + let _ = s1; //~ ERROR calls to `std::mem::forget` + let _ = s2; //~ ERROR calls to `std::mem::forget` + let _ = s3; //~ ERROR calls to `std::mem::forget` +} diff --git a/tests/ui/lint/forgetting_copy_types-can-fixed.rs b/tests/ui/lint/forgetting_copy_types-can-fixed.rs new file mode 100644 index 0000000000000..c557229428007 --- /dev/null +++ b/tests/ui/lint/forgetting_copy_types-can-fixed.rs @@ -0,0 +1,22 @@ +//@ check-fail +//@ run-rustfix + +#![deny(forgetting_copy_types)] +#![allow(unused_mut)] +#![allow(unused_imports)] + +use std::vec::Vec; +use std::mem::forget; + +#[derive(Copy, Clone)] +struct SomeStruct; + +fn main() { + let s1 = SomeStruct {}; + let s2 = s1; + let mut s3 = s1; + + forget(s1); //~ ERROR calls to `std::mem::forget` + forget(s2); //~ ERROR calls to `std::mem::forget` + forget(s3); //~ ERROR calls to `std::mem::forget` +} diff --git a/tests/ui/lint/forgetting_copy_types-can-fixed.stderr b/tests/ui/lint/forgetting_copy_types-can-fixed.stderr new file mode 100644 index 0000000000000..cb7bbf02222e7 --- /dev/null +++ b/tests/ui/lint/forgetting_copy_types-can-fixed.stderr @@ -0,0 +1,49 @@ +error: calls to `std::mem::forget` with a value that implements `Copy` does nothing + --> $DIR/forgetting_copy_types-can-fixed.rs:19:5 + | +LL | forget(s1); + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` + | +note: the lint level is defined here + --> $DIR/forgetting_copy_types-can-fixed.rs:4:9 + | +LL | #![deny(forgetting_copy_types)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s1); +LL + let _ = s1; + | + +error: calls to `std::mem::forget` with a value that implements `Copy` does nothing + --> $DIR/forgetting_copy_types-can-fixed.rs:20:5 + | +LL | forget(s2); + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s2); +LL + let _ = s2; + | + +error: calls to `std::mem::forget` with a value that implements `Copy` does nothing + --> $DIR/forgetting_copy_types-can-fixed.rs:21:5 + | +LL | forget(s3); + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s3); +LL + let _ = s3; + | + +error: aborting due to 3 previous errors + diff --git a/tests/ui/lint/forgetting_copy_types.stderr b/tests/ui/lint/forgetting_copy_types.stderr index 36d1ef5c53e93..980ee6caba254 100644 --- a/tests/ui/lint/forgetting_copy_types.stderr +++ b/tests/ui/lint/forgetting_copy_types.stderr @@ -6,12 +6,16 @@ LL | forget(s1); | | | argument has type `SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/forgetting_copy_types.rs:3:9 | LL | #![warn(forgetting_copy_types)] | ^^^^^^^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s1); +LL + let _ = s1; + | warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing --> $DIR/forgetting_copy_types.rs:35:5 @@ -21,7 +25,11 @@ LL | forget(s2); | | | argument has type `SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s2); +LL + let _ = s2; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_copy_types.rs:36:5 @@ -31,8 +39,12 @@ LL | forget(s3); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result = note: `#[warn(forgetting_references)]` on by default +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s3); +LL + let _ = s3; + | warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing --> $DIR/forgetting_copy_types.rs:37:5 @@ -42,7 +54,11 @@ LL | forget(s4); | | | argument has type `SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s4); +LL + let _ = s4; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_copy_types.rs:38:5 @@ -52,7 +68,11 @@ LL | forget(s5); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(s5); +LL + let _ = s5; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_copy_types.rs:50:5 @@ -62,7 +82,11 @@ LL | forget(a2); | | | argument has type `&AnotherStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(a2); +LL + let _ = a2; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_copy_types.rs:52:5 @@ -72,7 +96,11 @@ LL | forget(a3); | | | argument has type `&AnotherStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(a3); +LL + let _ = a3; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_copy_types.rs:53:5 @@ -82,7 +110,11 @@ LL | forget(a4); | | | argument has type `&AnotherStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(a4); +LL + let _ = a4; + | warning: 8 warnings emitted diff --git a/tests/ui/lint/forgetting_references-can-fixed.fixed b/tests/ui/lint/forgetting_references-can-fixed.fixed new file mode 100644 index 0000000000000..64475f042840a --- /dev/null +++ b/tests/ui/lint/forgetting_references-can-fixed.fixed @@ -0,0 +1,40 @@ +//@ check-fail +//@ run-rustfix + +#![deny(forgetting_references)] + +use std::mem::forget; + +struct SomeStruct; + +fn main() { + let _ = &SomeStruct; //~ ERROR calls to `std::mem::forget` + + let mut owned = SomeStruct; + let _ = &owned; //~ ERROR calls to `std::mem::forget` + let _ = &&owned; //~ ERROR calls to `std::mem::forget` + let _ = &mut owned; //~ ERROR calls to `std::mem::forget` + forget(owned); + + let reference1 = &SomeStruct; + let _ = &*reference1; //~ ERROR calls to `std::mem::forget` + + let reference2 = &mut SomeStruct; + let _ = reference2; //~ ERROR calls to `std::mem::forget` + + let ref reference3 = SomeStruct; + let _ = reference3; //~ ERROR calls to `std::mem::forget` +} + +#[allow(dead_code)] +fn test_generic_fn_forget(val: T) { + let _ = &val; //~ ERROR calls to `std::mem::forget` + forget(val); +} + +#[allow(dead_code)] +fn test_similarly_named_function() { + fn forget(_val: T) {} + forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name + let _ = &SomeStruct; //~ ERROR calls to `std::mem::forget` +} diff --git a/tests/ui/lint/forgetting_references-can-fixed.rs b/tests/ui/lint/forgetting_references-can-fixed.rs new file mode 100644 index 0000000000000..4c9ef541d3418 --- /dev/null +++ b/tests/ui/lint/forgetting_references-can-fixed.rs @@ -0,0 +1,40 @@ +//@ check-fail +//@ run-rustfix + +#![deny(forgetting_references)] + +use std::mem::forget; + +struct SomeStruct; + +fn main() { + forget(&SomeStruct); //~ ERROR calls to `std::mem::forget` + + let mut owned = SomeStruct; + forget(&owned); //~ ERROR calls to `std::mem::forget` + forget(&&owned); //~ ERROR calls to `std::mem::forget` + forget(&mut owned); //~ ERROR calls to `std::mem::forget` + forget(owned); + + let reference1 = &SomeStruct; + forget(&*reference1); //~ ERROR calls to `std::mem::forget` + + let reference2 = &mut SomeStruct; + forget(reference2); //~ ERROR calls to `std::mem::forget` + + let ref reference3 = SomeStruct; + forget(reference3); //~ ERROR calls to `std::mem::forget` +} + +#[allow(dead_code)] +fn test_generic_fn_forget(val: T) { + forget(&val); //~ ERROR calls to `std::mem::forget` + forget(val); +} + +#[allow(dead_code)] +fn test_similarly_named_function() { + fn forget(_val: T) {} + forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name + std::mem::forget(&SomeStruct); //~ ERROR calls to `std::mem::forget` +} diff --git a/tests/ui/lint/forgetting_references-can-fixed.stderr b/tests/ui/lint/forgetting_references-can-fixed.stderr new file mode 100644 index 0000000000000..05eb636ab4595 --- /dev/null +++ b/tests/ui/lint/forgetting_references-can-fixed.stderr @@ -0,0 +1,133 @@ +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:11:5 + | +LL | forget(&SomeStruct); + | ^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | +note: the lint level is defined here + --> $DIR/forgetting_references-can-fixed.rs:4:9 + | +LL | #![deny(forgetting_references)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&SomeStruct); +LL + let _ = &SomeStruct; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:14:5 + | +LL | forget(&owned); + | ^^^^^^^------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&owned); +LL + let _ = &owned; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:15:5 + | +LL | forget(&&owned); + | ^^^^^^^-------^ + | | + | argument has type `&&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&&owned); +LL + let _ = &&owned; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:16:5 + | +LL | forget(&mut owned); + | ^^^^^^^----------^ + | | + | argument has type `&mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&mut owned); +LL + let _ = &mut owned; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:20:5 + | +LL | forget(&*reference1); + | ^^^^^^^------------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&*reference1); +LL + let _ = &*reference1; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:23:5 + | +LL | forget(reference2); + | ^^^^^^^----------^ + | | + | argument has type `&mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(reference2); +LL + let _ = reference2; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:26:5 + | +LL | forget(reference3); + | ^^^^^^^----------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(reference3); +LL + let _ = reference3; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:31:5 + | +LL | forget(&val); + | ^^^^^^^----^ + | | + | argument has type `&T` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&val); +LL + let _ = &val; + | + +error: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references-can-fixed.rs:39:5 + | +LL | std::mem::forget(&SomeStruct); + | ^^^^^^^^^^^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::mem::forget(&SomeStruct); +LL + let _ = &SomeStruct; + | + +error: aborting due to 9 previous errors + diff --git a/tests/ui/lint/forgetting_references.rs b/tests/ui/lint/forgetting_references.rs index ecfa23ee49705..d0ec2a77ab1ca 100644 --- a/tests/ui/lint/forgetting_references.rs +++ b/tests/ui/lint/forgetting_references.rs @@ -23,6 +23,16 @@ fn main() { let ref reference3 = SomeStruct; forget(reference3); //~ WARN calls to `std::mem::forget` + + let ref reference4 = SomeStruct; + + let a = 1; + match a { + 1 => forget(&*reference1), //~ WARN calls to `std::mem::forget` + 2 => forget(reference3), //~ WARN calls to `std::mem::forget` + 3 => forget(reference4), //~ WARN calls to `std::mem::forget` + _ => {} + } } #[allow(dead_code)] diff --git a/tests/ui/lint/forgetting_references.stderr b/tests/ui/lint/forgetting_references.stderr index 5624b690789f8..afd5030a6805b 100644 --- a/tests/ui/lint/forgetting_references.stderr +++ b/tests/ui/lint/forgetting_references.stderr @@ -6,12 +6,16 @@ LL | forget(&SomeStruct); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/forgetting_references.rs:3:9 | LL | #![warn(forgetting_references)] | ^^^^^^^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&SomeStruct); +LL + let _ = &SomeStruct; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_references.rs:13:5 @@ -21,7 +25,11 @@ LL | forget(&owned); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&owned); +LL + let _ = &owned; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_references.rs:14:5 @@ -31,7 +39,11 @@ LL | forget(&&owned); | | | argument has type `&&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&&owned); +LL + let _ = &&owned; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_references.rs:15:5 @@ -41,7 +53,11 @@ LL | forget(&mut owned); | | | argument has type `&mut SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&mut owned); +LL + let _ = &mut owned; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_references.rs:19:5 @@ -51,7 +67,11 @@ LL | forget(&*reference1); | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&*reference1); +LL + let _ = &*reference1; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_references.rs:22:5 @@ -61,7 +81,11 @@ LL | forget(reference2); | | | argument has type `&mut SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(reference2); +LL + let _ = reference2; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forgetting_references.rs:25:5 @@ -71,27 +95,69 @@ LL | forget(reference3); | | | argument has type `&SomeStruct` | +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(reference3); +LL + let _ = reference3; + | + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references.rs:31:14 + | +LL | 1 => forget(&*reference1), + | ^^^^^^^------------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references.rs:32:14 + | +LL | 2 => forget(reference3), + | ^^^^^^^----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forgetting_references.rs:33:14 + | +LL | 3 => forget(reference4), + | ^^^^^^^----------^ + | | + | argument has type `&SomeStruct` + | = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing - --> $DIR/forgetting_references.rs:30:5 + --> $DIR/forgetting_references.rs:40:5 | LL | forget(&val); | ^^^^^^^----^ | | | argument has type `&T` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - forget(&val); +LL + let _ = &val; + | warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing - --> $DIR/forgetting_references.rs:38:5 + --> $DIR/forgetting_references.rs:48:5 | LL | std::mem::forget(&SomeStruct); | ^^^^^^^^^^^^^^^^^-----------^ | | | argument has type `&SomeStruct` | - = note: use `let _ = ...` to ignore the expression or result +help: use `let _ = ...` to ignore the expression or result + | +LL - std::mem::forget(&SomeStruct); +LL + let _ = &SomeStruct; + | -warning: 9 warnings emitted +warning: 12 warnings emitted