Skip to content

Commit ca68c93

Browse files
committed
Let lint_dropping_references give the suggestion if possible.
1 parent 5870f1c commit ca68c93

7 files changed

+261
-13
lines changed

compiler/rustc_lint/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ lint_dropping_copy_types = calls to `std::mem::drop` with a value that implement
238238
lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
239239
.label = argument has type `{$arg_ty}`
240240
.note = use `let _ = ...` to ignore the expression or result
241+
.suggestion = use `let _ = ...` to ignore the expression or result
241242
242243
lint_duplicate_macro_attribute =
243244
duplicated attribute

compiler/rustc_lint/src/drop_forget_useless.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_span::sym;
55

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

compiler/rustc_lint/src/lints.rs

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

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

669683
#[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)