Skip to content

Commit 5044fb6

Browse files
committed
Point the parent item and items that needs to be moved when appropriate
1 parent 1e07c18 commit 5044fb6

13 files changed

+311
-462
lines changed

Diff for: compiler/rustc_lint/messages.ftl

+6-5
Original file line numberDiff line numberDiff line change
@@ -452,18 +452,19 @@ lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may
452452
lint_non_local_definitions_deprecation = 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>
453453
454454
lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
455-
.move_help =
456-
move this `impl` block outside of the current {$body_kind_descr} {$depth ->
457-
[one] `{$body_name}`
458-
*[other] `{$body_name}` and up {$depth} bodies
459-
}
460455
.remove_help = remove `{$may_remove_part}` to make the `impl` local
461456
.without_trait = methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
462457
.with_trait = 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`
463458
.bounds = `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
464459
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
465460
.const_anon = use a const-anon item to suppress this lint
466461
462+
lint_non_local_definitions_impl_move_help =
463+
move this `impl` block outside of the current {$body_kind_descr} {$depth ->
464+
[one] `{$body_name}`
465+
*[other] `{$body_name}` and up {$depth} bodies
466+
}
467+
467468
lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
468469
.help =
469470
remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->

Diff for: compiler/rustc_lint/src/lints.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1340,8 +1340,7 @@ pub enum NonLocalDefinitionsDiag {
13401340
body_name: String,
13411341
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
13421342
const_anon: Option<Option<Span>>,
1343-
move_help: Span,
1344-
may_move: Vec<Span>,
1343+
move_to: Option<(Span, Vec<Span>)>,
13451344
may_remove: Option<(Span, String)>,
13461345
has_trait: bool,
13471346
self_ty_str: String,
@@ -1366,8 +1365,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
13661365
body_name,
13671366
cargo_update,
13681367
const_anon,
1369-
move_help,
1370-
may_move,
1368+
move_to,
13711369
may_remove,
13721370
has_trait,
13731371
self_ty_str,
@@ -1388,11 +1386,13 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
13881386
diag.note(fluent::lint_without_trait);
13891387
}
13901388

1391-
let mut ms = MultiSpan::from_span(move_help);
1392-
for sp in may_move {
1393-
ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
1389+
if let Some((move_help, may_move)) = move_to {
1390+
let mut ms = MultiSpan::from_span(move_help);
1391+
for sp in may_move {
1392+
ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
1393+
}
1394+
diag.span_help(ms, fluent::lint_non_local_definitions_impl_move_help);
13941395
}
1395-
diag.span_help(ms, fluent::lint_move_help);
13961396

13971397
if let Some((span, part)) = may_remove {
13981398
diag.arg("may_remove_part", part);

Diff for: compiler/rustc_lint/src/non_local_def.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
198198
}
199199
collector.visit_generics(&impl_.generics);
200200

201-
let may_move: Vec<Span> = collector
201+
let mut may_move: Vec<Span> = collector
202202
.paths
203203
.into_iter()
204204
.filter_map(|path| {
205-
if path_has_local_parent(&path, cx, parent, parent_parent) {
206-
Some(path_span_without_args(&path))
205+
if let Some(did) = path.res.opt_def_id()
206+
&& did_has_local_parent(did, cx.tcx, parent, parent_parent)
207+
{
208+
Some(cx.tcx.def_span(did))
207209
} else {
208210
None
209211
}
210212
})
211213
.collect();
214+
may_move.sort();
215+
may_move.dedup();
212216

213217
let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. })
214218
.then_some(span_for_const_anon_suggestion);
@@ -244,13 +248,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
244248
} else {
245249
None
246250
};
251+
let move_to = if may_move.is_empty() {
252+
ms.push_span_label(
253+
cx.tcx.def_span(parent),
254+
fluent::lint_non_local_definitions_impl_move_help,
255+
);
256+
None
257+
} else {
258+
Some((cx.tcx.def_span(parent), may_move))
259+
};
247260

248261
cx.emit_span_lint(
249262
NON_LOCAL_DEFINITIONS,
250263
ms,
251264
NonLocalDefinitionsDiag::Impl {
252265
depth: self.body_depth,
253-
move_help: item.span,
254266
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
255267
body_name: parent_opt_item_name
256268
.map(|s| s.to_ident_string())
@@ -259,7 +271,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
259271
const_anon,
260272
self_ty_str,
261273
of_trait_str,
262-
may_move,
274+
move_to,
263275
may_remove,
264276
has_trait: impl_.of_trait.is_some(),
265277
},

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

+1-5
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,10 @@ LL | non_local_macro::non_local_impl!(LocalStruct);
66
| |
77
| `LocalStruct` is not local
88
| `Debug` is not local
9+
| move this `impl` block outside of the current constant `_IMPL_DEBUG`
910
|
1011
= 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
1112
= 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 `_IMPL_DEBUG`
13-
--> $DIR/cargo-update.rs:17:1
14-
|
15-
LL | non_local_macro::non_local_impl!(LocalStruct);
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1713
= 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`
1814
= note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
1915
= 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>

Diff for: tests/ui/lint/non-local-defs/consts.stderr

+37-59
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
22
--> $DIR/consts.rs:13:5
33
|
44
LL | const Z: () = {
5-
| - help: use a const-anon item to suppress this lint: `_`
5+
| -----------
6+
| | |
7+
| | help: use a const-anon item to suppress this lint: `_`
8+
| move this `impl` block outside of the current constant `Z`
69
...
710
LL | impl Uto for &Test {}
811
| ^^^^^---^^^^^-----
@@ -12,18 +15,15 @@ LL | impl Uto for &Test {}
1215
|
1316
= 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
1417
= 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`
15-
help: move this `impl` block outside of the current constant `Z`
16-
--> $DIR/consts.rs:13:5
17-
|
18-
LL | impl Uto for &Test {}
19-
| ^^^^^^^^^^^^^^^^^^^^^
2018
= note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
2119
= 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>
2220
= note: `#[warn(non_local_definitions)]` on by default
2321

2422
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
2523
--> $DIR/consts.rs:24:5
2624
|
25+
LL | static A: u32 = {
26+
| ------------- move this `impl` block outside of the current static `A`
2727
LL | impl Uto2 for Test {}
2828
| ^^^^^----^^^^^----
2929
| | |
@@ -32,17 +32,14 @@ LL | impl Uto2 for Test {}
3232
|
3333
= 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
3434
= 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`
35-
help: move this `impl` block outside of the current static `A`
36-
--> $DIR/consts.rs:24:5
37-
|
38-
LL | impl Uto2 for Test {}
39-
| ^^^^^^^^^^^^^^^^^^^^^
4035
= note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
4136
= 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>
4237

4338
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
4439
--> $DIR/consts.rs:32:5
4540
|
41+
LL | const B: u32 = {
42+
| ------------ move this `impl` block outside of the current constant `B`
4643
LL | impl Uto3 for Test {}
4744
| ^^^^^----^^^^^----
4845
| | |
@@ -51,75 +48,60 @@ LL | impl Uto3 for Test {}
5148
|
5249
= 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
5350
= 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`
54-
help: move this `impl` block outside of the current constant `B`
55-
--> $DIR/consts.rs:32:5
56-
|
57-
LL | impl Uto3 for Test {}
58-
| ^^^^^^^^^^^^^^^^^^^^^
5951
= note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
6052
= 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>
6153

6254
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
6355
--> $DIR/consts.rs:43:5
6456
|
57+
LL | fn main() {
58+
| --------- move this `impl` block outside of the current function `main`
6559
LL | impl Test {
6660
| ^^^^^----
6761
| |
6862
| `Test` is not local
6963
|
7064
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
71-
help: move this `impl` block outside of the current function `main`
72-
--> $DIR/consts.rs:43:5
73-
|
74-
LL | / impl Test {
75-
LL | |
76-
LL | | fn foo() {}
77-
LL | | }
78-
| |_____^
7965
= 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>
8066

8167
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
8268
--> $DIR/consts.rs:50:9
8369
|
84-
LL | impl Test {
85-
| ^^^^^----
86-
| |
87-
| `Test` is not local
88-
|
89-
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
90-
help: move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
91-
--> $DIR/consts.rs:50:9
92-
|
93-
LL | / impl Test {
70+
LL | const {
71+
| ___________-
72+
LL | | impl Test {
73+
| | ^^^^^----
74+
| | |
75+
| | `Test` is not local
9476
LL | |
9577
LL | | fn hoo() {}
96-
LL | | }
97-
| |_________^
78+
... |
79+
LL | | 1
80+
LL | | };
81+
| |_____- move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
82+
|
83+
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
9884
= 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>
9985

10086
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
10187
--> $DIR/consts.rs:59:9
10288
|
89+
LL | const _: u32 = {
90+
| ------------ move this `impl` block outside of the current constant `_` and up 2 bodies
10391
LL | impl Test {
10492
| ^^^^^----
10593
| |
10694
| `Test` is not local
10795
|
10896
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
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-
LL | |
114-
LL | | fn foo2() {}
115-
LL | | }
116-
| |_________^
11797
= note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
11898
= 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>
11999

120100
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
121101
--> $DIR/consts.rs:72:9
122102
|
103+
LL | let _a = || {
104+
| -- move this `impl` block outside of the current closure `<unnameable>` and up 2 bodies
123105
LL | impl Uto9 for Test {}
124106
| ^^^^^----^^^^^----
125107
| | |
@@ -128,29 +110,25 @@ LL | impl Uto9 for Test {}
128110
|
129111
= 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
130112
= 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-
| ^^^^^^^^^^^^^^^^^^^^^
136113
= 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>
137114

138115
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
139116
--> $DIR/consts.rs:79:9
140117
|
141-
LL | impl Uto10 for Test {}
142-
| ^^^^^-----^^^^^----
143-
| | |
144-
| | `Test` is not local
145-
| `Uto10` is not local
118+
LL | type A = [u32; {
119+
| ____________________-
120+
LL | | impl Uto10 for Test {}
121+
| | ^^^^^-----^^^^^----
122+
| | | |
123+
| | | `Test` is not local
124+
| | `Uto10` is not local
125+
LL | |
126+
... |
127+
LL | | }];
128+
| |_____- move this `impl` block outside of the current constant expression `<unnameable>` and up 2 bodies
146129
|
147130
= 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
148131
= 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-
| ^^^^^^^^^^^^^^^^^^^^^^
154132
= 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>
155133

156134
warning: 8 warnings emitted

0 commit comments

Comments
 (0)