Skip to content

Commit

Permalink
Use labels to indicate what may need to be moved
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed May 14, 2024
1 parent ed1ed42 commit 9a5bb1f
Show file tree
Hide file tree
Showing 12 changed files with 311 additions and 114 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ lint_non_local_definitions_deprecation = this lint may become deny-by-default in
lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
.help =
move this `impl` block and all the necessary types/traits outside the of the current {$body_kind_descr} {$depth ->
move this `impl` block and outside the of the current {$body_kind_descr} {$depth ->
[one] `{$body_name}`
*[other] `{$body_name}` and up {$depth} bodies
}
Expand All @@ -463,6 +463,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#
.non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
.exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module
lint_non_local_definitions_may_move = may need to be moved as well
lint_non_snake_case = {$sort} `{$name}` should have a snake case name
.rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
.cannot_convert_note = `{$sc}` cannot be used as a raw identifier
Expand Down
13 changes: 11 additions & 2 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::errors::RequestedLevel;
use crate::fluent_generated as fluent;
use rustc_errors::{
codes::*, Applicability, Diag, DiagMessage, DiagStyledString, EmissionGuarantee,
LintDiagnostic, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
LintDiagnostic, MultiSpan, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
};
use rustc_hir::def_id::DefId;
use rustc_macros::{LintDiagnostic, Subdiagnostic};
Expand Down Expand Up @@ -1341,6 +1341,8 @@ pub enum NonLocalDefinitionsDiag {
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
const_anon: Option<Option<Span>>,
move_help: Span,
self_ty: Span,
of_trait: Option<Span>,
has_trait: bool,
},
MacroRules {
Expand All @@ -1363,6 +1365,8 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
cargo_update,
const_anon,
move_help,
self_ty,
of_trait,
has_trait,
} => {
diag.arg("depth", depth);
Expand All @@ -1375,7 +1379,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
} else {
diag.note(fluent::lint_without_trait);
}
diag.span_help(move_help, fluent::lint_help);
let mut ms = MultiSpan::from_span(move_help);
ms.push_span_label(self_ty, fluent::lint_non_local_definitions_may_move);
if let Some(of_trait) = of_trait {
ms.push_span_label(of_trait, fluent::lint_non_local_definitions_may_move);
}
diag.span_help(ms, fluent::lint_help);

if let Some(cargo_update) = cargo_update {
diag.subdiagnostic(&diag.dcx, cargo_update);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/non_local_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
NonLocalDefinitionsDiag::Impl {
depth: self.body_depth,
move_help: item.span,
self_ty: impl_.self_ty.span,
of_trait: impl_.of_trait.map(|t| t.path.span),
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
body_name: parent_opt_item_name
.map(|s| s.to_ident_string())
Expand Down
5 changes: 4 additions & 1 deletion tests/ui/lint/non-local-defs/cargo-update.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ LL | non_local_macro::non_local_impl!(LocalStruct);
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current constant `_IMPL_DEBUG`
help: move this `impl` block and outside the of the current constant `_IMPL_DEBUG`
--> $DIR/cargo-update.rs:17:1
|
LL | non_local_macro::non_local_impl!(LocalStruct);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| may need to be moved as well
| may need to be moved as well
= 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`
= 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
= 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>
Expand Down
56 changes: 40 additions & 16 deletions tests/ui/lint/non-local-defs/consts.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ LL | impl Uto for &Test {}
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current constant `Z`
help: move this `impl` block and outside the of the current constant `Z`
--> $DIR/consts.rs:13:5
|
LL | impl Uto for &Test {}
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^---^^^^^-----^^^
| | |
| | may need to be moved as well
| may need to be moved as well
= 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
= 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>
= note: `#[warn(non_local_definitions)]` on by default
Expand All @@ -26,11 +29,14 @@ LL | impl Uto2 for Test {}
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current static `A`
help: move this `impl` block and outside the of the current static `A`
--> $DIR/consts.rs:24:5
|
LL | impl Uto2 for Test {}
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^----^^^^^----^^^
| | |
| | may need to be moved as well
| may need to be moved as well
= 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
= 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>

Expand All @@ -42,11 +48,14 @@ LL | impl Uto3 for Test {}
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current constant `B`
help: move this `impl` block and outside the of the current constant `B`
--> $DIR/consts.rs:32:5
|
LL | impl Uto3 for Test {}
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^----^^^^^----^^^
| | |
| | may need to be moved as well
| may need to be moved as well
= 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
= 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>

Expand All @@ -57,10 +66,13 @@ LL | impl Test {
| ^^^^^^^^^
|
= 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
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/consts.rs:43:5
|
LL | / impl Test {
LL | impl Test {
| ^ ---- may need to be moved as well
| _____|
| |
LL | |
LL | | fn foo() {}
LL | | }
Expand All @@ -74,10 +86,13 @@ LL | impl Test {
| ^^^^^^^^^
|
= 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
help: move this `impl` block and all the necessary types/traits outside the of the current inline constant `<unnameable>` and up 2 bodies
help: move this `impl` block and outside the of the current inline constant `<unnameable>` and up 2 bodies
--> $DIR/consts.rs:50:9
|
LL | / impl Test {
LL | impl Test {
| ^ ---- may need to be moved as well
| _________|
| |
LL | |
LL | | fn hoo() {}
LL | | }
Expand All @@ -91,10 +106,13 @@ LL | impl Test {
| ^^^^^^^^^
|
= 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
help: move this `impl` block and all the necessary types/traits outside the of the current constant `_` and up 2 bodies
help: move this `impl` block and outside the of the current constant `_` and up 2 bodies
--> $DIR/consts.rs:59:9
|
LL | / impl Test {
LL | impl Test {
| ^ ---- may need to be moved as well
| _________|
| |
LL | |
LL | | fn foo2() {}
LL | | }
Expand All @@ -110,11 +128,14 @@ LL | impl Uto9 for Test {}
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current closure `<unnameable>` and up 2 bodies
help: move this `impl` block and outside the of the current closure `<unnameable>` and up 2 bodies
--> $DIR/consts.rs:72:9
|
LL | impl Uto9 for Test {}
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^----^^^^^----^^^
| | |
| | may need to be moved as well
| may need to be moved as well
= 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>

warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
Expand All @@ -125,11 +146,14 @@ LL | impl Uto10 for Test {}
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current constant expression `<unnameable>` and up 2 bodies
help: move this `impl` block and outside the of the current constant expression `<unnameable>` and up 2 bodies
--> $DIR/consts.rs:79:9
|
LL | impl Uto10 for Test {}
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^-----^^^^^----^^^
| | |
| | may need to be moved as well
| may need to be moved as well
= 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>

warning: 8 warnings emitted
Expand Down
48 changes: 36 additions & 12 deletions tests/ui/lint/non-local-defs/exhaustive-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ LL | impl PartialEq<()> for Dog {
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/exhaustive-trait.rs:7:5
|
LL | / impl PartialEq<()> for Dog {
LL | impl PartialEq<()> for Dog {
| ^ ------------- --- may need to be moved as well
| | |
| _____| may need to be moved as well
| |
LL | |
LL | | fn eq(&self, _: &()) -> bool {
LL | | todo!()
Expand All @@ -27,10 +31,14 @@ LL | impl PartialEq<()> for &Dog {
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/exhaustive-trait.rs:14:5
|
LL | / impl PartialEq<()> for &Dog {
LL | impl PartialEq<()> for &Dog {
| ^ ------------- ---- may need to be moved as well
| | |
| _____| may need to be moved as well
| |
LL | |
LL | | fn eq(&self, _: &()) -> bool {
LL | | todo!()
Expand All @@ -47,10 +55,14 @@ LL | impl PartialEq<Dog> for () {
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/exhaustive-trait.rs:21:5
|
LL | / impl PartialEq<Dog> for () {
LL | impl PartialEq<Dog> for () {
| ^ -------------- -- may need to be moved as well
| | |
| _____| may need to be moved as well
| |
LL | |
LL | | fn eq(&self, _: &Dog) -> bool {
LL | | todo!()
Expand All @@ -67,10 +79,14 @@ LL | impl PartialEq<&Dog> for () {
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/exhaustive-trait.rs:28:5
|
LL | / impl PartialEq<&Dog> for () {
LL | impl PartialEq<&Dog> for () {
| ^ --------------- -- may need to be moved as well
| | |
| _____| may need to be moved as well
| |
LL | |
LL | | fn eq(&self, _: &&Dog) -> bool {
LL | | todo!()
Expand All @@ -87,10 +103,14 @@ LL | impl PartialEq<Dog> for &Dog {
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/exhaustive-trait.rs:35:5
|
LL | / impl PartialEq<Dog> for &Dog {
LL | impl PartialEq<Dog> for &Dog {
| ^ -------------- ---- may need to be moved as well
| | |
| _____| may need to be moved as well
| |
LL | |
LL | | fn eq(&self, _: &Dog) -> bool {
LL | | todo!()
Expand All @@ -107,10 +127,14 @@ LL | impl PartialEq<&Dog> for &Dog {
|
= 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
= 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`
help: move this `impl` block and all the necessary types/traits outside the of the current function `main`
help: move this `impl` block and outside the of the current function `main`
--> $DIR/exhaustive-trait.rs:42:5
|
LL | / impl PartialEq<&Dog> for &Dog {
LL | impl PartialEq<&Dog> for &Dog {
| ^ --------------- ---- may need to be moved as well
| | |
| _____| may need to be moved as well
| |
LL | |
LL | | fn eq(&self, _: &&Dog) -> bool {
LL | | todo!()
Expand Down
Loading

0 comments on commit 9a5bb1f

Please sign in to comment.