Skip to content

Commit ac736d6

Browse files
committed
Let lint_forgetting_references give the suggestion if possible
1 parent d7f0d1f commit ac736d6

10 files changed

+383
-45
lines changed

compiler/rustc_lint/messages.ftl

+2-5
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,6 @@ lint_dropping_copy_types = calls to `std::mem::drop` with a value that implement
237237
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}`
240-
.note = use `let _ = ...` to ignore the expression or result
241-
.suggestion = use `let _ = ...` to ignore the expression or result
242240
243241
lint_duplicate_macro_attribute =
244242
duplicated attribute
@@ -273,12 +271,9 @@ lint_for_loops_over_fallibles =
273271
274272
lint_forgetting_copy_types = calls to `std::mem::forget` with a value that implements `Copy` does nothing
275273
.label = argument has type `{$arg_ty}`
276-
.note = use `let _ = ...` to ignore the expression or result
277-
.suggestion = use `let _ = ...` to ignore the expression or result
278274
279275
lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing
280276
.label = argument has type `{$arg_ty}`
281-
.note = use `let _ = ...` to ignore the expression or result
282277
283278
lint_hidden_glob_reexport = private item shadows public glob re-export
284279
.note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here
@@ -897,6 +892,8 @@ lint_unused_op = unused {$op} that must be used
897892
898893
lint_unused_result = unused result of type `{$ty}`
899894
895+
lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
896+
900897
lint_variant_size_differences =
901898
enum variant is more than three times larger ({$largest} bytes) than the next largest
902899

compiler/rustc_lint/src/drop_forget_useless.rs

+25-14
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ use rustc_span::sym;
55

66
use crate::{
77
lints::{
8-
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, IgnoreDropSuggestion,
8+
DropCopyDiag, DropCopySuggestion, DropRefDiag, ForgetCopyDiag, ForgetRefDiag,
99
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion,
10+
UseLetUnderscoreIgnoreSuggestion,
1011
},
1112
LateContext, LateLintPass, LintContext,
1213
};
@@ -148,31 +149,37 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
148149
let arg_ty = cx.typeck_results().expr_ty(arg);
149150
let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
150151
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()),
152+
let let_underscore_ignore_sugg = || {
153+
if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)
154+
&& let Node::Stmt(stmt) = node
155+
&& let StmtKind::Semi(e) = stmt.kind
156+
&& e.hir_id == expr.hir_id
157+
{
158+
UseLetUnderscoreIgnoreSuggestion::Suggestion {
159+
start_span: expr.span.shrink_to_lo().until(arg.span),
160+
end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
161+
}
162+
} else {
163+
UseLetUnderscoreIgnoreSuggestion::Note
159164
}
160-
} else {
161-
IgnoreDropSuggestion::Note
162165
};
163166
match fn_name {
164167
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
165168
cx.emit_span_lint(
166169
DROPPING_REFERENCES,
167170
expr.span,
168-
DropRefDiag { arg_ty, label: arg.span, sugg },
171+
DropRefDiag { arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg() },
169172
);
170173
}
171174
sym::mem_forget if arg_ty.is_ref() => {
172175
cx.emit_span_lint(
173176
FORGETTING_REFERENCES,
174177
expr.span,
175-
ForgetRefDiag { arg_ty, label: arg.span },
178+
ForgetRefDiag {
179+
arg_ty,
180+
label: arg.span,
181+
sugg: let_underscore_ignore_sugg(),
182+
},
176183
);
177184
}
178185
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
@@ -199,7 +206,11 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
199206
cx.emit_span_lint(
200207
FORGETTING_COPY_TYPES,
201208
expr.span,
202-
ForgetCopyDiag { arg_ty, label: arg.span, sugg },
209+
ForgetCopyDiag {
210+
arg_ty,
211+
label: arg.span,
212+
sugg: let_underscore_ignore_sugg(),
213+
},
203214
);
204215
}
205216
sym::mem_drop

compiler/rustc_lint/src/lints.rs

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

659659
#[derive(Subdiagnostic)]
660-
pub enum IgnoreDropSuggestion {
661-
#[note(lint_note)]
660+
pub enum UseLetUnderscoreIgnoreSuggestion {
661+
#[note(lint_use_let_underscore_ignore_suggestion)]
662662
Note,
663-
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
663+
#[multipart_suggestion(
664+
lint_use_let_underscore_ignore_suggestion,
665+
style = "verbose",
666+
applicability = "maybe-incorrect"
667+
)]
664668
Suggestion {
665669
#[suggestion_part(code = "let _ = ")]
666670
start_span: Span,
@@ -677,7 +681,7 @@ pub struct DropRefDiag<'a> {
677681
#[label]
678682
pub label: Span,
679683
#[subdiagnostic]
680-
pub sugg: IgnoreDropSuggestion,
684+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
681685
}
682686

683687
#[derive(LintDiagnostic)]
@@ -705,11 +709,12 @@ pub enum DropCopySuggestion {
705709

706710
#[derive(LintDiagnostic)]
707711
#[diag(lint_forgetting_references)]
708-
#[note]
709712
pub struct ForgetRefDiag<'a> {
710713
pub arg_ty: Ty<'a>,
711714
#[label]
712715
pub label: Span,
716+
#[subdiagnostic]
717+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
713718
}
714719

715720
#[derive(LintDiagnostic)]
@@ -719,7 +724,7 @@ pub struct ForgetCopyDiag<'a> {
719724
#[label]
720725
pub label: Span,
721726
#[subdiagnostic]
722-
pub sugg: IgnoreDropSuggestion,
727+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
723728
}
724729

725730
#[derive(LintDiagnostic)]

tests/ui/lint/dropping_copy_types.stderr

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

4549
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
4650
--> $DIR/dropping_copy_types.rs:37:5
@@ -64,7 +68,11 @@ LL | drop(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 - drop(s5);
74+
LL + let _ = s5;
75+
|
6876

6977
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
7078
--> $DIR/dropping_copy_types.rs:50:5
@@ -74,7 +82,11 @@ LL | drop(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 - drop(a2);
88+
LL + let _ = a2;
89+
|
7890

7991
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
8092
--> $DIR/dropping_copy_types.rs:52:5
@@ -84,7 +96,11 @@ LL | drop(a4);
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 - drop(a4);
102+
LL + let _ = a4;
103+
|
88104

89105
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
90106
--> $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)