Skip to content

Commit 078441c

Browse files
committed
Let lint_forgetting_references give the suggestion if possible
1 parent d0d0a45 commit 078441c

9 files changed

+336
-25
lines changed

compiler/rustc_lint/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ lint_forgetting_copy_types = calls to `std::mem::forget` with a value that imple
230230
lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing
231231
.label = argument has type `{$arg_ty}`
232232
.note = use `let _ = ...` to ignore the expression or result
233+
.suggestion = use `let _ = ...` to ignore the expression or result
233234
234235
lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label}
235236
.label = this {$label} contains {$count ->

compiler/rustc_lint/src/drop_forget_useless.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use rustc_span::sym;
44

55
use crate::{
66
lints::{
7-
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, IgnoreDropSuggestion,
8-
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion,
7+
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag,
8+
UndroppedManuallyDropsSuggestion, UseLetUnderscoreIgnoreSuggestion,
99
},
1010
LateContext, LateLintPass, LintContext,
1111
};
@@ -152,12 +152,12 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
152152
&& let StmtKind::Semi(e) = stmt.kind
153153
&& e.hir_id == expr.hir_id
154154
{
155-
IgnoreDropSuggestion::Suggestion {
155+
UseLetUnderscoreIgnoreSuggestion::Suggestion {
156156
start_span: expr.span.shrink_to_lo().until(arg.span),
157157
end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
158158
}
159159
} else {
160-
IgnoreDropSuggestion::Note
160+
UseLetUnderscoreIgnoreSuggestion::Note
161161
};
162162
match fn_name {
163163
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
@@ -171,7 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
171171
cx.emit_span_lint(
172172
FORGETTING_REFERENCES,
173173
expr.span,
174-
ForgetRefDiag { arg_ty, label: arg.span },
174+
ForgetRefDiag { arg_ty, label: arg.span, sugg },
175175
);
176176
}
177177
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {

compiler/rustc_lint/src/lints.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
658658
}
659659

660660
#[derive(Subdiagnostic)]
661-
pub enum IgnoreDropSuggestion {
661+
pub enum UseLetUnderscoreIgnoreSuggestion {
662662
#[note(lint_note)]
663663
Note,
664664
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
@@ -678,7 +678,7 @@ pub struct DropRefDiag<'a> {
678678
#[label]
679679
pub label: Span,
680680
#[subdiagnostic]
681-
pub sugg: IgnoreDropSuggestion,
681+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
682682
}
683683

684684
#[derive(LintDiagnostic)]
@@ -692,11 +692,12 @@ pub struct DropCopyDiag<'a> {
692692

693693
#[derive(LintDiagnostic)]
694694
#[diag(lint_forgetting_references)]
695-
#[note]
696695
pub struct ForgetRefDiag<'a> {
697696
pub arg_ty: Ty<'a>,
698697
#[label]
699698
pub label: Span,
699+
#[subdiagnostic]
700+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
700701
}
701702

702703
#[derive(LintDiagnostic)]
@@ -706,7 +707,7 @@ pub struct ForgetCopyDiag<'a> {
706707
#[label]
707708
pub label: Span,
708709
#[subdiagnostic]
709-
pub sugg: IgnoreDropSuggestion,
710+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
710711
}
711712

712713
#[derive(LintDiagnostic)]

tests/ui/lint/forgetting_copy_types.stderr

+25-5
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ LL | forget(s3);
3939
| |
4040
| argument has type `&SomeStruct`
4141
|
42-
= note: use `let _ = ...` to ignore the expression or result
4342
= note: `#[warn(forgetting_references)]` on by default
43+
help: use `let _ = ...` to ignore the expression or result
44+
|
45+
LL - forget(s3);
46+
LL + let _ = s3;
47+
|
4448

4549
warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
4650
--> $DIR/forgetting_copy_types.rs:37:5
@@ -64,7 +68,11 @@ LL | forget(s5);
6468
| |
6569
| argument has type `&SomeStruct`
6670
|
67-
= note: use `let _ = ...` to ignore the expression or result
71+
help: use `let _ = ...` to ignore the expression or result
72+
|
73+
LL - forget(s5);
74+
LL + let _ = s5;
75+
|
6876

6977
warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
7078
--> $DIR/forgetting_copy_types.rs:50:5
@@ -74,7 +82,11 @@ LL | forget(a2);
7482
| |
7583
| argument has type `&AnotherStruct`
7684
|
77-
= note: use `let _ = ...` to ignore the expression or result
85+
help: use `let _ = ...` to ignore the expression or result
86+
|
87+
LL - forget(a2);
88+
LL + let _ = a2;
89+
|
7890

7991
warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
8092
--> $DIR/forgetting_copy_types.rs:52:5
@@ -84,7 +96,11 @@ LL | forget(a3);
8496
| |
8597
| argument has type `&AnotherStruct`
8698
|
87-
= note: use `let _ = ...` to ignore the expression or result
99+
help: use `let _ = ...` to ignore the expression or result
100+
|
101+
LL - forget(a3);
102+
LL + let _ = a3;
103+
|
88104

89105
warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
90106
--> $DIR/forgetting_copy_types.rs:53:5
@@ -94,7 +110,11 @@ LL | forget(a4);
94110
| |
95111
| argument has type `&AnotherStruct`
96112
|
97-
= note: use `let _ = ...` to ignore the expression or result
113+
help: use `let _ = ...` to ignore the expression or result
114+
|
115+
LL - forget(a4);
116+
LL + let _ = a4;
117+
|
98118

99119
warning: 8 warnings emitted
100120

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

tests/ui/lint/forgetting_references.rs

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ fn main() {
2323

2424
let ref reference3 = SomeStruct;
2525
forget(reference3); //~ WARN calls to `std::mem::forget`
26+
27+
let ref reference4 = SomeStruct;
28+
29+
let a = 1;
30+
match a {
31+
1 => forget(&*reference1), //~ WARN calls to `std::mem::forget`
32+
2 => forget(reference3), //~ WARN calls to `std::mem::forget`
33+
3 => forget(reference4), //~ WARN calls to `std::mem::forget`
34+
_ => {}
35+
}
2636
}
2737

2838
#[allow(dead_code)]

0 commit comments

Comments
 (0)