Skip to content

Commit 22095fb

Browse files
committed
non_local_defs: use labels to indicate what may need to be moved
1 parent 26b873d commit 22095fb

12 files changed

+587
-59
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ lint_non_local_definitions_deprecation = this lint may become deny-by-default in
544544
545545
lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
546546
.help =
547-
move this `impl` block outside the of the current {$body_kind_descr} {$depth ->
547+
move this `impl` block outside of the current {$body_kind_descr} {$depth ->
548548
[one] `{$body_name}`
549549
*[other] `{$body_name}` and up {$depth} bodies
550550
}
@@ -565,6 +565,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#
565565
.non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
566566
.exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module
567567
568+
lint_non_local_definitions_may_move = may need to be moved as well
569+
568570
lint_non_snake_case = {$sort} `{$name}` should have a snake case name
569571
.rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
570572
.cannot_convert_note = `{$sc}` cannot be used as a raw identifier

compiler/rustc_lint/src/lints.rs

Lines changed: 13 additions & 2 deletions
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, DiagArgValue, DiagMessage, DiagStyledString,
9-
ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, SubdiagMessageOp,
9+
ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,
1010
Subdiagnostic, SuggestionStyle,
1111
};
1212
use rustc_hir::{def::Namespace, def_id::DefId};
@@ -1336,6 +1336,9 @@ pub enum NonLocalDefinitionsDiag {
13361336
body_name: String,
13371337
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
13381338
const_anon: Option<Option<Span>>,
1339+
move_help: Span,
1340+
self_ty: Span,
1341+
of_trait: Option<Span>,
13391342
has_trait: bool,
13401343
},
13411344
MacroRules {
@@ -1357,20 +1360,28 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
13571360
body_name,
13581361
cargo_update,
13591362
const_anon,
1363+
move_help,
1364+
self_ty,
1365+
of_trait,
13601366
has_trait,
13611367
} => {
13621368
diag.primary_message(fluent::lint_non_local_definitions_impl);
13631369
diag.arg("depth", depth);
13641370
diag.arg("body_kind_descr", body_kind_descr);
13651371
diag.arg("body_name", body_name);
13661372

1367-
diag.help(fluent::lint_help);
13681373
if has_trait {
13691374
diag.note(fluent::lint_bounds);
13701375
diag.note(fluent::lint_with_trait);
13711376
} else {
13721377
diag.note(fluent::lint_without_trait);
13731378
}
1379+
let mut ms = MultiSpan::from_span(move_help);
1380+
ms.push_span_label(self_ty, fluent::lint_non_local_definitions_may_move);
1381+
if let Some(of_trait) = of_trait {
1382+
ms.push_span_label(of_trait, fluent::lint_non_local_definitions_may_move);
1383+
}
1384+
diag.span_help(ms, fluent::lint_help);
13741385

13751386
if let Some(cargo_update) = cargo_update {
13761387
diag.subdiagnostic(&diag.dcx, cargo_update);

compiler/rustc_lint/src/non_local_def.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
222222
item.span.shrink_to_lo().to(impl_.self_ty.span),
223223
NonLocalDefinitionsDiag::Impl {
224224
depth: self.body_depth,
225+
move_help: item.span,
226+
self_ty: impl_.self_ty.span,
227+
of_trait: impl_.of_trait.map(|t| t.path.span),
225228
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
226229
body_name: parent_opt_item_name
227230
.map(|s| s.to_ident_string())

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
44
LL | non_local_macro::non_local_impl!(LocalStruct);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= help: move this `impl` block outside the of the current constant `_IMPL_DEBUG`
87
= 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
98
= 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 outside of the current constant `_IMPL_DEBUG`
10+
--> $DIR/cargo-update.rs:17:1
11+
|
12+
LL | non_local_macro::non_local_impl!(LocalStruct);
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
| |
15+
| may need to be moved as well
16+
| may need to be moved as well
1017
= 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`
1118
= 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
1219
= 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

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ LL | const Z: () = {
77
LL | impl Uto for &Test {}
88
| ^^^^^^^^^^^^^^^^^^
99
|
10-
= help: move this `impl` block outside the of the current constant `Z`
1110
= 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
1211
= 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 outside of the current constant `Z`
13+
--> $DIR/consts.rs:13:5
14+
|
15+
LL | impl Uto for &Test {}
16+
| ^^^^^---^^^^^-----^^^
17+
| | |
18+
| | may need to be moved as well
19+
| may need to be moved as well
1320
= 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
1421
= 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>
1522
= note: `#[warn(non_local_definitions)]` on by default
@@ -20,9 +27,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
2027
LL | impl Uto2 for Test {}
2128
| ^^^^^^^^^^^^^^^^^^
2229
|
23-
= help: move this `impl` block outside the of the current static `A`
2430
= 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
2531
= 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`
32+
help: move this `impl` block outside of the current static `A`
33+
--> $DIR/consts.rs:24:5
34+
|
35+
LL | impl Uto2 for Test {}
36+
| ^^^^^----^^^^^----^^^
37+
| | |
38+
| | may need to be moved as well
39+
| may need to be moved as well
2640
= 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
2741
= 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>
2842

@@ -32,9 +46,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
3246
LL | impl Uto3 for Test {}
3347
| ^^^^^^^^^^^^^^^^^^
3448
|
35-
= help: move this `impl` block outside the of the current constant `B`
3649
= 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
3750
= 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`
51+
help: move this `impl` block outside of the current constant `B`
52+
--> $DIR/consts.rs:32:5
53+
|
54+
LL | impl Uto3 for Test {}
55+
| ^^^^^----^^^^^----^^^
56+
| | |
57+
| | may need to be moved as well
58+
| may need to be moved as well
3859
= 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
3960
= 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>
4061

@@ -44,8 +65,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
4465
LL | impl Test {
4566
| ^^^^^^^^^
4667
|
47-
= help: move this `impl` block outside the of the current function `main`
4868
= 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
69+
help: move this `impl` block outside of the current function `main`
70+
--> $DIR/consts.rs:43:5
71+
|
72+
LL | impl Test {
73+
| ^ ---- may need to be moved as well
74+
| _____|
75+
| |
76+
LL | |
77+
LL | | fn foo() {}
78+
LL | | }
79+
| |_____^
4980
= 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>
5081

5182
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -54,8 +85,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
5485
LL | impl Test {
5586
| ^^^^^^^^^
5687
|
57-
= help: move this `impl` block outside the of the current inline constant `<unnameable>` and up 2 bodies
5888
= 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
89+
help: move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
90+
--> $DIR/consts.rs:50:9
91+
|
92+
LL | impl Test {
93+
| ^ ---- may need to be moved as well
94+
| _________|
95+
| |
96+
LL | |
97+
LL | | fn hoo() {}
98+
LL | | }
99+
| |_________^
59100
= 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>
60101

61102
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -64,8 +105,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
64105
LL | impl Test {
65106
| ^^^^^^^^^
66107
|
67-
= help: move this `impl` block outside the of the current constant `_` and up 2 bodies
68108
= 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
109+
help: move this `impl` block outside of the current constant `_` and up 2 bodies
110+
--> $DIR/consts.rs:59:9
111+
|
112+
LL | impl Test {
113+
| ^ ---- may need to be moved as well
114+
| _________|
115+
| |
116+
LL | |
117+
LL | | fn foo2() {}
118+
LL | | }
119+
| |_________^
69120
= 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
70121
= 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>
71122

@@ -75,9 +126,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
75126
LL | impl Uto9 for Test {}
76127
| ^^^^^^^^^^^^^^^^^^
77128
|
78-
= help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
79129
= 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
80130
= 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`
131+
help: move this `impl` block outside of the current closure `<unnameable>` and up 2 bodies
132+
--> $DIR/consts.rs:72:9
133+
|
134+
LL | impl Uto9 for Test {}
135+
| ^^^^^----^^^^^----^^^
136+
| | |
137+
| | may need to be moved as well
138+
| may need to be moved as well
81139
= 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>
82140

83141
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -86,9 +144,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
86144
LL | impl Uto10 for Test {}
87145
| ^^^^^^^^^^^^^^^^^^^
88146
|
89-
= help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
90147
= 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
91148
= 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`
149+
help: move this `impl` block outside of the current constant expression `<unnameable>` and up 2 bodies
150+
--> $DIR/consts.rs:79:9
151+
|
152+
LL | impl Uto10 for Test {}
153+
| ^^^^^-----^^^^^----^^^
154+
| | |
155+
| | may need to be moved as well
156+
| may need to be moved as well
92157
= 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>
93158

94159
warning: 8 warnings emitted

0 commit comments

Comments
 (0)