Let lint_dropping_references give the suggestion if possible.
This commit is contained in:
parent
5870f1ccbb
commit
ca68c93135
@ -238,6 +238,7 @@ lint_dropping_copy_types = calls to `std::mem::drop` with a value that implement
|
|||||||
lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
.label = argument has type `{$arg_ty}`
|
.label = argument has type `{$arg_ty}`
|
||||||
.note = use `let _ = ...` to ignore the expression or result
|
.note = use `let _ = ...` to ignore the expression or result
|
||||||
|
.suggestion = use `let _ = ...` to ignore the expression or result
|
||||||
|
|
||||||
lint_duplicate_macro_attribute =
|
lint_duplicate_macro_attribute =
|
||||||
duplicated attribute
|
duplicated attribute
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lints::{
|
lints::{
|
||||||
DropCopyDiag, DropCopySuggestion, DropRefDiag, ForgetCopyDiag, ForgetRefDiag,
|
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, IgnoreDropSuggestion,
|
||||||
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion,
|
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion,
|
||||||
},
|
},
|
||||||
LateContext, LateLintPass, LintContext,
|
LateContext, LateLintPass, LintContext,
|
||||||
@ -148,12 +148,24 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
|||||||
let arg_ty = cx.typeck_results().expr_ty(arg);
|
let arg_ty = cx.typeck_results().expr_ty(arg);
|
||||||
let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
|
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 drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
|
||||||
|
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
|
||||||
|
{
|
||||||
|
IgnoreDropSuggestion::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 {
|
||||||
|
IgnoreDropSuggestion::Note
|
||||||
|
};
|
||||||
match fn_name {
|
match fn_name {
|
||||||
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
|
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
|
||||||
cx.emit_span_lint(
|
cx.emit_span_lint(
|
||||||
DROPPING_REFERENCES,
|
DROPPING_REFERENCES,
|
||||||
expr.span,
|
expr.span,
|
||||||
DropRefDiag { arg_ty, label: arg.span },
|
DropRefDiag { arg_ty, label: arg.span, sugg },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
sym::mem_forget if arg_ty.is_ref() => {
|
sym::mem_forget if arg_ty.is_ref() => {
|
||||||
|
@ -656,14 +656,28 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
|
|||||||
pub end_span: Span,
|
pub end_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
pub enum IgnoreDropSuggestion {
|
||||||
|
#[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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// drop_forget_useless.rs
|
// drop_forget_useless.rs
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(lint_dropping_references)]
|
#[diag(lint_dropping_references)]
|
||||||
#[note]
|
|
||||||
pub struct DropRefDiag<'a> {
|
pub struct DropRefDiag<'a> {
|
||||||
pub arg_ty: Ty<'a>,
|
pub arg_ty: Ty<'a>,
|
||||||
#[label]
|
#[label]
|
||||||
pub label: Span,
|
pub label: Span,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub sugg: IgnoreDropSuggestion,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
|
31
tests/ui/lint/dropping_references-can-fixed.fixed
Normal file
31
tests/ui/lint/dropping_references-can-fixed.fixed
Normal file
@ -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<T>(val: T) {
|
||||||
|
let _ = &val; //~ ERROR calls to `std::mem::drop`
|
||||||
|
drop(val);
|
||||||
|
}
|
31
tests/ui/lint/dropping_references-can-fixed.rs
Normal file
31
tests/ui/lint/dropping_references-can-fixed.rs
Normal file
@ -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<T>(val: T) {
|
||||||
|
drop(&val); //~ ERROR calls to `std::mem::drop`
|
||||||
|
drop(val);
|
||||||
|
}
|
119
tests/ui/lint/dropping_references-can-fixed.stderr
Normal file
119
tests/ui/lint/dropping_references-can-fixed.stderr
Normal file
@ -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
|
||||||
|
|
@ -6,12 +6,16 @@ LL | drop(&SomeStruct);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&SomeStruct`
|
| argument has type `&SomeStruct`
|
||||||
|
|
|
|
||||||
= note: use `let _ = ...` to ignore the expression or result
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/dropping_references.rs:3:9
|
--> $DIR/dropping_references.rs:3:9
|
||||||
|
|
|
|
||||||
LL | #![warn(dropping_references)]
|
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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:11:5
|
--> $DIR/dropping_references.rs:11:5
|
||||||
@ -21,7 +25,11 @@ LL | drop(&owned1);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&SomeStruct`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:12:5
|
--> $DIR/dropping_references.rs:12:5
|
||||||
@ -31,7 +39,11 @@ LL | drop(&&owned1);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&&SomeStruct`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:13:5
|
--> $DIR/dropping_references.rs:13:5
|
||||||
@ -41,7 +53,11 @@ LL | drop(&mut owned1);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&mut SomeStruct`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:17:5
|
--> $DIR/dropping_references.rs:17:5
|
||||||
@ -51,7 +67,11 @@ LL | drop(reference1);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&SomeStruct`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:20:5
|
--> $DIR/dropping_references.rs:20:5
|
||||||
@ -61,7 +81,11 @@ LL | drop(reference2);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&mut SomeStruct`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:23:5
|
--> $DIR/dropping_references.rs:23:5
|
||||||
@ -71,7 +95,11 @@ LL | drop(reference3);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&SomeStruct`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:28:5
|
--> $DIR/dropping_references.rs:28:5
|
||||||
@ -81,7 +109,11 @@ LL | drop(&val);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&T`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:36:5
|
--> $DIR/dropping_references.rs:36:5
|
||||||
@ -91,7 +123,11 @@ LL | std::mem::drop(&SomeStruct);
|
|||||||
| |
|
| |
|
||||||
| argument has type `&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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:91:13
|
--> $DIR/dropping_references.rs:91:13
|
||||||
@ -101,7 +137,11 @@ LL | drop(println_and(&13));
|
|||||||
| |
|
| |
|
||||||
| argument has type `&i32`
|
| 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
|
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
|
||||||
--> $DIR/dropping_references.rs:94:14
|
--> $DIR/dropping_references.rs:94:14
|
||||||
|
Loading…
Reference in New Issue
Block a user