Skip to content

Commit 963e221

Browse files
committed
Let lint_forgetting_references give the suggestion if possible
1 parent d0d0a45 commit 963e221

10 files changed

+384
-41
lines changed

compiler/rustc_lint/messages.ftl

+3
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 ->
@@ -642,5 +643,7 @@ lint_unused_op = unused {$op} that must be used
642643
643644
lint_unused_result = unused result of type `{$ty}`
644645
646+
lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
647+
645648
lint_variant_size_differences =
646649
enum variant is more than three times larger ({$largest} bytes) than the next largest

compiler/rustc_lint/src/drop_forget_useless.rs

+25-15
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
};
@@ -147,31 +147,37 @@ 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()),
150+
let let_underscore_ignore_sugg = || {
151+
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+
UseLetUnderscoreIgnoreSuggestion::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+
UseLetUnderscoreIgnoreSuggestion::Note
158162
}
159-
} else {
160-
IgnoreDropSuggestion::Note
161163
};
162164
match fn_name {
163165
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
164166
cx.emit_span_lint(
165167
DROPPING_REFERENCES,
166168
expr.span,
167-
DropRefDiag { arg_ty, label: arg.span, sugg },
169+
DropRefDiag { arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg() },
168170
);
169171
}
170172
sym::mem_forget if arg_ty.is_ref() => {
171173
cx.emit_span_lint(
172174
FORGETTING_REFERENCES,
173175
expr.span,
174-
ForgetRefDiag { arg_ty, label: arg.span },
176+
ForgetRefDiag {
177+
arg_ty,
178+
label: arg.span,
179+
sugg: let_underscore_ignore_sugg(),
180+
},
175181
);
176182
}
177183
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
@@ -185,7 +191,11 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
185191
cx.emit_span_lint(
186192
FORGETTING_COPY_TYPES,
187193
expr.span,
188-
ForgetCopyDiag { arg_ty, label: arg.span, sugg },
194+
ForgetCopyDiag {
195+
arg_ty,
196+
label: arg.span,
197+
sugg: let_underscore_ignore_sugg(),
198+
},
189199
);
190200
}
191201
sym::mem_drop

compiler/rustc_lint/src/lints.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -658,10 +658,14 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
658658
}
659659

660660
#[derive(Subdiagnostic)]
661-
pub enum IgnoreDropSuggestion {
662-
#[note(lint_note)]
661+
pub enum UseLetUnderscoreIgnoreSuggestion {
662+
#[note(lint_use_let_underscore_ignore_suggestion)]
663663
Note,
664-
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
664+
#[multipart_suggestion(
665+
lint_use_let_underscore_ignore_suggestion,
666+
style = "verbose",
667+
applicability = "maybe-incorrect"
668+
)]
665669
Suggestion {
666670
#[suggestion_part(code = "let _ = ")]
667671
start_span: Span,
@@ -678,7 +682,7 @@ pub struct DropRefDiag<'a> {
678682
#[label]
679683
pub label: Span,
680684
#[subdiagnostic]
681-
pub sugg: IgnoreDropSuggestion,
685+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
682686
}
683687

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

693697
#[derive(LintDiagnostic)]
694698
#[diag(lint_forgetting_references)]
695-
#[note]
696699
pub struct ForgetRefDiag<'a> {
697700
pub arg_ty: Ty<'a>,
698701
#[label]
699702
pub label: Span,
703+
#[subdiagnostic]
704+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
700705
}
701706

702707
#[derive(LintDiagnostic)]
@@ -706,7 +711,7 @@ pub struct ForgetCopyDiag<'a> {
706711
#[label]
707712
pub label: Span,
708713
#[subdiagnostic]
709-
pub sugg: IgnoreDropSuggestion,
714+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
710715
}
711716

712717
#[derive(LintDiagnostic)]

tests/ui/lint/dropping_copy_types.stderr

+20-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ LL | drop(s3);
3131
| |
3232
| argument has type `&SomeStruct`
3333
|
34-
= note: use `let _ = ...` to ignore the expression or result
3534
= note: `#[warn(dropping_references)]` on by default
35+
help: use `let _ = ...` to ignore the expression or result
36+
|
37+
LL - drop(s3);
38+
LL + let _ = s3;
39+
|
3640

3741
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
3842
--> $DIR/dropping_copy_types.rs:37:5
@@ -52,7 +56,11 @@ LL | drop(s5);
5256
| |
5357
| argument has type `&SomeStruct`
5458
|
55-
= note: use `let _ = ...` to ignore the expression or result
59+
help: use `let _ = ...` to ignore the expression or result
60+
|
61+
LL - drop(s5);
62+
LL + let _ = s5;
63+
|
5664

5765
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
5866
--> $DIR/dropping_copy_types.rs:50:5
@@ -62,7 +70,11 @@ LL | drop(a2);
6270
| |
6371
| argument has type `&AnotherStruct`
6472
|
65-
= note: use `let _ = ...` to ignore the expression or result
73+
help: use `let _ = ...` to ignore the expression or result
74+
|
75+
LL - drop(a2);
76+
LL + let _ = a2;
77+
|
6678

6779
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
6880
--> $DIR/dropping_copy_types.rs:52:5
@@ -72,7 +84,11 @@ LL | drop(a4);
7284
| |
7385
| argument has type `&AnotherStruct`
7486
|
75-
= note: use `let _ = ...` to ignore the expression or result
87+
help: use `let _ = ...` to ignore the expression or result
88+
|
89+
LL - drop(a4);
90+
LL + let _ = a4;
91+
|
7692

7793
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
7894
--> $DIR/dropping_copy_types.rs:71:13

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+
}

0 commit comments

Comments
 (0)