Skip to content

Commit 9a5bb1f

Browse files
committed
Use labels to indicate what may need to be moved
1 parent ed1ed42 commit 9a5bb1f

12 files changed

+311
-114
lines changed

compiler/rustc_lint/messages.ftl

+3-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ lint_non_local_definitions_deprecation = this lint may become deny-by-default in
442442
443443
lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
444444
.help =
445-
move this `impl` block and all the necessary types/traits outside the of the current {$body_kind_descr} {$depth ->
445+
move this `impl` block and outside the of the current {$body_kind_descr} {$depth ->
446446
[one] `{$body_name}`
447447
*[other] `{$body_name}` and up {$depth} bodies
448448
}
@@ -463,6 +463,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#
463463
.non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
464464
.exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module
465465
466+
lint_non_local_definitions_may_move = may need to be moved as well
467+
466468
lint_non_snake_case = {$sort} `{$name}` should have a snake case name
467469
.rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
468470
.cannot_convert_note = `{$sc}` cannot be used as a raw identifier

compiler/rustc_lint/src/lints.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::errors::RequestedLevel;
66
use crate::fluent_generated as fluent;
77
use rustc_errors::{
88
codes::*, Applicability, Diag, DiagMessage, DiagStyledString, EmissionGuarantee,
9-
LintDiagnostic, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
9+
LintDiagnostic, MultiSpan, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
1010
};
1111
use rustc_hir::def_id::DefId;
1212
use rustc_macros::{LintDiagnostic, Subdiagnostic};
@@ -1341,6 +1341,8 @@ pub enum NonLocalDefinitionsDiag {
13411341
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
13421342
const_anon: Option<Option<Span>>,
13431343
move_help: Span,
1344+
self_ty: Span,
1345+
of_trait: Option<Span>,
13441346
has_trait: bool,
13451347
},
13461348
MacroRules {
@@ -1363,6 +1365,8 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
13631365
cargo_update,
13641366
const_anon,
13651367
move_help,
1368+
self_ty,
1369+
of_trait,
13661370
has_trait,
13671371
} => {
13681372
diag.arg("depth", depth);
@@ -1375,7 +1379,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
13751379
} else {
13761380
diag.note(fluent::lint_without_trait);
13771381
}
1378-
diag.span_help(move_help, fluent::lint_help);
1382+
let mut ms = MultiSpan::from_span(move_help);
1383+
ms.push_span_label(self_ty, fluent::lint_non_local_definitions_may_move);
1384+
if let Some(of_trait) = of_trait {
1385+
ms.push_span_label(of_trait, fluent::lint_non_local_definitions_may_move);
1386+
}
1387+
diag.span_help(ms, fluent::lint_help);
13791388

13801389
if let Some(cargo_update) = cargo_update {
13811390
diag.subdiagnostic(&diag.dcx, cargo_update);

compiler/rustc_lint/src/non_local_def.rs

+2
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
223223
NonLocalDefinitionsDiag::Impl {
224224
depth: self.body_depth,
225225
move_help: item.span,
226+
self_ty: impl_.self_ty.span,
227+
of_trait: impl_.of_trait.map(|t| t.path.span),
226228
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
227229
body_name: parent_opt_item_name
228230
.map(|s| s.to_ident_string())

tests/ui/lint/non-local-defs/cargo-update.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ LL | non_local_macro::non_local_impl!(LocalStruct);
66
|
77
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
88
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
9-
help: move this `impl` block and all the necessary types/traits outside the of the current constant `_IMPL_DEBUG`
9+
help: move this `impl` block and outside the of the current constant `_IMPL_DEBUG`
1010
--> $DIR/cargo-update.rs:17:1
1111
|
1212
LL | non_local_macro::non_local_impl!(LocalStruct);
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
| |
15+
| may need to be moved as well
16+
| may need to be moved as well
1417
= note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
1518
= note: anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type are consider to be transparent regarding the nesting level
1619
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>

tests/ui/lint/non-local-defs/consts.stderr

+40-16
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ LL | impl Uto for &Test {}
99
|
1010
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
1111
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
12-
help: move this `impl` block and all the necessary types/traits outside the of the current constant `Z`
12+
help: move this `impl` block and outside the of the current constant `Z`
1313
--> $DIR/consts.rs:13:5
1414
|
1515
LL | impl Uto for &Test {}
16-
| ^^^^^^^^^^^^^^^^^^^^^
16+
| ^^^^^---^^^^^-----^^^
17+
| | |
18+
| | may need to be moved as well
19+
| may need to be moved as well
1720
= note: anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type are consider to be transparent regarding the nesting level
1821
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
1922
= note: `#[warn(non_local_definitions)]` on by default
@@ -26,11 +29,14 @@ LL | impl Uto2 for Test {}
2629
|
2730
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
2831
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
29-
help: move this `impl` block and all the necessary types/traits outside the of the current static `A`
32+
help: move this `impl` block and outside the of the current static `A`
3033
--> $DIR/consts.rs:24:5
3134
|
3235
LL | impl Uto2 for Test {}
33-
| ^^^^^^^^^^^^^^^^^^^^^
36+
| ^^^^^----^^^^^----^^^
37+
| | |
38+
| | may need to be moved as well
39+
| may need to be moved as well
3440
= note: anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type are consider to be transparent regarding the nesting level
3541
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
3642

@@ -42,11 +48,14 @@ LL | impl Uto3 for Test {}
4248
|
4349
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
4450
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
45-
help: move this `impl` block and all the necessary types/traits outside the of the current constant `B`
51+
help: move this `impl` block and outside the of the current constant `B`
4652
--> $DIR/consts.rs:32:5
4753
|
4854
LL | impl Uto3 for Test {}
49-
| ^^^^^^^^^^^^^^^^^^^^^
55+
| ^^^^^----^^^^^----^^^
56+
| | |
57+
| | may need to be moved as well
58+
| may need to be moved as well
5059
= note: anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type are consider to be transparent regarding the nesting level
5160
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
5261

@@ -57,10 +66,13 @@ LL | impl Test {
5766
| ^^^^^^^^^
5867
|
5968
= note: methods and assoc const are still usable outside the current expression, only `impl Local` and `impl dyn Local` are local and only if the `Local` type is at the same nesting as the `impl` block
60-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
69+
help: move this `impl` block and outside the of the current function `main`
6170
--> $DIR/consts.rs:43:5
6271
|
63-
LL | / impl Test {
72+
LL | impl Test {
73+
| ^ ---- may need to be moved as well
74+
| _____|
75+
| |
6476
LL | |
6577
LL | | fn foo() {}
6678
LL | | }
@@ -74,10 +86,13 @@ LL | impl Test {
7486
| ^^^^^^^^^
7587
|
7688
= note: methods and assoc const are still usable outside the current expression, only `impl Local` and `impl dyn Local` are local and only if the `Local` type is at the same nesting as the `impl` block
77-
help: move this `impl` block and all the necessary types/traits outside the of the current inline constant `<unnameable>` and up 2 bodies
89+
help: move this `impl` block and outside the of the current inline constant `<unnameable>` and up 2 bodies
7890
--> $DIR/consts.rs:50:9
7991
|
80-
LL | / impl Test {
92+
LL | impl Test {
93+
| ^ ---- may need to be moved as well
94+
| _________|
95+
| |
8196
LL | |
8297
LL | | fn hoo() {}
8398
LL | | }
@@ -91,10 +106,13 @@ LL | impl Test {
91106
| ^^^^^^^^^
92107
|
93108
= note: methods and assoc const are still usable outside the current expression, only `impl Local` and `impl dyn Local` are local and only if the `Local` type is at the same nesting as the `impl` block
94-
help: move this `impl` block and all the necessary types/traits outside the of the current constant `_` and up 2 bodies
109+
help: move this `impl` block and outside the of the current constant `_` and up 2 bodies
95110
--> $DIR/consts.rs:59:9
96111
|
97-
LL | / impl Test {
112+
LL | impl Test {
113+
| ^ ---- may need to be moved as well
114+
| _________|
115+
| |
98116
LL | |
99117
LL | | fn foo2() {}
100118
LL | | }
@@ -110,11 +128,14 @@ LL | impl Uto9 for Test {}
110128
|
111129
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
112130
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
113-
help: move this `impl` block and all the necessary types/traits outside the of the current closure `<unnameable>` and up 2 bodies
131+
help: move this `impl` block and outside the of the current closure `<unnameable>` and up 2 bodies
114132
--> $DIR/consts.rs:72:9
115133
|
116134
LL | impl Uto9 for Test {}
117-
| ^^^^^^^^^^^^^^^^^^^^^
135+
| ^^^^^----^^^^^----^^^
136+
| | |
137+
| | may need to be moved as well
138+
| may need to be moved as well
118139
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
119140

120141
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -125,11 +146,14 @@ LL | impl Uto10 for Test {}
125146
|
126147
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
127148
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
128-
help: move this `impl` block and all the necessary types/traits outside the of the current constant expression `<unnameable>` and up 2 bodies
149+
help: move this `impl` block and outside the of the current constant expression `<unnameable>` and up 2 bodies
129150
--> $DIR/consts.rs:79:9
130151
|
131152
LL | impl Uto10 for Test {}
132-
| ^^^^^^^^^^^^^^^^^^^^^^
153+
| ^^^^^-----^^^^^----^^^
154+
| | |
155+
| | may need to be moved as well
156+
| may need to be moved as well
133157
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
134158

135159
warning: 8 warnings emitted

tests/ui/lint/non-local-defs/exhaustive-trait.stderr

+36-12
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ LL | impl PartialEq<()> for Dog {
66
|
77
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
88
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
9-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
9+
help: move this `impl` block and outside the of the current function `main`
1010
--> $DIR/exhaustive-trait.rs:7:5
1111
|
12-
LL | / impl PartialEq<()> for Dog {
12+
LL | impl PartialEq<()> for Dog {
13+
| ^ ------------- --- may need to be moved as well
14+
| | |
15+
| _____| may need to be moved as well
16+
| |
1317
LL | |
1418
LL | | fn eq(&self, _: &()) -> bool {
1519
LL | | todo!()
@@ -27,10 +31,14 @@ LL | impl PartialEq<()> for &Dog {
2731
|
2832
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
2933
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
30-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
34+
help: move this `impl` block and outside the of the current function `main`
3135
--> $DIR/exhaustive-trait.rs:14:5
3236
|
33-
LL | / impl PartialEq<()> for &Dog {
37+
LL | impl PartialEq<()> for &Dog {
38+
| ^ ------------- ---- may need to be moved as well
39+
| | |
40+
| _____| may need to be moved as well
41+
| |
3442
LL | |
3543
LL | | fn eq(&self, _: &()) -> bool {
3644
LL | | todo!()
@@ -47,10 +55,14 @@ LL | impl PartialEq<Dog> for () {
4755
|
4856
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
4957
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
50-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
58+
help: move this `impl` block and outside the of the current function `main`
5159
--> $DIR/exhaustive-trait.rs:21:5
5260
|
53-
LL | / impl PartialEq<Dog> for () {
61+
LL | impl PartialEq<Dog> for () {
62+
| ^ -------------- -- may need to be moved as well
63+
| | |
64+
| _____| may need to be moved as well
65+
| |
5466
LL | |
5567
LL | | fn eq(&self, _: &Dog) -> bool {
5668
LL | | todo!()
@@ -67,10 +79,14 @@ LL | impl PartialEq<&Dog> for () {
6779
|
6880
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
6981
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
70-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
82+
help: move this `impl` block and outside the of the current function `main`
7183
--> $DIR/exhaustive-trait.rs:28:5
7284
|
73-
LL | / impl PartialEq<&Dog> for () {
85+
LL | impl PartialEq<&Dog> for () {
86+
| ^ --------------- -- may need to be moved as well
87+
| | |
88+
| _____| may need to be moved as well
89+
| |
7490
LL | |
7591
LL | | fn eq(&self, _: &&Dog) -> bool {
7692
LL | | todo!()
@@ -87,10 +103,14 @@ LL | impl PartialEq<Dog> for &Dog {
87103
|
88104
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
89105
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
90-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
106+
help: move this `impl` block and outside the of the current function `main`
91107
--> $DIR/exhaustive-trait.rs:35:5
92108
|
93-
LL | / impl PartialEq<Dog> for &Dog {
109+
LL | impl PartialEq<Dog> for &Dog {
110+
| ^ -------------- ---- may need to be moved as well
111+
| | |
112+
| _____| may need to be moved as well
113+
| |
94114
LL | |
95115
LL | | fn eq(&self, _: &Dog) -> bool {
96116
LL | | todo!()
@@ -107,10 +127,14 @@ LL | impl PartialEq<&Dog> for &Dog {
107127
|
108128
= note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
109129
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
110-
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
130+
help: move this `impl` block and outside the of the current function `main`
111131
--> $DIR/exhaustive-trait.rs:42:5
112132
|
113-
LL | / impl PartialEq<&Dog> for &Dog {
133+
LL | impl PartialEq<&Dog> for &Dog {
134+
| ^ --------------- ---- may need to be moved as well
135+
| | |
136+
| _____| may need to be moved as well
137+
| |
114138
LL | |
115139
LL | | fn eq(&self, _: &&Dog) -> bool {
116140
LL | | todo!()

0 commit comments

Comments
 (0)