Skip to content

Commit 771d8d4

Browse files
committed
Let lint_dropping_references give the suggestion if possible.
1 parent 9f432d7 commit 771d8d4

7 files changed

+263
-15
lines changed

compiler/rustc_lint/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ lint_dropping_copy_types = calls to `std::mem::drop` with a value that implement
201201
lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
202202
.label = argument has type `{$arg_ty}`
203203
.note = use `let _ = ...` to ignore the expression or result
204+
.suggestion = use `let _ = ...` to ignore the expression or result
204205
205206
lint_enum_intrinsics_mem_discriminant =
206207
the return value of `mem::discriminant` is unspecified when called with a non-enum type

compiler/rustc_lint/src/drop_forget_useless.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use rustc_hir::{Arm, Expr, ExprKind, Node};
1+
use rustc_hir::{Arm, Expr, ExprKind, Node, StmtKind};
22
use rustc_middle::ty;
33
use rustc_span::sym;
44

55
use crate::{
66
lints::{
7-
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag,
8-
UndroppedManuallyDropsSuggestion,
7+
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, IgnoreDropSuggestion,
8+
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion,
99
},
1010
LateContext, LateLintPass, LintContext,
1111
};
@@ -147,12 +147,24 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
147147
let arg_ty = cx.typeck_results().expr_ty(arg);
148148
let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
149149
let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
150+
let sugg = if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)
151+
&& let Node::Stmt(stmt) = node
152+
&& let StmtKind::Semi(e) = stmt.kind
153+
&& e.hir_id == expr.hir_id
154+
{
155+
IgnoreDropSuggestion::Suggestion {
156+
start_span: expr.span.shrink_to_lo().until(arg.span),
157+
end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
158+
}
159+
} else {
160+
IgnoreDropSuggestion::Note
161+
};
150162
match fn_name {
151163
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
152164
cx.emit_span_lint(
153165
DROPPING_REFERENCES,
154166
expr.span,
155-
DropRefDiag { arg_ty, label: arg.span },
167+
DropRefDiag { arg_ty, label: arg.span, sugg },
156168
);
157169
}
158170
sym::mem_forget if arg_ty.is_ref() => {

compiler/rustc_lint/src/lints.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -657,14 +657,28 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
657657
pub end_span: Span,
658658
}
659659

660+
#[derive(Subdiagnostic)]
661+
pub enum IgnoreDropSuggestion {
662+
#[note(lint_note)]
663+
Note,
664+
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
665+
Suggestion {
666+
#[suggestion_part(code = "let _ = ")]
667+
start_span: Span,
668+
#[suggestion_part(code = "")]
669+
end_span: Span,
670+
},
671+
}
672+
660673
// drop_forget_useless.rs
661674
#[derive(LintDiagnostic)]
662675
#[diag(lint_dropping_references)]
663-
#[note]
664676
pub struct DropRefDiag<'a> {
665677
pub arg_ty: Ty<'a>,
666678
#[label]
667679
pub label: Span,
680+
#[subdiagnostic]
681+
pub sugg: IgnoreDropSuggestion,
668682
}
669683

670684
#[derive(LintDiagnostic)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//@ check-fail
2+
//@ run-rustfix
3+
4+
#![deny(dropping_references)]
5+
6+
struct SomeStruct;
7+
8+
fn main() {
9+
let _ = &SomeStruct; //~ ERROR calls to `std::mem::drop`
10+
11+
let mut owned1 = SomeStruct;
12+
let _ = &owned1; //~ ERROR calls to `std::mem::drop`
13+
let _ = &&owned1; //~ ERROR calls to `std::mem::drop`
14+
let _ = &mut owned1; //~ ERROR calls to `std::mem::drop`
15+
drop(owned1);
16+
17+
let reference1 = &SomeStruct;
18+
let _ = reference1; //~ ERROR calls to `std::mem::drop`
19+
20+
let reference2 = &mut SomeStruct;
21+
let _ = reference2; //~ ERROR calls to `std::mem::drop`
22+
23+
let ref reference3 = SomeStruct;
24+
let _ = reference3; //~ ERROR calls to `std::mem::drop`
25+
}
26+
27+
#[allow(dead_code)]
28+
fn test_generic_fn_drop<T>(val: T) {
29+
let _ = &val; //~ ERROR calls to `std::mem::drop`
30+
drop(val);
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//@ check-fail
2+
//@ run-rustfix
3+
4+
#![deny(dropping_references)]
5+
6+
struct SomeStruct;
7+
8+
fn main() {
9+
drop(&SomeStruct); //~ ERROR calls to `std::mem::drop`
10+
11+
let mut owned1 = SomeStruct;
12+
drop(&owned1); //~ ERROR calls to `std::mem::drop`
13+
drop(&&owned1); //~ ERROR calls to `std::mem::drop`
14+
drop(&mut owned1); //~ ERROR calls to `std::mem::drop`
15+
drop(owned1);
16+
17+
let reference1 = &SomeStruct;
18+
drop(reference1); //~ ERROR calls to `std::mem::drop`
19+
20+
let reference2 = &mut SomeStruct;
21+
drop(reference2); //~ ERROR calls to `std::mem::drop`
22+
23+
let ref reference3 = SomeStruct;
24+
drop(reference3); //~ ERROR calls to `std::mem::drop`
25+
}
26+
27+
#[allow(dead_code)]
28+
fn test_generic_fn_drop<T>(val: T) {
29+
drop(&val); //~ ERROR calls to `std::mem::drop`
30+
drop(val);
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
2+
--> $DIR/dropping_references-can-fixed.rs:9:5
3+
|
4+
LL | drop(&SomeStruct);
5+
| ^^^^^-----------^
6+
| |
7+
| argument has type `&SomeStruct`
8+
|
9+
note: the lint level is defined here
10+
--> $DIR/dropping_references-can-fixed.rs:4:9
11+
|
12+
LL | #![deny(dropping_references)]
13+
| ^^^^^^^^^^^^^^^^^^^
14+
help: use `let _ = ...` to ignore the expression or result
15+
|
16+
LL - drop(&SomeStruct);
17+
LL + let _ = &SomeStruct;
18+
|
19+
20+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
21+
--> $DIR/dropping_references-can-fixed.rs:12:5
22+
|
23+
LL | drop(&owned1);
24+
| ^^^^^-------^
25+
| |
26+
| argument has type `&SomeStruct`
27+
|
28+
help: use `let _ = ...` to ignore the expression or result
29+
|
30+
LL - drop(&owned1);
31+
LL + let _ = &owned1;
32+
|
33+
34+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
35+
--> $DIR/dropping_references-can-fixed.rs:13:5
36+
|
37+
LL | drop(&&owned1);
38+
| ^^^^^--------^
39+
| |
40+
| argument has type `&&SomeStruct`
41+
|
42+
help: use `let _ = ...` to ignore the expression or result
43+
|
44+
LL - drop(&&owned1);
45+
LL + let _ = &&owned1;
46+
|
47+
48+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
49+
--> $DIR/dropping_references-can-fixed.rs:14:5
50+
|
51+
LL | drop(&mut owned1);
52+
| ^^^^^-----------^
53+
| |
54+
| argument has type `&mut SomeStruct`
55+
|
56+
help: use `let _ = ...` to ignore the expression or result
57+
|
58+
LL - drop(&mut owned1);
59+
LL + let _ = &mut owned1;
60+
|
61+
62+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
63+
--> $DIR/dropping_references-can-fixed.rs:18:5
64+
|
65+
LL | drop(reference1);
66+
| ^^^^^----------^
67+
| |
68+
| argument has type `&SomeStruct`
69+
|
70+
help: use `let _ = ...` to ignore the expression or result
71+
|
72+
LL - drop(reference1);
73+
LL + let _ = reference1;
74+
|
75+
76+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
77+
--> $DIR/dropping_references-can-fixed.rs:21:5
78+
|
79+
LL | drop(reference2);
80+
| ^^^^^----------^
81+
| |
82+
| argument has type `&mut SomeStruct`
83+
|
84+
help: use `let _ = ...` to ignore the expression or result
85+
|
86+
LL - drop(reference2);
87+
LL + let _ = reference2;
88+
|
89+
90+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
91+
--> $DIR/dropping_references-can-fixed.rs:24:5
92+
|
93+
LL | drop(reference3);
94+
| ^^^^^----------^
95+
| |
96+
| argument has type `&SomeStruct`
97+
|
98+
help: use `let _ = ...` to ignore the expression or result
99+
|
100+
LL - drop(reference3);
101+
LL + let _ = reference3;
102+
|
103+
104+
error: calls to `std::mem::drop` with a reference instead of an owned value does nothing
105+
--> $DIR/dropping_references-can-fixed.rs:29:5
106+
|
107+
LL | drop(&val);
108+
| ^^^^^----^
109+
| |
110+
| argument has type `&T`
111+
|
112+
help: use `let _ = ...` to ignore the expression or result
113+
|
114+
LL - drop(&val);
115+
LL + let _ = &val;
116+
|
117+
118+
error: aborting due to 8 previous errors
119+

tests/ui/lint/dropping_references.stderr

+50-10
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ LL | drop(&SomeStruct);
66
| |
77
| argument has type `&SomeStruct`
88
|
9-
= note: use `let _ = ...` to ignore the expression or result
109
note: the lint level is defined here
1110
--> $DIR/dropping_references.rs:3:9
1211
|
1312
LL | #![warn(dropping_references)]
1413
| ^^^^^^^^^^^^^^^^^^^
14+
help: use `let _ = ...` to ignore the expression or result
15+
|
16+
LL - drop(&SomeStruct);
17+
LL + let _ = &SomeStruct;
18+
|
1519

1620
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
1721
--> $DIR/dropping_references.rs:11:5
@@ -21,7 +25,11 @@ LL | drop(&owned1);
2125
| |
2226
| argument has type `&SomeStruct`
2327
|
24-
= note: use `let _ = ...` to ignore the expression or result
28+
help: use `let _ = ...` to ignore the expression or result
29+
|
30+
LL - drop(&owned1);
31+
LL + let _ = &owned1;
32+
|
2533

2634
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
2735
--> $DIR/dropping_references.rs:12:5
@@ -31,7 +39,11 @@ LL | drop(&&owned1);
3139
| |
3240
| argument has type `&&SomeStruct`
3341
|
34-
= note: use `let _ = ...` to ignore the expression or result
42+
help: use `let _ = ...` to ignore the expression or result
43+
|
44+
LL - drop(&&owned1);
45+
LL + let _ = &&owned1;
46+
|
3547

3648
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
3749
--> $DIR/dropping_references.rs:13:5
@@ -41,7 +53,11 @@ LL | drop(&mut owned1);
4153
| |
4254
| argument has type `&mut SomeStruct`
4355
|
44-
= note: use `let _ = ...` to ignore the expression or result
56+
help: use `let _ = ...` to ignore the expression or result
57+
|
58+
LL - drop(&mut owned1);
59+
LL + let _ = &mut owned1;
60+
|
4561

4662
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
4763
--> $DIR/dropping_references.rs:17:5
@@ -51,7 +67,11 @@ LL | drop(reference1);
5167
| |
5268
| argument has type `&SomeStruct`
5369
|
54-
= note: use `let _ = ...` to ignore the expression or result
70+
help: use `let _ = ...` to ignore the expression or result
71+
|
72+
LL - drop(reference1);
73+
LL + let _ = reference1;
74+
|
5575

5676
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
5777
--> $DIR/dropping_references.rs:20:5
@@ -61,7 +81,11 @@ LL | drop(reference2);
6181
| |
6282
| argument has type `&mut SomeStruct`
6383
|
64-
= note: use `let _ = ...` to ignore the expression or result
84+
help: use `let _ = ...` to ignore the expression or result
85+
|
86+
LL - drop(reference2);
87+
LL + let _ = reference2;
88+
|
6589

6690
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
6791
--> $DIR/dropping_references.rs:23:5
@@ -71,7 +95,11 @@ LL | drop(reference3);
7195
| |
7296
| argument has type `&SomeStruct`
7397
|
74-
= note: use `let _ = ...` to ignore the expression or result
98+
help: use `let _ = ...` to ignore the expression or result
99+
|
100+
LL - drop(reference3);
101+
LL + let _ = reference3;
102+
|
75103

76104
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
77105
--> $DIR/dropping_references.rs:28:5
@@ -81,7 +109,11 @@ LL | drop(&val);
81109
| |
82110
| argument has type `&T`
83111
|
84-
= note: use `let _ = ...` to ignore the expression or result
112+
help: use `let _ = ...` to ignore the expression or result
113+
|
114+
LL - drop(&val);
115+
LL + let _ = &val;
116+
|
85117

86118
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
87119
--> $DIR/dropping_references.rs:36:5
@@ -91,7 +123,11 @@ LL | std::mem::drop(&SomeStruct);
91123
| |
92124
| argument has type `&SomeStruct`
93125
|
94-
= note: use `let _ = ...` to ignore the expression or result
126+
help: use `let _ = ...` to ignore the expression or result
127+
|
128+
LL - std::mem::drop(&SomeStruct);
129+
LL + let _ = &SomeStruct;
130+
|
95131

96132
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
97133
--> $DIR/dropping_references.rs:91:13
@@ -101,7 +137,11 @@ LL | drop(println_and(&13));
101137
| |
102138
| argument has type `&i32`
103139
|
104-
= note: use `let _ = ...` to ignore the expression or result
140+
help: use `let _ = ...` to ignore the expression or result
141+
|
142+
LL - drop(println_and(&13));
143+
LL + let _ = println_and(&13);
144+
|
105145

106146
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
107147
--> $DIR/dropping_references.rs:94:14

0 commit comments

Comments
 (0)