Skip to content

Commit a83f933

Browse files
committed
Auto merge of #125531 - surechen:make_suggestion_for_note_like_drop_lint, r=Urgau
Make lint: `lint_dropping_references` `lint_forgetting_copy_types` `lint_forgetting_references` give suggestion if possible. This is a follow-up PR of #125433. When it's merged, I want change lint `dropping_copy_types` to use the same `Subdiagnostic` struct `UseLetUnderscoreIgnoreSuggestion` which is added in this PR. Hi, Thank you(`@Urgau` ) again for your help in the previous PR. If your time permits, please also take a look at this one. r? compiler <!-- If this PR is related to an unstable feature or an otherwise tracked effort, please link to the relevant tracking issue here. If you don't know of a related tracking issue or there are none, feel free to ignore this. This PR will get automatically assigned to a reviewer. In case you would like a specific user to review your work, you can assign it to them by using r​? <reviewer name> -->
2 parents f2e1a3a + 9d1ed80 commit a83f933

17 files changed

+743
-74
lines changed

compiler/rustc_lint/messages.ftl

+3-5
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,9 @@ lint_drop_trait_constraints =
232232
233233
lint_dropping_copy_types = calls to `std::mem::drop` with a value that implements `Copy` does nothing
234234
.label = argument has type `{$arg_ty}`
235-
.note = use `let _ = ...` to ignore the expression or result
236-
.suggestion = use `let _ = ...` to ignore the expression or result
237235
238236
lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
239237
.label = argument has type `{$arg_ty}`
240-
.note = use `let _ = ...` to ignore the expression or result
241238
242239
lint_duplicate_macro_attribute =
243240
duplicated attribute
@@ -272,10 +269,9 @@ lint_for_loops_over_fallibles =
272269
273270
lint_forgetting_copy_types = calls to `std::mem::forget` with a value that implements `Copy` does nothing
274271
.label = argument has type `{$arg_ty}`
275-
.note = use `let _ = ...` to ignore the expression or result
272+
276273
lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing
277274
.label = argument has type `{$arg_ty}`
278-
.note = use `let _ = ...` to ignore the expression or result
279275
280276
lint_hidden_glob_reexport = private item shadows public glob re-export
281277
.note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here
@@ -894,6 +890,8 @@ lint_unused_op = unused {$op} that must be used
894890
895891
lint_unused_result = unused result of type `{$ty}`
896892
893+
lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
894+
897895
lint_variant_size_differences =
898896
enum variant is more than three times larger ({$largest} bytes) than the next largest
899897

compiler/rustc_lint/src/drop_forget_useless.rs

+32-19
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use rustc_span::sym;
55

66
use crate::{
77
lints::{
8-
DropCopyDiag, DropCopySuggestion, DropRefDiag, ForgetCopyDiag, ForgetRefDiag,
9-
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion,
8+
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag,
9+
UndroppedManuallyDropsSuggestion, UseLetUnderscoreIgnoreSuggestion,
1010
},
1111
LateContext, LateLintPass, LintContext,
1212
};
@@ -148,46 +148,59 @@ 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 let_underscore_ignore_sugg = || {
152+
if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)
153+
&& let Node::Stmt(stmt) = node
154+
&& let StmtKind::Semi(e) = stmt.kind
155+
&& e.hir_id == expr.hir_id
156+
{
157+
UseLetUnderscoreIgnoreSuggestion::Suggestion {
158+
start_span: expr.span.shrink_to_lo().until(arg.span),
159+
end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
160+
}
161+
} else {
162+
UseLetUnderscoreIgnoreSuggestion::Note
163+
}
164+
};
151165
match fn_name {
152166
sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
153167
cx.emit_span_lint(
154168
DROPPING_REFERENCES,
155169
expr.span,
156-
DropRefDiag { arg_ty, label: arg.span },
170+
DropRefDiag { arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg() },
157171
);
158172
}
159173
sym::mem_forget if arg_ty.is_ref() => {
160174
cx.emit_span_lint(
161175
FORGETTING_REFERENCES,
162176
expr.span,
163-
ForgetRefDiag { arg_ty, label: arg.span },
177+
ForgetRefDiag {
178+
arg_ty,
179+
label: arg.span,
180+
sugg: let_underscore_ignore_sugg(),
181+
},
164182
);
165183
}
166184
sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
167-
let sugg = if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0)
168-
&& let Node::Stmt(stmt) = node
169-
&& let StmtKind::Semi(e) = stmt.kind
170-
&& e.hir_id == expr.hir_id
171-
{
172-
DropCopySuggestion::Suggestion {
173-
start_span: expr.span.shrink_to_lo().until(arg.span),
174-
end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
175-
}
176-
} else {
177-
DropCopySuggestion::Note
178-
};
179-
180185
cx.emit_span_lint(
181186
DROPPING_COPY_TYPES,
182187
expr.span,
183-
DropCopyDiag { arg_ty, label: arg.span, sugg },
188+
DropCopyDiag {
189+
arg_ty,
190+
label: arg.span,
191+
sugg: let_underscore_ignore_sugg(),
192+
},
184193
);
185194
}
186195
sym::mem_forget if is_copy => {
187196
cx.emit_span_lint(
188197
FORGETTING_COPY_TYPES,
189198
expr.span,
190-
ForgetCopyDiag { arg_ty, label: arg.span },
199+
ForgetCopyDiag {
200+
arg_ty,
201+
label: arg.span,
202+
sugg: let_underscore_ignore_sugg(),
203+
},
191204
);
192205
}
193206
sym::mem_drop

compiler/rustc_lint/src/lints.rs

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

659+
#[derive(Subdiagnostic)]
660+
pub enum UseLetUnderscoreIgnoreSuggestion {
661+
#[note(lint_use_let_underscore_ignore_suggestion)]
662+
Note,
663+
#[multipart_suggestion(
664+
lint_use_let_underscore_ignore_suggestion,
665+
style = "verbose",
666+
applicability = "maybe-incorrect"
667+
)]
668+
Suggestion {
669+
#[suggestion_part(code = "let _ = ")]
670+
start_span: Span,
671+
#[suggestion_part(code = "")]
672+
end_span: Span,
673+
},
674+
}
675+
659676
// drop_forget_useless.rs
660677
#[derive(LintDiagnostic)]
661678
#[diag(lint_dropping_references)]
662-
#[note]
663679
pub struct DropRefDiag<'a> {
664680
pub arg_ty: Ty<'a>,
665681
#[label]
666682
pub label: Span,
683+
#[subdiagnostic]
684+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
667685
}
668686

669687
#[derive(LintDiagnostic)]
@@ -673,38 +691,27 @@ pub struct DropCopyDiag<'a> {
673691
#[label]
674692
pub label: Span,
675693
#[subdiagnostic]
676-
pub sugg: DropCopySuggestion,
677-
}
678-
679-
#[derive(Subdiagnostic)]
680-
pub enum DropCopySuggestion {
681-
#[note(lint_note)]
682-
Note,
683-
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
684-
Suggestion {
685-
#[suggestion_part(code = "let _ = ")]
686-
start_span: Span,
687-
#[suggestion_part(code = "")]
688-
end_span: Span,
689-
},
694+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
690695
}
691696

692697
#[derive(LintDiagnostic)]
693698
#[diag(lint_forgetting_references)]
694-
#[note]
695699
pub struct ForgetRefDiag<'a> {
696700
pub arg_ty: Ty<'a>,
697701
#[label]
698702
pub label: Span,
703+
#[subdiagnostic]
704+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
699705
}
700706

701707
#[derive(LintDiagnostic)]
702708
#[diag(lint_forgetting_copy_types)]
703-
#[note]
704709
pub struct ForgetCopyDiag<'a> {
705710
pub arg_ty: Ty<'a>,
706711
#[label]
707712
pub label: Span,
713+
#[subdiagnostic]
714+
pub sugg: UseLetUnderscoreIgnoreSuggestion,
708715
}
709716

710717
#[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
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+
}

0 commit comments

Comments
 (0)