From 5ad4ad7aee5e0e63d8a2d95fd5dabf194e56836b Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Mon, 13 May 2024 19:35:52 +0200
Subject: [PATCH 01/11] non_local_defs: move out from
 `#[derive(LintDiagnostic)]` to manual impl

---
 compiler/rustc_lint/src/lints.rs         | 80 +++++++++++++++++++-----
 compiler/rustc_lint/src/non_local_def.rs |  1 -
 2 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 42963a11f71..deaf56c8f25 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1329,40 +1329,88 @@ pub struct SuspiciousDoubleRefCloneDiag<'a> {
 }
 
 // non_local_defs.rs
-#[derive(LintDiagnostic)]
 pub enum NonLocalDefinitionsDiag {
-    #[diag(lint_non_local_definitions_impl)]
-    #[help]
-    #[note(lint_non_local)]
-    #[note(lint_exception)]
-    #[note(lint_non_local_definitions_deprecation)]
     Impl {
         depth: u32,
         body_kind_descr: &'static str,
         body_name: String,
-        #[subdiagnostic]
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
-        #[suggestion(lint_const_anon, code = "_", applicability = "machine-applicable")]
         const_anon: Option<Span>,
     },
-    #[diag(lint_non_local_definitions_macro_rules)]
     MacroRules {
         depth: u32,
         body_kind_descr: &'static str,
         body_name: String,
-        #[help]
         help: Option<()>,
-        #[help(lint_help_doctest)]
         doctest_help: Option<()>,
-        #[note(lint_non_local)]
-        #[note(lint_exception)]
-        #[note(lint_non_local_definitions_deprecation)]
-        notes: (),
-        #[subdiagnostic]
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
     },
 }
 
+impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
+    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
+        match self {
+            NonLocalDefinitionsDiag::Impl {
+                depth,
+                body_kind_descr,
+                body_name,
+                cargo_update,
+                const_anon,
+            } => {
+                diag.primary_message(fluent::lint_non_local_definitions_impl);
+                diag.arg("depth", depth);
+                diag.arg("body_kind_descr", body_kind_descr);
+                diag.arg("body_name", body_name);
+
+                diag.help(fluent::lint_help);
+                diag.note(fluent::lint_non_local);
+                diag.note(fluent::lint_exception);
+                diag.note(fluent::lint_non_local_definitions_deprecation);
+
+                if let Some(cargo_update) = cargo_update {
+                    diag.subdiagnostic(&diag.dcx, cargo_update);
+                }
+                if let Some(const_anon) = const_anon {
+                    diag.span_suggestion(
+                        const_anon,
+                        fluent::lint_const_anon,
+                        "_",
+                        Applicability::MachineApplicable,
+                    );
+                }
+            }
+            NonLocalDefinitionsDiag::MacroRules {
+                depth,
+                body_kind_descr,
+                body_name,
+                help,
+                doctest_help,
+                cargo_update,
+            } => {
+                diag.primary_message(fluent::lint_non_local_definitions_macro_rules);
+                diag.arg("depth", depth);
+                diag.arg("body_kind_descr", body_kind_descr);
+                diag.arg("body_name", body_name);
+
+                if let Some(()) = help {
+                    diag.help(fluent::lint_help);
+                }
+                if let Some(()) = doctest_help {
+                    diag.help(fluent::lint_help_doctest);
+                }
+
+                diag.note(fluent::lint_non_local);
+                diag.note(fluent::lint_exception);
+                diag.note(fluent::lint_non_local_definitions_deprecation);
+
+                if let Some(cargo_update) = cargo_update {
+                    diag.subdiagnostic(&diag.dcx, cargo_update);
+                }
+            }
+        }
+    }
+}
+
 #[derive(Subdiagnostic)]
 #[note(lint_non_local_definitions_cargo_update)]
 pub struct NonLocalDefinitionsCargoUpdateNote {
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 87ee5f53628..f112048bb26 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -250,7 +250,6 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                         cargo_update: cargo_update(),
                         help: (!is_at_toplevel_doctest).then_some(()),
                         doctest_help: is_at_toplevel_doctest.then_some(()),
-                        notes: (),
                     },
                 )
             }

From 06c6a2d9d680c16399fa1e0fffa993ce60fd09f0 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Mon, 13 May 2024 19:58:40 +0200
Subject: [PATCH 02/11] non_local_defs: switch to more friendly primary message

---
 compiler/rustc_lint/messages.ftl              |  4 +-
 .../rustdoc-ui/doctest/non_local_defs.stderr  |  2 +-
 .../lint/non-local-defs/cargo-update.stderr   |  2 +-
 tests/ui/lint/non-local-defs/consts.stderr    | 16 ++++----
 .../non-local-defs/exhaustive-trait.stderr    | 12 +++---
 .../ui/lint/non-local-defs/exhaustive.stderr  | 40 +++++++++----------
 .../from-local-for-global.stderr              | 10 ++---
 tests/ui/lint/non-local-defs/generics.stderr  | 16 ++++----
 .../non-local-defs/inside-macro_rules.stderr  |  2 +-
 .../ui/lint/non-local-defs/macro_rules.stderr |  8 ++--
 .../trait-solver-overflow-123573.stderr       |  2 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr | 12 +++---
 tests/ui/proc-macro/nested-macro-rules.stderr |  2 +-
 13 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index a9304f27fe5..9d3ae7312ee 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -542,7 +542,7 @@ lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may
 
 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>
 
-lint_non_local_definitions_impl = non-local `impl` definition, they should be avoided as they go against expectation
+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 outside the of the current {$body_kind_descr} {$depth ->
             [one] `{$body_name}`
@@ -552,7 +552,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, they should be av
     .exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module and anon-const at the same nesting as the trait or type
     .const_anon = use a const-anon item to suppress this lint
 
-lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, they should be avoided as they go against expectation
+lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
     .help =
         remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->
             [one] `{$body_name}`
diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr
index 39a25de1aae..f8dffe10c11 100644
--- a/tests/rustdoc-ui/doctest/non_local_defs.stderr
+++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr
@@ -1,4 +1,4 @@
-warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   --> $DIR/non_local_defs.rs:9:1
    |
 LL | macro_rules! a_macro { () => {} }
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index e9e33b9aa17..640a462c2cf 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/cargo-update.rs:17:1
    |
 LL | non_local_macro::non_local_impl!(LocalStruct);
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index d15b452b004..ef86d735b7a 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:13:5
    |
 LL | const Z: () = {
@@ -13,7 +13,7 @@ LL |     impl Uto for &Test {}
    = 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
 
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:24:5
    |
 LL |     impl Uto2 for Test {}
@@ -24,7 +24,7 @@ LL |     impl Uto2 for Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:32:5
    |
 LL |     impl Uto3 for Test {}
@@ -35,7 +35,7 @@ LL |     impl Uto3 for Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:43:5
    |
 LL | /     impl Test {
@@ -49,7 +49,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:50:9
    |
 LL | /         impl Test {
@@ -63,7 +63,7 @@ LL | |         }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:59:9
    |
 LL | /         impl Test {
@@ -77,7 +77,7 @@ LL | |         }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:72:9
    |
 LL |         impl Uto9 for Test {}
@@ -88,7 +88,7 @@ LL |         impl Uto9 for Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:79:9
    |
 LL |         impl Uto10 for Test {}
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index 8d58d4dd27c..ea75dcf0c66 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:7:5
    |
 LL | /     impl PartialEq<()> for Dog {
@@ -15,7 +15,7 @@ LL | |     }
    = 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
 
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:14:5
    |
 LL | /     impl PartialEq<()> for &Dog {
@@ -31,7 +31,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:21:5
    |
 LL | /     impl PartialEq<Dog> for () {
@@ -47,7 +47,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:28:5
    |
 LL | /     impl PartialEq<&Dog> for () {
@@ -63,7 +63,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:35:5
    |
 LL | /     impl PartialEq<Dog> for &Dog {
@@ -79,7 +79,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:42:5
    |
 LL | /     impl PartialEq<&Dog> for &Dog {
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index b3697969c4f..c8f0bbf8c14 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:10:5
    |
 LL | /     impl Test {
@@ -13,7 +13,7 @@ LL | |     }
    = 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
 
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:15:5
    |
 LL | /     impl Display for Test {
@@ -29,7 +29,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:22:5
    |
 LL |     impl dyn Trait {}
@@ -40,7 +40,7 @@ LL |     impl dyn Trait {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:25:5
    |
 LL |     impl<T: Trait> Trait for Vec<T> { }
@@ -51,7 +51,7 @@ LL |     impl<T: Trait> Trait for Vec<T> { }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:28:5
    |
 LL |     impl Trait for &dyn Trait {}
@@ -62,7 +62,7 @@ LL |     impl Trait for &dyn Trait {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:31:5
    |
 LL |     impl Trait for *mut Test {}
@@ -73,7 +73,7 @@ LL |     impl Trait for *mut Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:34:5
    |
 LL |     impl Trait for *mut [Test] {}
@@ -84,7 +84,7 @@ LL |     impl Trait for *mut [Test] {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:37:5
    |
 LL |     impl Trait for [Test; 8] {}
@@ -95,7 +95,7 @@ LL |     impl Trait for [Test; 8] {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:40:5
    |
 LL |     impl Trait for (Test,) {}
@@ -106,7 +106,7 @@ LL |     impl Trait for (Test,) {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:43:5
    |
 LL |     impl Trait for fn(Test) -> () {}
@@ -117,7 +117,7 @@ LL |     impl Trait for fn(Test) -> () {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:46:5
    |
 LL |     impl Trait for fn() -> Test {}
@@ -128,7 +128,7 @@ LL |     impl Trait for fn() -> Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:50:9
    |
 LL |         impl Trait for Test {}
@@ -139,7 +139,7 @@ LL |         impl Trait for Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:58:5
    |
 LL |     impl Trait for *mut InsideMain {}
@@ -150,7 +150,7 @@ LL |     impl Trait for *mut InsideMain {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:60:5
    |
 LL |     impl Trait for *mut [InsideMain] {}
@@ -161,7 +161,7 @@ LL |     impl Trait for *mut [InsideMain] {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:62:5
    |
 LL |     impl Trait for [InsideMain; 8] {}
@@ -172,7 +172,7 @@ LL |     impl Trait for [InsideMain; 8] {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:64:5
    |
 LL |     impl Trait for (InsideMain,) {}
@@ -183,7 +183,7 @@ LL |     impl Trait for (InsideMain,) {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:66:5
    |
 LL |     impl Trait for fn(InsideMain) -> () {}
@@ -194,7 +194,7 @@ LL |     impl Trait for fn(InsideMain) -> () {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:68:5
    |
 LL |     impl Trait for fn() -> InsideMain {}
@@ -205,7 +205,7 @@ LL |     impl Trait for fn() -> InsideMain {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:72:9
    |
 LL | /         impl Display for InsideMain {
@@ -221,7 +221,7 @@ LL | |         }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:79:9
    |
 LL | /         impl InsideMain {
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index 0cd385049aa..05a8cc06609 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:8:5
    |
 LL | /     impl From<Cat> for () {
@@ -15,7 +15,7 @@ LL | |     }
    = 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
 
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:18:5
    |
 LL | /     impl From<Wrap<Wrap<Elephant>>> for () {
@@ -31,7 +31,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:32:5
    |
 LL |     impl StillNonLocal for &Foo {}
@@ -42,7 +42,7 @@ LL |     impl StillNonLocal for &Foo {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:40:5
    |
 LL | /     impl From<Local1> for GlobalSameFunction {
@@ -58,7 +58,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:48:5
    |
 LL | /     impl From<Local2> for GlobalSameFunction {
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index 681d9e45e7a..fd4b844a5bf 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:9:5
    |
 LL |     impl<T: Local> Global for Vec<T> { }
@@ -10,7 +10,7 @@ LL |     impl<T: Local> Global for Vec<T> { }
    = 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
 
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:20:5
    |
 LL |     impl Uto7 for Test where Local: std::any::Any {}
@@ -21,7 +21,7 @@ LL |     impl Uto7 for Test where Local: std::any::Any {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:23:5
    |
 LL |     impl<T> Uto8 for T {}
@@ -32,7 +32,7 @@ LL |     impl<T> Uto8 for T {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:32:5
    |
 LL | /     impl Default for UwU<OwO> {
@@ -48,7 +48,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:43:5
    |
 LL | /     impl AsRef<Cat> for () {
@@ -62,7 +62,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:54:5
    |
 LL | /     impl PartialEq<B> for G {
@@ -78,7 +78,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:69:5
    |
 LL | /     impl From<Wrap<Wrap<Lion>>> for () {
@@ -94,7 +94,7 @@ LL | |     }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:76:5
    |
 LL | /     impl From<()> for Wrap<Lion> {
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index 319682b973d..53177624663 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/inside-macro_rules.rs:9:13
    |
 LL |             impl MacroTrait for OutsideStruct {}
diff --git a/tests/ui/lint/non-local-defs/macro_rules.stderr b/tests/ui/lint/non-local-defs/macro_rules.stderr
index 125d8e97d87..57dbdef1ae3 100644
--- a/tests/ui/lint/non-local-defs/macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/macro_rules.stderr
@@ -1,4 +1,4 @@
-warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   --> $DIR/macro_rules.rs:10:5
    |
 LL |     macro_rules! m0 { () => { } };
@@ -10,7 +10,7 @@ LL |     macro_rules! m0 { () => { } };
    = 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
 
-warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   --> $DIR/macro_rules.rs:16:1
    |
 LL | non_local_macro::non_local_macro_rules!(my_macro);
@@ -23,7 +23,7 @@ LL | non_local_macro::non_local_macro_rules!(my_macro);
    = note: the macro `non_local_macro::non_local_macro_rules` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
    = note: this warning originates in the macro `non_local_macro::non_local_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   --> $DIR/macro_rules.rs:21:5
    |
 LL |     macro_rules! m { () => { } };
@@ -34,7 +34,7 @@ LL |     macro_rules! m { () => { } };
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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 `macro_rules!` definition, they should be avoided as they go against expectation
+warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   --> $DIR/macro_rules.rs:29:13
    |
 LL |             macro_rules! m2 { () => { } };
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index 9a8ab810835..3dfdca69138 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/trait-solver-overflow-123573.rs:12:5
    |
 LL |     impl Test for &Local {}
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index 015a0cce43b..e7ce780e51c 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -1,4 +1,4 @@
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:8:5
    |
 LL |     impl Uto for *mut Test {}
@@ -10,7 +10,7 @@ LL |     impl Uto for *mut Test {}
    = 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
 
-warning: non-local `impl` definition, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:16:9
    |
 LL |         impl Uto for Test {}
@@ -21,7 +21,7 @@ LL |         impl Uto for Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:25:9
    |
 LL | /         impl Test {
@@ -35,7 +35,7 @@ LL | |         }
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:34:9
    |
 LL |         impl Uto for &Test {}
@@ -46,7 +46,7 @@ LL |         impl Uto for &Test {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:41:9
    |
 LL |         impl Uto for &(Test,) {}
@@ -57,7 +57,7 @@ LL |         impl Uto for &(Test,) {}
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = 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, they should be avoided as they go against expectation
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:48:9
    |
 LL |         impl Uto for &(Test,Test) {}
diff --git a/tests/ui/proc-macro/nested-macro-rules.stderr b/tests/ui/proc-macro/nested-macro-rules.stderr
index 270e9161b03..7b5258a1574 100644
--- a/tests/ui/proc-macro/nested-macro-rules.stderr
+++ b/tests/ui/proc-macro/nested-macro-rules.stderr
@@ -1,4 +1,4 @@
-warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
   --> $DIR/auxiliary/nested-macro-rules.rs:7:9
    |
 LL |   macro_rules! outer_macro {

From de1c122950ac14801f5b1edf25f17e5297f797fd Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Mon, 13 May 2024 20:15:57 +0200
Subject: [PATCH 03/11] non_local_defs: improve some notes around trait,
 bounds, consts

 - Restrict const-anon exception diag to relevant places
 - Invoke bounds (and type-inference) in non_local_defs
 - Specialize diagnostic for impl without Trait
---
 compiler/rustc_lint/messages.ftl              |  6 +-
 compiler/rustc_lint/src/lints.rs              | 30 +++++---
 compiler/rustc_lint/src/non_local_def.rs      |  9 ++-
 .../lint/non-local-defs/cargo-update.stderr   |  7 +-
 tests/ui/lint/non-local-defs/consts.stderr    | 33 ++++----
 .../non-local-defs/exhaustive-trait.stderr    | 24 +++---
 .../ui/lint/non-local-defs/exhaustive.stderr  | 77 +++++++++----------
 .../from-local-for-global.stderr              | 20 ++---
 tests/ui/lint/non-local-defs/generics.stderr  | 32 ++++----
 .../non-local-defs/inside-macro_rules.stderr  |  4 +-
 .../trait-solver-overflow-123573.stderr       |  4 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr | 23 +++---
 12 files changed, 141 insertions(+), 128 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 9d3ae7312ee..52d8def425f 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -548,8 +548,10 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
             [one] `{$body_name}`
            *[other] `{$body_name}` and up {$depth} bodies
         }
-    .non_local = an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-    .exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module and anon-const at the same nesting as the trait or type
+    .without_trait = 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
+    .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`
+    .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
+    .exception = 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
     .const_anon = use a const-anon item to suppress this lint
 
 lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index deaf56c8f25..d3c409bb6e5 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1335,7 +1335,8 @@ pub enum NonLocalDefinitionsDiag {
         body_kind_descr: &'static str,
         body_name: String,
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
-        const_anon: Option<Span>,
+        const_anon: Option<Option<Span>>,
+        has_trait: bool,
     },
     MacroRules {
         depth: u32,
@@ -1356,6 +1357,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 body_name,
                 cargo_update,
                 const_anon,
+                has_trait,
             } => {
                 diag.primary_message(fluent::lint_non_local_definitions_impl);
                 diag.arg("depth", depth);
@@ -1363,21 +1365,29 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 diag.arg("body_name", body_name);
 
                 diag.help(fluent::lint_help);
-                diag.note(fluent::lint_non_local);
-                diag.note(fluent::lint_exception);
-                diag.note(fluent::lint_non_local_definitions_deprecation);
+                if has_trait {
+                    diag.note(fluent::lint_bounds);
+                    diag.note(fluent::lint_with_trait);
+                } else {
+                    diag.note(fluent::lint_without_trait);
+                }
 
                 if let Some(cargo_update) = cargo_update {
                     diag.subdiagnostic(&diag.dcx, cargo_update);
                 }
                 if let Some(const_anon) = const_anon {
-                    diag.span_suggestion(
-                        const_anon,
-                        fluent::lint_const_anon,
-                        "_",
-                        Applicability::MachineApplicable,
-                    );
+                    diag.note(fluent::lint_exception);
+                    if let Some(const_anon) = const_anon {
+                        diag.span_suggestion(
+                            const_anon,
+                            fluent::lint_const_anon,
+                            "_",
+                            Applicability::MachineApplicable,
+                        );
+                    }
                 }
+
+                diag.note(fluent::lint_non_local_definitions_deprecation);
             }
             NonLocalDefinitionsDiag::MacroRules {
                 depth,
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index f112048bb26..dc65db5e9ec 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -202,8 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 // Get the span of the parent const item ident (if it's a not a const anon).
                 //
                 // Used to suggest changing the const item to a const anon.
-                let span_for_const_anon_suggestion = if self.body_depth == 1
-                    && parent_def_kind == DefKind::Const
+                let span_for_const_anon_suggestion = if parent_def_kind == DefKind::Const
                     && parent_opt_item_name != Some(kw::Underscore)
                     && let Some(parent) = parent.as_local()
                     && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
@@ -215,6 +214,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     None
                 };
 
+                let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. })
+                    .then_some(span_for_const_anon_suggestion);
+
                 cx.emit_span_lint(
                     NON_LOCAL_DEFINITIONS,
                     item.span,
@@ -225,7 +227,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                             .map(|s| s.to_ident_string())
                             .unwrap_or_else(|| "<unnameable>".to_string()),
                         cargo_update: cargo_update(),
-                        const_anon: span_for_const_anon_suggestion,
+                        const_anon,
+                        has_trait: impl_.of_trait.is_some(),
                     },
                 )
             }
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index 640a462c2cf..af9ca5b0abd 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -5,10 +5,11 @@ LL | non_local_macro::non_local_impl!(LocalStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `_IMPL_DEBUG`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
-   = 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: `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`
    = 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>
    = note: `#[warn(non_local_definitions)]` on by default
    = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index ef86d735b7a..868b65457d1 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -8,8 +8,9 @@ LL |     impl Uto for &Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `Z`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
+   = 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
 
@@ -20,8 +21,9 @@ LL |     impl Uto2 for Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current static `A`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
+   = 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>
 
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -31,8 +33,9 @@ LL |     impl Uto3 for Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `B`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
+   = 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>
 
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -45,8 +48,7 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
    = 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
@@ -59,8 +61,7 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current inline constant `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
    = 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
@@ -73,8 +74,8 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current constant `_` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
+   = 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>
 
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
@@ -84,8 +85,8 @@ LL |         impl Uto9 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -95,8 +96,8 @@ LL |         impl Uto10 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index ea75dcf0c66..ca4eec5e5d0 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -10,8 +10,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
 
@@ -27,8 +27,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -43,8 +43,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -59,8 +59,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -75,8 +75,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -91,8 +91,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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: 6 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index c8f0bbf8c14..1fabf84dac6 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -8,8 +8,7 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
    = 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
 
@@ -25,8 +24,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -36,8 +35,7 @@ LL |     impl dyn Trait {}
    |     ^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
    = 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
@@ -47,8 +45,8 @@ LL |     impl<T: Trait> Trait for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -58,8 +56,8 @@ LL |     impl Trait for &dyn Trait {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -69,8 +67,8 @@ LL |     impl Trait for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -80,8 +78,8 @@ LL |     impl Trait for *mut [Test] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -91,8 +89,8 @@ LL |     impl Trait for [Test; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -102,8 +100,8 @@ LL |     impl Trait for (Test,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -113,8 +111,8 @@ LL |     impl Trait for fn(Test) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -124,8 +122,8 @@ LL |     impl Trait for fn() -> Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -135,8 +133,8 @@ LL |         impl Trait for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -146,8 +144,8 @@ LL |     impl Trait for *mut InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -157,8 +155,8 @@ LL |     impl Trait for *mut [InsideMain] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -168,8 +166,8 @@ LL |     impl Trait for [InsideMain; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -179,8 +177,8 @@ LL |     impl Trait for (InsideMain,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -190,8 +188,8 @@ LL |     impl Trait for fn(InsideMain) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -201,8 +199,8 @@ LL |     impl Trait for fn() -> InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -217,8 +215,8 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -231,8 +229,7 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
    = 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: 20 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index 05a8cc06609..b4ad3f3585c 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -10,8 +10,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
 
@@ -27,8 +27,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -38,8 +38,8 @@ LL |     impl StillNonLocal for &Foo {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `only_global`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -54,8 +54,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `same_function`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -70,8 +70,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `same_function`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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: 5 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index fd4b844a5bf..b62c25b828c 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -5,8 +5,8 @@ LL |     impl<T: Local> Global for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
 
@@ -17,8 +17,8 @@ LL |     impl Uto7 for Test where Local: std::any::Any {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `bad`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -28,8 +28,8 @@ LL |     impl<T> Uto8 for T {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `bad`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -44,8 +44,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `fun`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -58,8 +58,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `meow`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -74,8 +74,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `fun2`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -90,8 +90,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `rawr`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -106,8 +106,8 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `rawr`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index 53177624663..8c0a71a6765 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -8,8 +8,8 @@ LL | m!();
    | ---- in this macro invocation
    |
    = help: move this `impl` block outside the of the current function `my_func`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index 3dfdca69138..30e46555053 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -5,8 +5,8 @@ LL |     impl Test for &Local {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
 
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index e7ce780e51c..2e0e0695f59 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -5,8 +5,8 @@ LL |     impl Uto for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
 
@@ -17,8 +17,8 @@ LL |         impl Uto for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>`
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -31,8 +31,7 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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
    = 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
@@ -42,8 +41,8 @@ LL |         impl Uto for &Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -53,8 +52,8 @@ LL |         impl Uto for &(Test,) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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
@@ -64,8 +63,8 @@ LL |         impl Uto for &(Test,Test) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = 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`
    = 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: 6 warnings emitted

From 26b873d030f5f6bcc21ea1037c6d546f28f98e52 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Tue, 14 May 2024 12:54:26 +0200
Subject: [PATCH 04/11] non_local_defs: use span of the impl def and not the
 impl block

---
 compiler/rustc_lint/src/non_local_def.rs      |  2 +-
 tests/ui/lint/non-local-defs/consts.stderr    | 31 ++++-----
 .../non-local-defs/exhaustive-trait.stderr    | 54 ++++------------
 .../ui/lint/non-local-defs/exhaustive.stderr  | 64 +++++++------------
 .../from-local-for-global.stderr              | 38 +++--------
 tests/ui/lint/non-local-defs/generics.stderr  | 49 ++++----------
 .../non-local-defs/inside-macro_rules.stderr  |  2 +-
 .../trait-solver-overflow-123573.stderr       |  2 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr | 17 ++---
 9 files changed, 79 insertions(+), 180 deletions(-)

diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index dc65db5e9ec..d4d3afcce3b 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -219,7 +219,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
 
                 cx.emit_span_lint(
                     NON_LOCAL_DEFINITIONS,
-                    item.span,
+                    item.span.shrink_to_lo().to(impl_.self_ty.span),
                     NonLocalDefinitionsDiag::Impl {
                         depth: self.body_depth,
                         body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index 868b65457d1..e49256e7f35 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -5,7 +5,7 @@ LL | const Z: () = {
    |       - help: use a const-anon item to suppress this lint: `_`
 ...
 LL |     impl Uto for &Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `Z`
    = 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
@@ -18,7 +18,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:24:5
    |
 LL |     impl Uto2 for Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current static `A`
    = 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
@@ -30,7 +30,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:32:5
    |
 LL |     impl Uto3 for Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `B`
    = 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
@@ -41,11 +41,8 @@ LL |     impl Uto3 for Test {}
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:43:5
    |
-LL | /     impl Test {
-LL | |
-LL | |         fn foo() {}
-LL | |     }
-   | |_____^
+LL |     impl Test {
+   |     ^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -54,11 +51,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:50:9
    |
-LL | /         impl Test {
-LL | |
-LL | |             fn hoo() {}
-LL | |         }
-   | |_________^
+LL |         impl Test {
+   |         ^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current inline constant `<unnameable>` and up 2 bodies
    = 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
@@ -67,11 +61,8 @@ LL | |         }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:59:9
    |
-LL | /         impl Test {
-LL | |
-LL | |             fn foo2() {}
-LL | |         }
-   | |_________^
+LL |         impl Test {
+   |         ^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `_` and up 2 bodies
    = 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
@@ -82,7 +73,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:72:9
    |
 LL |         impl Uto9 for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
    = 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
@@ -93,7 +84,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:79:9
    |
 LL |         impl Uto10 for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index ca4eec5e5d0..63995715874 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -1,13 +1,8 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:7:5
    |
-LL | /     impl PartialEq<()> for Dog {
-LL | |
-LL | |         fn eq(&self, _: &()) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<()> for Dog {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -18,13 +13,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:14:5
    |
-LL | /     impl PartialEq<()> for &Dog {
-LL | |
-LL | |         fn eq(&self, _: &()) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<()> for &Dog {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -34,13 +24,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:21:5
    |
-LL | /     impl PartialEq<Dog> for () {
-LL | |
-LL | |         fn eq(&self, _: &Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<Dog> for () {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -50,13 +35,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:28:5
    |
-LL | /     impl PartialEq<&Dog> for () {
-LL | |
-LL | |         fn eq(&self, _: &&Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<&Dog> for () {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -66,13 +46,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:35:5
    |
-LL | /     impl PartialEq<Dog> for &Dog {
-LL | |
-LL | |         fn eq(&self, _: &Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<Dog> for &Dog {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -82,13 +57,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:42:5
    |
-LL | /     impl PartialEq<&Dog> for &Dog {
-LL | |
-LL | |         fn eq(&self, _: &&Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<&Dog> for &Dog {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index 1fabf84dac6..31783855470 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -1,11 +1,8 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:10:5
    |
-LL | /     impl Test {
-LL | |
-LL | |         fn foo() {}
-LL | |     }
-   | |_____^
+LL |     impl Test {
+   |     ^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -15,13 +12,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:15:5
    |
-LL | /     impl Display for Test {
-LL | |
-LL | |         fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl Display for Test {
+   |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -32,7 +24,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:22:5
    |
 LL |     impl dyn Trait {}
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -42,7 +34,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:25:5
    |
 LL |     impl<T: Trait> Trait for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -53,7 +45,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:28:5
    |
 LL |     impl Trait for &dyn Trait {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -64,7 +56,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:31:5
    |
 LL |     impl Trait for *mut Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -75,7 +67,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:34:5
    |
 LL |     impl Trait for *mut [Test] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -86,7 +78,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:37:5
    |
 LL |     impl Trait for [Test; 8] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -97,7 +89,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:40:5
    |
 LL |     impl Trait for (Test,) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -108,7 +100,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:43:5
    |
 LL |     impl Trait for fn(Test) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -119,7 +111,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:46:5
    |
 LL |     impl Trait for fn() -> Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -130,7 +122,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:50:9
    |
 LL |         impl Trait for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
    = 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
@@ -141,7 +133,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:58:5
    |
 LL |     impl Trait for *mut InsideMain {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -152,7 +144,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:60:5
    |
 LL |     impl Trait for *mut [InsideMain] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -163,7 +155,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:62:5
    |
 LL |     impl Trait for [InsideMain; 8] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -174,7 +166,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:64:5
    |
 LL |     impl Trait for (InsideMain,) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -185,7 +177,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:66:5
    |
 LL |     impl Trait for fn(InsideMain) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -196,7 +188,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:68:5
    |
 LL |     impl Trait for fn() -> InsideMain {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -206,13 +198,8 @@ LL |     impl Trait for fn() -> InsideMain {}
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:72:9
    |
-LL | /         impl Display for InsideMain {
-LL | |
-LL | |             fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-LL | |                 todo!()
-LL | |             }
-LL | |         }
-   | |_________^
+LL |         impl Display for InsideMain {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
    = 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
@@ -222,11 +209,8 @@ LL | |         }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:79:9
    |
-LL | /         impl InsideMain {
-LL | |
-LL | |             fn bar() {}
-LL | |         }
-   | |_________^
+LL |         impl InsideMain {
+   |         ^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
    = 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
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index b4ad3f3585c..e5e91e78746 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -1,13 +1,8 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:8:5
    |
-LL | /     impl From<Cat> for () {
-LL | |
-LL | |         fn from(_: Cat) -> () {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl From<Cat> for () {
+   |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -18,13 +13,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:18:5
    |
-LL | /     impl From<Wrap<Wrap<Elephant>>> for () {
-LL | |
-LL | |         fn from(_: Wrap<Wrap<Elephant>>) -> Self {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl From<Wrap<Wrap<Elephant>>> for () {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -35,7 +25,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:32:5
    |
 LL |     impl StillNonLocal for &Foo {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `only_global`
    = 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
@@ -45,13 +35,8 @@ LL |     impl StillNonLocal for &Foo {}
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:40:5
    |
-LL | /     impl From<Local1> for GlobalSameFunction {
-LL | |
-LL | |         fn from(x: Local1) -> GlobalSameFunction {
-LL | |             x.0
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl From<Local1> for GlobalSameFunction {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `same_function`
    = 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
@@ -61,13 +46,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:48:5
    |
-LL | /     impl From<Local2> for GlobalSameFunction {
-LL | |
-LL | |         fn from(x: Local2) -> GlobalSameFunction {
-LL | |             x.0
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl From<Local2> for GlobalSameFunction {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `same_function`
    = 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
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index b62c25b828c..26cdb0896b4 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -2,7 +2,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:9:5
    |
 LL |     impl<T: Local> Global for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
@@ -14,7 +14,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:20:5
    |
 LL |     impl Uto7 for Test where Local: std::any::Any {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `bad`
    = 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
@@ -25,7 +25,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:23:5
    |
 LL |     impl<T> Uto8 for T {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `bad`
    = 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
@@ -35,13 +35,8 @@ LL |     impl<T> Uto8 for T {}
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:32:5
    |
-LL | /     impl Default for UwU<OwO> {
-LL | |
-LL | |         fn default() -> Self {
-LL | |             UwU(OwO)
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl Default for UwU<OwO> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `fun`
    = 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
@@ -51,11 +46,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:43:5
    |
-LL | /     impl AsRef<Cat> for () {
-LL | |
-LL | |         fn as_ref(&self) -> &Cat { &Cat }
-LL | |     }
-   | |_____^
+LL |     impl AsRef<Cat> for () {
+   |     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `meow`
    = 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
@@ -65,13 +57,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:54:5
    |
-LL | /     impl PartialEq<B> for G {
-LL | |
-LL | |         fn eq(&self, _: &B) -> bool {
-LL | |             true
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl PartialEq<B> for G {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `fun2`
    = 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
@@ -81,13 +68,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:69:5
    |
-LL | /     impl From<Wrap<Wrap<Lion>>> for () {
-LL | |
-LL | |         fn from(_: Wrap<Wrap<Lion>>) -> Self {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl From<Wrap<Wrap<Lion>>> for () {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `rawr`
    = 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
@@ -97,13 +79,8 @@ LL | |     }
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/generics.rs:76:5
    |
-LL | /     impl From<()> for Wrap<Lion> {
-LL | |
-LL | |         fn from(_: ()) -> Self {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL |     impl From<()> for Wrap<Lion> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `rawr`
    = 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
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index 8c0a71a6765..cace400082a 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -2,7 +2,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/inside-macro_rules.rs:9:13
    |
 LL |             impl MacroTrait for OutsideStruct {}
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...
 LL | m!();
    | ---- in this macro invocation
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index 30e46555053..45bc86162eb 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -2,7 +2,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/trait-solver-overflow-123573.rs:12:5
    |
 LL |     impl Test for &Local {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
    = 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
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index 2e0e0695f59..af6df2165d1 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -2,7 +2,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:8:5
    |
 LL |     impl Uto for *mut Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>`
    = 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
@@ -14,7 +14,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:16:9
    |
 LL |         impl Uto for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>`
    = 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
@@ -24,11 +24,8 @@ LL |         impl Uto for Test {}
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:25:9
    |
-LL | /         impl Test {
-LL | |
-LL | |             fn bar() {}
-LL | |         }
-   | |_________^
+LL |         impl Test {
+   |         ^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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
@@ -38,7 +35,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:34:9
    |
 LL |         impl Uto for &Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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
@@ -49,7 +46,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:41:9
    |
 LL |         impl Uto for &(Test,) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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
@@ -60,7 +57,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:48:9
    |
 LL |         impl Uto for &(Test,Test) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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

From 22095fbd8d71d46231d0acc7217594ee2fff133b Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Tue, 14 May 2024 12:41:27 +0200
Subject: [PATCH 05/11] non_local_defs: use labels to indicate what may need to
 be moved

---
 compiler/rustc_lint/messages.ftl              |   4 +-
 compiler/rustc_lint/src/lints.rs              |  15 +-
 compiler/rustc_lint/src/non_local_def.rs      |   3 +
 .../lint/non-local-defs/cargo-update.stderr   |   9 +-
 tests/ui/lint/non-local-defs/consts.stderr    |  81 ++++++-
 .../non-local-defs/exhaustive-trait.stderr    |  90 +++++++-
 .../ui/lint/non-local-defs/exhaustive.stderr  | 197 ++++++++++++++++--
 .../from-local-for-global.stderr              |  69 +++++-
 tests/ui/lint/non-local-defs/generics.stderr  | 100 ++++++++-
 .../non-local-defs/inside-macro_rules.stderr  |  12 +-
 .../trait-solver-overflow-123573.stderr       |   9 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr |  57 ++++-
 12 files changed, 587 insertions(+), 59 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 52d8def425f..8582148e26c 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -544,7 +544,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 outside the of the current {$body_kind_descr} {$depth ->
+        move this `impl` block outside of the current {$body_kind_descr} {$depth ->
             [one] `{$body_name}`
            *[other] `{$body_name}` and up {$depth} bodies
         }
@@ -565,6 +565,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
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d3c409bb6e5..305cc67c1ee 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -6,7 +6,7 @@ use crate::errors::RequestedLevel;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
     codes::*, Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString,
-    ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, SubdiagMessageOp,
+    ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,
     Subdiagnostic, SuggestionStyle,
 };
 use rustc_hir::{def::Namespace, def_id::DefId};
@@ -1336,6 +1336,9 @@ pub enum NonLocalDefinitionsDiag {
         body_name: String,
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
         const_anon: Option<Option<Span>>,
+        move_help: Span,
+        self_ty: Span,
+        of_trait: Option<Span>,
         has_trait: bool,
     },
     MacroRules {
@@ -1357,6 +1360,9 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 body_name,
                 cargo_update,
                 const_anon,
+                move_help,
+                self_ty,
+                of_trait,
                 has_trait,
             } => {
                 diag.primary_message(fluent::lint_non_local_definitions_impl);
@@ -1364,13 +1370,18 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 diag.arg("body_kind_descr", body_kind_descr);
                 diag.arg("body_name", body_name);
 
-                diag.help(fluent::lint_help);
                 if has_trait {
                     diag.note(fluent::lint_bounds);
                     diag.note(fluent::lint_with_trait);
                 } else {
                     diag.note(fluent::lint_without_trait);
                 }
+                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);
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index d4d3afcce3b..6b75e546a66 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -222,6 +222,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     item.span.shrink_to_lo().to(impl_.self_ty.span),
                     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())
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index af9ca5b0abd..9c9f24cd2e9 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -4,9 +4,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL | non_local_macro::non_local_impl!(LocalStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant `_IMPL_DEBUG`
    = 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 outside 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>
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index e49256e7f35..7abf795079e 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -7,9 +7,16 @@ LL | const Z: () = {
 LL |     impl Uto for &Test {}
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant `Z`
    = 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 outside 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
@@ -20,9 +27,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Uto2 for Test {}
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current static `A`
    = 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 outside 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>
 
@@ -32,9 +46,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Uto3 for Test {}
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant `B`
    = 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 outside 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>
 
@@ -44,8 +65,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Test {
    |     ^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/consts.rs:43:5
+   |
+LL |       impl Test {
+   |       ^    ---- may need to be moved as well
+   |  _____|
+   | |
+LL | |
+LL | |         fn foo() {}
+LL | |     }
+   | |_____^
    = 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
@@ -54,8 +85,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Test {
    |         ^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current inline constant `<unnameable>` and up 2 bodies
    = 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 outside of the current inline constant `<unnameable>` and up 2 bodies
+  --> $DIR/consts.rs:50:9
+   |
+LL |           impl Test {
+   |           ^    ---- may need to be moved as well
+   |  _________|
+   | |
+LL | |
+LL | |             fn hoo() {}
+LL | |         }
+   | |_________^
    = 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
@@ -64,8 +105,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Test {
    |         ^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant `_` and up 2 bodies
    = 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 outside of the current constant `_` and up 2 bodies
+  --> $DIR/consts.rs:59:9
+   |
+LL |           impl Test {
+   |           ^    ---- may need to be moved as well
+   |  _________|
+   | |
+LL | |
+LL | |             fn foo2() {}
+LL | |         }
+   | |_________^
    = 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>
 
@@ -75,9 +126,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Uto9 for Test {}
    |         ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
    = 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 outside 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
@@ -86,9 +144,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Uto10 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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 outside 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
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index 63995715874..031927ba669 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -4,9 +4,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<()> for Dog {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive-trait.rs:7:5
+   |
+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!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
 
@@ -16,9 +29,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<()> for &Dog {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive-trait.rs:14:5
+   |
+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!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -27,9 +53,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<Dog> for () {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive-trait.rs:21:5
+   |
+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!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -38,9 +77,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<&Dog> for () {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive-trait.rs:28:5
+   |
+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!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -49,9 +101,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<Dog> for &Dog {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive-trait.rs:35:5
+   |
+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!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -60,9 +125,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<&Dog> for &Dog {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive-trait.rs:42:5
+   |
+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!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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: 6 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index 31783855470..91d4b2d4f65 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -4,8 +4,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Test {
    |     ^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:10:5
+   |
+LL |       impl Test {
+   |       ^    ---- may need to be moved as well
+   |  _____|
+   | |
+LL | |
+LL | |         fn foo() {}
+LL | |     }
+   | |_____^
    = 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
 
@@ -15,9 +25,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Display for Test {
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:15:5
+   |
+LL |       impl Display for Test {
+   |       ^    -------     ---- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -26,8 +49,14 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl dyn Trait {}
    |     ^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:22:5
+   |
+LL |     impl dyn Trait {}
+   |     ^^^^^---------^^^
+   |          |
+   |          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
@@ -36,9 +65,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl<T: Trait> Trait for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:25:5
+   |
+LL |     impl<T: Trait> Trait for Vec<T> { }
+   |     ^^^^^^^^^^^^^^^-----^^^^^------^^^^
+   |                    |         |
+   |                    |         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
@@ -47,9 +83,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for &dyn Trait {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:28:5
+   |
+LL |     impl Trait for &dyn Trait {}
+   |     ^^^^^-----^^^^^----------^^^
+   |          |         |
+   |          |         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
@@ -58,9 +101,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:31:5
+   |
+LL |     impl Trait for *mut 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
@@ -69,9 +119,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for *mut [Test] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:34:5
+   |
+LL |     impl Trait for *mut [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
@@ -80,9 +137,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for [Test; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:37:5
+   |
+LL |     impl Trait for [Test; 8] {}
+   |     ^^^^^-----^^^^^---------^^^
+   |          |         |
+   |          |         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
@@ -91,9 +155,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for (Test,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:40:5
+   |
+LL |     impl Trait 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
@@ -102,9 +173,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for fn(Test) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:43:5
+   |
+LL |     impl Trait for fn(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
@@ -113,9 +191,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for fn() -> Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:46:5
+   |
+LL |     impl Trait for fn() -> 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
@@ -124,9 +209,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Trait for Test {}
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
    = 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 outside of the current closure `<unnameable>` and up 2 bodies
+  --> $DIR/exhaustive.rs:50:9
+   |
+LL |         impl Trait 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
@@ -135,9 +227,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for *mut InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:58:5
+   |
+LL |     impl Trait for *mut InsideMain {}
+   |     ^^^^^-----^^^^^---------------^^^
+   |          |         |
+   |          |         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
@@ -146,9 +245,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for *mut [InsideMain] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:60:5
+   |
+LL |     impl Trait for *mut [InsideMain] {}
+   |     ^^^^^-----^^^^^-----------------^^^
+   |          |         |
+   |          |         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
@@ -157,9 +263,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for [InsideMain; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:62:5
+   |
+LL |     impl Trait for [InsideMain; 8] {}
+   |     ^^^^^-----^^^^^---------------^^^
+   |          |         |
+   |          |         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
@@ -168,9 +281,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for (InsideMain,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:64:5
+   |
+LL |     impl Trait for (InsideMain,) {}
+   |     ^^^^^-----^^^^^-------------^^^
+   |          |         |
+   |          |         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
@@ -179,9 +299,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for fn(InsideMain) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:66:5
+   |
+LL |     impl Trait for fn(InsideMain) -> () {}
+   |     ^^^^^-----^^^^^--------------------^^^
+   |          |         |
+   |          |         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
@@ -190,9 +317,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Trait for fn() -> InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/exhaustive.rs:68:5
+   |
+LL |     impl Trait for fn() -> InsideMain {}
+   |     ^^^^^-----^^^^^------------------^^^
+   |          |         |
+   |          |         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
@@ -201,9 +335,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Display for InsideMain {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
    = 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 outside of the current function `inside_inside` and up 2 bodies
+  --> $DIR/exhaustive.rs:72:9
+   |
+LL |           impl Display for InsideMain {
+   |           ^    -------     ---------- may need to be moved as well
+   |           |    |
+   |  _________|    may need to be moved as well
+   | |
+LL | |
+LL | |             fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+LL | |                 todo!()
+LL | |             }
+LL | |         }
+   | |_________^
    = 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
@@ -212,8 +359,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl InsideMain {
    |         ^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
    = 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 outside of the current function `inside_inside` and up 2 bodies
+  --> $DIR/exhaustive.rs:79:9
+   |
+LL |           impl InsideMain {
+   |           ^    ---------- may need to be moved as well
+   |  _________|
+   | |
+LL | |
+LL | |             fn bar() {}
+LL | |         }
+   | |_________^
    = 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: 20 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index e5e91e78746..de3fabc97f4 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -4,9 +4,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl From<Cat> for () {
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/from-local-for-global.rs:8:5
+   |
+LL |       impl From<Cat> for () {
+   |       ^    ---------     -- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn from(_: Cat) -> () {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
 
@@ -16,9 +29,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl From<Wrap<Wrap<Elephant>>> for () {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/from-local-for-global.rs:18:5
+   |
+LL |       impl From<Wrap<Wrap<Elephant>>> for () {
+   |       ^    --------------------------     -- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn from(_: Wrap<Wrap<Elephant>>) -> Self {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -27,9 +53,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl StillNonLocal for &Foo {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `only_global`
    = 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 outside of the current function `only_global`
+  --> $DIR/from-local-for-global.rs:32:5
+   |
+LL |     impl StillNonLocal for &Foo {}
+   |     ^^^^^-------------^^^^^----^^^
+   |          |                 |
+   |          |                 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
@@ -38,9 +71,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl From<Local1> for GlobalSameFunction {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `same_function`
    = 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 outside of the current function `same_function`
+  --> $DIR/from-local-for-global.rs:40:5
+   |
+LL |       impl From<Local1> for GlobalSameFunction {
+   |       ^    ------------     ------------------ may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn from(x: Local1) -> GlobalSameFunction {
+LL | |             x.0
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -49,9 +95,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl From<Local2> for GlobalSameFunction {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `same_function`
    = 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 outside of the current function `same_function`
+  --> $DIR/from-local-for-global.rs:48:5
+   |
+LL |       impl From<Local2> for GlobalSameFunction {
+   |       ^    ------------     ------------------ may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn from(x: Local2) -> GlobalSameFunction {
+LL | |             x.0
+LL | |         }
+LL | |     }
+   | |_____^
    = 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: 5 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index 26cdb0896b4..8ef6e3b71da 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -4,9 +4,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl<T: Local> Global for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/generics.rs:9:5
+   |
+LL |     impl<T: Local> Global for Vec<T> { }
+   |     ^^^^^^^^^^^^^^^------^^^^^------^^^^
+   |                    |          |
+   |                    |          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>
    = note: `#[warn(non_local_definitions)]` on by default
 
@@ -16,9 +23,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Uto7 for Test where Local: std::any::Any {}
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `bad`
    = 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 outside of the current function `bad`
+  --> $DIR/generics.rs:20:5
+   |
+LL |     impl Uto7 for Test where Local: std::any::Any {}
+   |     ^^^^^----^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |          |        |
+   |          |        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
@@ -27,9 +41,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl<T> Uto8 for T {}
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `bad`
    = 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 outside of the current function `bad`
+  --> $DIR/generics.rs:23:5
+   |
+LL |     impl<T> Uto8 for T {}
+   |     ^^^^^^^^----^^^^^-^^^
+   |             |        |
+   |             |        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
@@ -38,9 +59,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Default for UwU<OwO> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `fun`
    = 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 outside of the current function `fun`
+  --> $DIR/generics.rs:32:5
+   |
+LL |       impl Default for UwU<OwO> {
+   |       ^    -------     -------- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn default() -> Self {
+LL | |             UwU(OwO)
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -49,9 +83,20 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl AsRef<Cat> for () {
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `meow`
    = 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 outside of the current function `meow`
+  --> $DIR/generics.rs:43:5
+   |
+LL |       impl AsRef<Cat> for () {
+   |       ^    ----------     -- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn as_ref(&self) -> &Cat { &Cat }
+LL | |     }
+   | |_____^
    = 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
@@ -60,9 +105,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl PartialEq<B> for G {
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `fun2`
    = 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 outside of the current function `fun2`
+  --> $DIR/generics.rs:54:5
+   |
+LL |       impl PartialEq<B> for G {
+   |       ^    ------------     - may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn eq(&self, _: &B) -> bool {
+LL | |             true
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -71,9 +129,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl From<Wrap<Wrap<Lion>>> for () {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `rawr`
    = 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 outside of the current function `rawr`
+  --> $DIR/generics.rs:69:5
+   |
+LL |       impl From<Wrap<Wrap<Lion>>> for () {
+   |       ^    ----------------------     -- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn from(_: Wrap<Wrap<Lion>>) -> Self {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
@@ -82,9 +153,22 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl From<()> for Wrap<Lion> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `rawr`
    = 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 outside of the current function `rawr`
+  --> $DIR/generics.rs:76:5
+   |
+LL |       impl From<()> for Wrap<Lion> {
+   |       ^    --------     ---------- may need to be moved as well
+   |       |    |
+   |  _____|    may need to be moved as well
+   | |
+LL | |
+LL | |         fn from(_: ()) -> Self {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
    = 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
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index cace400082a..0325fd2bdc7 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -7,9 +7,19 @@ LL |             impl MacroTrait for OutsideStruct {}
 LL | m!();
    | ---- in this macro invocation
    |
-   = help: move this `impl` block outside the of the current function `my_func`
    = 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 outside of the current function `my_func`
+  --> $DIR/inside-macro_rules.rs:9:13
+   |
+LL |             impl MacroTrait for OutsideStruct {}
+   |             ^^^^^----------^^^^^-------------^^^
+   |                  |              |
+   |                  |              may need to be moved as well
+   |                  may need to be moved as well
+...
+LL | m!();
+   | ---- in this macro invocation
    = 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
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index 45bc86162eb..b52ea62230a 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -4,9 +4,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Test for &Local {}
    |     ^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current function `main`
    = 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 outside of the current function `main`
+  --> $DIR/trait-solver-overflow-123573.rs:12:5
+   |
+LL |     impl Test for &Local {}
+   |     ^^^^^----^^^^^------^^^
+   |          |        |
+   |          |        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>
    = note: `#[warn(non_local_definitions)]` on by default
 
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index af6df2165d1..d49e2b777dd 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -4,9 +4,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl Uto for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>`
    = 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 outside of the current constant expression `<unnameable>`
+  --> $DIR/weird-exprs.rs:8:5
+   |
+LL |     impl Uto for *mut 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>
    = note: `#[warn(non_local_definitions)]` on by default
 
@@ -16,9 +23,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Uto for Test {}
    |         ^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>`
    = 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 outside of the current constant expression `<unnameable>`
+  --> $DIR/weird-exprs.rs:16:9
+   |
+LL |         impl Uto 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
@@ -27,8 +41,18 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Test {
    |         ^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
+  --> $DIR/weird-exprs.rs:25:9
+   |
+LL |           impl Test {
+   |           ^    ---- may need to be moved as well
+   |  _________|
+   | |
+LL | |
+LL | |             fn bar() {}
+LL | |         }
+   | |_________^
    = 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
@@ -37,9 +61,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Uto for &Test {}
    |         ^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
+  --> $DIR/weird-exprs.rs:34:9
+   |
+LL |         impl Uto 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
@@ -48,9 +79,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Uto for &(Test,) {}
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
+  --> $DIR/weird-exprs.rs:41:9
+   |
+LL |         impl Uto 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
@@ -59,9 +97,16 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl Uto for &(Test,Test) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
+  --> $DIR/weird-exprs.rs:48:9
+   |
+LL |         impl Uto for &(Test,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: 6 warnings emitted

From 402580bcd5ade168a3a7edd0713821fa7d06dc2c Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Wed, 15 May 2024 07:54:37 +0200
Subject: [PATCH 06/11] non_local_defs: improve exception note for impl and
 macro_rules!

 - Remove wrong exception text for non-local macro_rules!
 - Simplify anonymous const exception note
---
 compiler/rustc_lint/messages.ftl                 | 3 +--
 compiler/rustc_lint/src/lints.rs                 | 1 -
 tests/rustdoc-ui/doctest/non_local_defs.stderr   | 1 -
 tests/ui/lint/non-local-defs/cargo-update.stderr | 2 +-
 tests/ui/lint/non-local-defs/consts.stderr       | 8 ++++----
 tests/ui/lint/non-local-defs/macro_rules.stderr  | 4 ----
 tests/ui/proc-macro/nested-macro-rules.stderr    | 1 -
 7 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 8582148e26c..13f6d116b81 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -551,7 +551,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
     .without_trait = 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
     .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`
     .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
-    .exception = 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
+    .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
     .const_anon = use a const-anon item to suppress this lint
 
 lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
@@ -563,7 +563,6 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#
     .help_doctest =
         remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
     .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
 
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 305cc67c1ee..800cd398adb 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1421,7 +1421,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 }
 
                 diag.note(fluent::lint_non_local);
-                diag.note(fluent::lint_exception);
                 diag.note(fluent::lint_non_local_definitions_deprecation);
 
                 if let Some(cargo_update) = cargo_update {
diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr
index f8dffe10c11..2b47e6b5bc4 100644
--- a/tests/rustdoc-ui/doctest/non_local_defs.stderr
+++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr
@@ -6,7 +6,6 @@ LL | macro_rules! a_macro { () => {} }
    |
    = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }`
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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
 
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index 9c9f24cd2e9..617a45aaec8 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -15,7 +15,7 @@ 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
    = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index 7abf795079e..c05c68d0b55 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -17,7 +17,7 @@ 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
 
@@ -37,7 +37,7 @@ 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
@@ -56,7 +56,7 @@ 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
@@ -117,7 +117,7 @@ LL | |
 LL | |             fn foo2() {}
 LL | |         }
    | |_________^
-   = 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
diff --git a/tests/ui/lint/non-local-defs/macro_rules.stderr b/tests/ui/lint/non-local-defs/macro_rules.stderr
index 57dbdef1ae3..4e86fc7b987 100644
--- a/tests/ui/lint/non-local-defs/macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/macro_rules.stderr
@@ -6,7 +6,6 @@ LL |     macro_rules! m0 { () => { } };
    |
    = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current constant `B`
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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
 
@@ -18,7 +17,6 @@ LL | non_local_macro::non_local_macro_rules!(my_macro);
    |
    = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current constant `_MACRO_EXPORT`
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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: the macro `non_local_macro::non_local_macro_rules` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
    = note: this warning originates in the macro `non_local_macro::non_local_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -31,7 +29,6 @@ LL |     macro_rules! m { () => { } };
    |
    = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current function `main`
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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 `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
@@ -42,7 +39,6 @@ LL |             macro_rules! m2 { () => { } };
    |
    = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current associated function `bar` and up 2 bodies
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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: 4 warnings emitted
diff --git a/tests/ui/proc-macro/nested-macro-rules.stderr b/tests/ui/proc-macro/nested-macro-rules.stderr
index 7b5258a1574..8fe041d61b8 100644
--- a/tests/ui/proc-macro/nested-macro-rules.stderr
+++ b/tests/ui/proc-macro/nested-macro-rules.stderr
@@ -19,7 +19,6 @@ LL |       nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
    |
    = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current function `main`
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = 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: the lint level is defined here
   --> $DIR/nested-macro-rules.rs:8:9

From d3dfe14b53e2211138e3a4eae5915351ff62f5bc Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Wed, 15 May 2024 14:08:28 +0200
Subject: [PATCH 07/11] non_local_defs: be more precise about what needs to be
 moved

---
 compiler/rustc_lint/src/lints.rs              |  12 +-
 compiler/rustc_lint/src/non_local_def.rs      |  40 ++++++-
 .../lint/non-local-defs/cargo-update.stderr   |   3 -
 tests/ui/lint/non-local-defs/consts.stderr    |  40 ++-----
 .../non-local-defs/exhaustive-trait.stderr    |  36 +-----
 .../ui/lint/non-local-defs/exhaustive.stderr  | 113 +++++-------------
 .../from-local-for-global.stderr              |  28 ++---
 tests/ui/lint/non-local-defs/generics.stderr  |  44 +++----
 .../non-local-defs/inside-macro_rules.stderr  |   5 +-
 .../non-local-defs/suggest-moving-inner.rs    |  17 +++
 .../suggest-moving-inner.stderr               |  28 +++++
 .../trait-solver-overflow-123573.stderr       |   7 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr |  30 +----
 13 files changed, 171 insertions(+), 232 deletions(-)
 create mode 100644 tests/ui/lint/non-local-defs/suggest-moving-inner.rs
 create mode 100644 tests/ui/lint/non-local-defs/suggest-moving-inner.stderr

diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 800cd398adb..ad6e7b958c7 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1337,8 +1337,7 @@ pub enum NonLocalDefinitionsDiag {
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
         const_anon: Option<Option<Span>>,
         move_help: Span,
-        self_ty: Span,
-        of_trait: Option<Span>,
+        may_move: Vec<Span>,
         has_trait: bool,
     },
     MacroRules {
@@ -1361,8 +1360,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 cargo_update,
                 const_anon,
                 move_help,
-                self_ty,
-                of_trait,
+                may_move,
                 has_trait,
             } => {
                 diag.primary_message(fluent::lint_non_local_definitions_impl);
@@ -1376,10 +1374,10 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 } else {
                     diag.note(fluent::lint_without_trait);
                 }
+
                 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);
+                for sp in may_move {
+                    ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
                 }
                 diag.span_help(ms, fluent::lint_help);
 
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 6b75e546a66..0805c2e2766 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -1,3 +1,5 @@
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::HirId;
 use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, TyKind};
 use rustc_hir::{Path, QPath};
 use rustc_infer::infer::InferCtxt;
@@ -214,6 +216,29 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     None
                 };
 
+                let mut collector = PathCollector { paths: Vec::new() };
+                collector.visit_ty(&impl_.self_ty);
+                if let Some(of_trait) = &impl_.of_trait {
+                    collector.visit_trait_ref(of_trait);
+                }
+                collector.visit_generics(&impl_.generics);
+
+                let may_move: Vec<Span> = collector
+                    .paths
+                    .into_iter()
+                    .filter_map(|path| {
+                        if path_has_local_parent(&path, cx, parent, parent_parent) {
+                            if let Some(args) = &path.segments.last().unwrap().args {
+                                Some(path.span.until(args.span_ext))
+                            } else {
+                                Some(path.span)
+                            }
+                        } else {
+                            None
+                        }
+                    })
+                    .collect();
+
                 let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. })
                     .then_some(span_for_const_anon_suggestion);
 
@@ -223,14 +248,13 @@ 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())
                             .unwrap_or_else(|| "<unnameable>".to_string()),
                         cargo_update: cargo_update(),
                         const_anon,
+                        may_move,
                         has_trait: impl_.of_trait.is_some(),
                     },
                 )
@@ -348,6 +372,18 @@ impl<'a, 'tcx, F: FnMut(DefId) -> bool> TypeFolder<TyCtxt<'tcx>>
     }
 }
 
+/// Simple hir::Path collector
+struct PathCollector<'tcx> {
+    paths: Vec<Path<'tcx>>,
+}
+
+impl<'tcx> Visitor<'tcx> for PathCollector<'tcx> {
+    fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
+        self.paths.push(path.clone()); // need to clone, bc of the restricted lifetime
+        intravisit::walk_path(self, path)
+    }
+}
+
 /// Given a path and a parent impl def id, this checks if the if parent resolution
 /// def id correspond to the def id of the parent impl definition.
 ///
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index 617a45aaec8..30696b0f8e5 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -11,9 +11,6 @@ help: move this `impl` block outside of the current constant `_IMPL_DEBUG`
    |
 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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 --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index c05c68d0b55..820e3a2d6e0 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -13,10 +13,7 @@ help: move this `impl` block outside 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
@@ -33,10 +30,7 @@ help: move this `impl` block outside 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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>
 
@@ -52,10 +46,7 @@ help: move this `impl` block outside 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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>
 
@@ -69,10 +60,7 @@ LL |     impl Test {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/consts.rs:43:5
    |
-LL |       impl Test {
-   |       ^    ---- may need to be moved as well
-   |  _____|
-   | |
+LL | /     impl Test {
 LL | |
 LL | |         fn foo() {}
 LL | |     }
@@ -89,10 +77,7 @@ LL |         impl Test {
 help: move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
   --> $DIR/consts.rs:50:9
    |
-LL |           impl Test {
-   |           ^    ---- may need to be moved as well
-   |  _________|
-   | |
+LL | /         impl Test {
 LL | |
 LL | |             fn hoo() {}
 LL | |         }
@@ -109,10 +94,7 @@ LL |         impl Test {
 help: move this `impl` block outside of the current constant `_` and up 2 bodies
   --> $DIR/consts.rs:59:9
    |
-LL |           impl Test {
-   |           ^    ---- may need to be moved as well
-   |  _________|
-   | |
+LL | /         impl Test {
 LL | |
 LL | |             fn foo2() {}
 LL | |         }
@@ -132,10 +114,7 @@ help: move this `impl` block outside of the current closure `<unnameable>` and u
   --> $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
@@ -150,10 +129,7 @@ help: move this `impl` block outside of the current constant expression `<unname
   --> $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
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index 031927ba669..a9e3624fde5 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -9,11 +9,7 @@ LL |     impl PartialEq<()> for Dog {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive-trait.rs:7:5
    |
-LL |       impl PartialEq<()> for Dog {
-   |       ^    -------------     --- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl PartialEq<()> for Dog {
 LL | |
 LL | |         fn eq(&self, _: &()) -> bool {
 LL | |             todo!()
@@ -34,11 +30,7 @@ LL |     impl PartialEq<()> for &Dog {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive-trait.rs:14:5
    |
-LL |       impl PartialEq<()> for &Dog {
-   |       ^    -------------     ---- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl PartialEq<()> for &Dog {
 LL | |
 LL | |         fn eq(&self, _: &()) -> bool {
 LL | |             todo!()
@@ -58,11 +50,7 @@ LL |     impl PartialEq<Dog> for () {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive-trait.rs:21:5
    |
-LL |       impl PartialEq<Dog> for () {
-   |       ^    --------------     -- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl PartialEq<Dog> for () {
 LL | |
 LL | |         fn eq(&self, _: &Dog) -> bool {
 LL | |             todo!()
@@ -82,11 +70,7 @@ LL |     impl PartialEq<&Dog> for () {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive-trait.rs:28:5
    |
-LL |       impl PartialEq<&Dog> for () {
-   |       ^    ---------------     -- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl PartialEq<&Dog> for () {
 LL | |
 LL | |         fn eq(&self, _: &&Dog) -> bool {
 LL | |             todo!()
@@ -106,11 +90,7 @@ LL |     impl PartialEq<Dog> for &Dog {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive-trait.rs:35:5
    |
-LL |       impl PartialEq<Dog> for &Dog {
-   |       ^    --------------     ---- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl PartialEq<Dog> for &Dog {
 LL | |
 LL | |         fn eq(&self, _: &Dog) -> bool {
 LL | |             todo!()
@@ -130,11 +110,7 @@ LL |     impl PartialEq<&Dog> for &Dog {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive-trait.rs:42:5
    |
-LL |       impl PartialEq<&Dog> for &Dog {
-   |       ^    ---------------     ---- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl PartialEq<&Dog> for &Dog {
 LL | |
 LL | |         fn eq(&self, _: &&Dog) -> bool {
 LL | |             todo!()
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index 91d4b2d4f65..c6b8dc26e31 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -8,10 +8,7 @@ LL |     impl Test {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:10:5
    |
-LL |       impl Test {
-   |       ^    ---- may need to be moved as well
-   |  _____|
-   | |
+LL | /     impl Test {
 LL | |
 LL | |         fn foo() {}
 LL | |     }
@@ -30,11 +27,7 @@ LL |     impl Display for Test {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:15:5
    |
-LL |       impl Display for Test {
-   |       ^    -------     ---- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl Display for Test {
 LL | |
 LL | |         fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 LL | |             todo!()
@@ -54,9 +47,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:22:5
    |
 LL |     impl dyn Trait {}
-   |     ^^^^^---------^^^
-   |          |
-   |          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
@@ -71,10 +62,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:25:5
    |
 LL |     impl<T: Trait> Trait for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^-----^^^^^------^^^^
-   |                    |         |
-   |                    |         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
@@ -89,10 +77,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:28:5
    |
 LL |     impl Trait for &dyn Trait {}
-   |     ^^^^^-----^^^^^----------^^^
-   |          |         |
-   |          |         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
@@ -107,10 +92,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:31:5
    |
 LL |     impl Trait for *mut 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
@@ -125,10 +107,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:34:5
    |
 LL |     impl Trait for *mut [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
@@ -143,10 +122,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:37:5
    |
 LL |     impl Trait for [Test; 8] {}
-   |     ^^^^^-----^^^^^---------^^^
-   |          |         |
-   |          |         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
@@ -161,10 +137,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:40:5
    |
 LL |     impl Trait 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
@@ -179,10 +152,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:43:5
    |
 LL |     impl Trait for fn(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
@@ -197,10 +167,7 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:46:5
    |
 LL |     impl Trait for fn() -> 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
@@ -215,10 +182,7 @@ help: move this `impl` block outside of the current closure `<unnameable>` and u
   --> $DIR/exhaustive.rs:50:9
    |
 LL |         impl Trait 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
@@ -233,10 +197,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:58:5
    |
 LL |     impl Trait for *mut InsideMain {}
-   |     ^^^^^-----^^^^^---------------^^^
-   |          |         |
-   |          |         may need to be moved as well
-   |          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
@@ -251,10 +214,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:60:5
    |
 LL |     impl Trait for *mut [InsideMain] {}
-   |     ^^^^^-----^^^^^-----------------^^^
-   |          |         |
-   |          |         may need to be moved as well
-   |          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
@@ -269,10 +231,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:62:5
    |
 LL |     impl Trait for [InsideMain; 8] {}
-   |     ^^^^^-----^^^^^---------------^^^
-   |          |         |
-   |          |         may need to be moved as well
-   |          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
@@ -287,10 +248,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:64:5
    |
 LL |     impl Trait for (InsideMain,) {}
-   |     ^^^^^-----^^^^^-------------^^^
-   |          |         |
-   |          |         may need to be moved as well
-   |          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
@@ -305,10 +265,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:66:5
    |
 LL |     impl Trait for fn(InsideMain) -> () {}
-   |     ^^^^^-----^^^^^--------------------^^^
-   |          |         |
-   |          |         may need to be moved as well
-   |          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
@@ -323,10 +282,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:68:5
    |
 LL |     impl Trait for fn() -> InsideMain {}
-   |     ^^^^^-----^^^^^------------------^^^
-   |          |         |
-   |          |         may need to be moved as well
-   |          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
@@ -340,11 +298,7 @@ LL |         impl Display for InsideMain {
 help: move this `impl` block outside of the current function `inside_inside` and up 2 bodies
   --> $DIR/exhaustive.rs:72:9
    |
-LL |           impl Display for InsideMain {
-   |           ^    -------     ---------- may need to be moved as well
-   |           |    |
-   |  _________|    may need to be moved as well
-   | |
+LL | /         impl Display for InsideMain {
 LL | |
 LL | |             fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 LL | |                 todo!()
@@ -363,10 +317,7 @@ LL |         impl InsideMain {
 help: move this `impl` block outside of the current function `inside_inside` and up 2 bodies
   --> $DIR/exhaustive.rs:79:9
    |
-LL |           impl InsideMain {
-   |           ^    ---------- may need to be moved as well
-   |  _________|
-   | |
+LL | /         impl InsideMain {
 LL | |
 LL | |             fn bar() {}
 LL | |         }
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index de3fabc97f4..27ffe35532a 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -9,11 +9,7 @@ LL |     impl From<Cat> for () {
 help: move this `impl` block outside of the current function `main`
   --> $DIR/from-local-for-global.rs:8:5
    |
-LL |       impl From<Cat> for () {
-   |       ^    ---------     -- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
-   | |
+LL | /     impl From<Cat> for () {
 LL | |
 LL | |         fn from(_: Cat) -> () {
 LL | |             todo!()
@@ -35,9 +31,8 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/from-local-for-global.rs:18:5
    |
 LL |       impl From<Wrap<Wrap<Elephant>>> for () {
-   |       ^    --------------------------     -- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^                   -------- may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn from(_: Wrap<Wrap<Elephant>>) -> Self {
@@ -59,10 +54,9 @@ help: move this `impl` block outside of the current function `only_global`
   --> $DIR/from-local-for-global.rs:32:5
    |
 LL |     impl StillNonLocal for &Foo {}
-   |     ^^^^^-------------^^^^^----^^^
-   |          |                 |
-   |          |                 may need to be moved as well
-   |          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
@@ -77,9 +71,8 @@ help: move this `impl` block outside of the current function `same_function`
   --> $DIR/from-local-for-global.rs:40:5
    |
 LL |       impl From<Local1> for GlobalSameFunction {
-   |       ^    ------------     ------------------ may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^         ------ may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn from(x: Local1) -> GlobalSameFunction {
@@ -101,9 +94,8 @@ help: move this `impl` block outside of the current function `same_function`
   --> $DIR/from-local-for-global.rs:48:5
    |
 LL |       impl From<Local2> for GlobalSameFunction {
-   |       ^    ------------     ------------------ may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^         ------ may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn from(x: Local2) -> GlobalSameFunction {
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index 8ef6e3b71da..1adefd40ffb 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -10,10 +10,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/generics.rs:9:5
    |
 LL |     impl<T: Local> Global for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^------^^^^^------^^^^
-   |                    |          |
-   |                    |          may need to be moved as well
-   |                    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>
    = note: `#[warn(non_local_definitions)]` on by default
 
@@ -29,10 +28,9 @@ help: move this `impl` block outside of the current function `bad`
   --> $DIR/generics.rs:20:5
    |
 LL |     impl Uto7 for Test where Local: std::any::Any {}
-   |     ^^^^^----^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |          |        |
-   |          |        may need to be moved as well
-   |          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
@@ -47,10 +45,7 @@ help: move this `impl` block outside of the current function `bad`
   --> $DIR/generics.rs:23:5
    |
 LL |     impl<T> Uto8 for T {}
-   |     ^^^^^^^^----^^^^^-^^^
-   |             |        |
-   |             |        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
@@ -65,9 +60,8 @@ help: move this `impl` block outside of the current function `fun`
   --> $DIR/generics.rs:32:5
    |
 LL |       impl Default for UwU<OwO> {
-   |       ^    -------     -------- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^                    --- may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn default() -> Self {
@@ -89,9 +83,8 @@ help: move this `impl` block outside of the current function `meow`
   --> $DIR/generics.rs:43:5
    |
 LL |       impl AsRef<Cat> for () {
-   |       ^    ----------     -- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^          --- may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn as_ref(&self) -> &Cat { &Cat }
@@ -111,9 +104,8 @@ help: move this `impl` block outside of the current function `fun2`
   --> $DIR/generics.rs:54:5
    |
 LL |       impl PartialEq<B> for G {
-   |       ^    ------------     - may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^              - may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn eq(&self, _: &B) -> bool {
@@ -135,9 +127,8 @@ help: move this `impl` block outside of the current function `rawr`
   --> $DIR/generics.rs:69:5
    |
 LL |       impl From<Wrap<Wrap<Lion>>> for () {
-   |       ^    ----------------------     -- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^                   ---- may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn from(_: Wrap<Wrap<Lion>>) -> Self {
@@ -159,9 +150,8 @@ help: move this `impl` block outside of the current function `rawr`
   --> $DIR/generics.rs:76:5
    |
 LL |       impl From<()> for Wrap<Lion> {
-   |       ^    --------     ---------- may need to be moved as well
-   |       |    |
-   |  _____|    may need to be moved as well
+   |       ^                      ---- may need to be moved as well
+   |  _____|
    | |
 LL | |
 LL | |         fn from(_: ()) -> Self {
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index 0325fd2bdc7..fea211a4e50 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -13,10 +13,7 @@ help: move this `impl` block outside of the current function `my_func`
   --> $DIR/inside-macro_rules.rs:9:13
    |
 LL |             impl MacroTrait for OutsideStruct {}
-   |             ^^^^^----------^^^^^-------------^^^
-   |                  |              |
-   |                  |              may need to be moved as well
-   |                  may need to be moved as well
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...
 LL | m!();
    | ---- in this macro invocation
diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs
new file mode 100644
index 00000000000..61b32e5bad9
--- /dev/null
+++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs
@@ -0,0 +1,17 @@
+//@ check-pass
+
+trait Trait<T> {}
+
+fn main() {
+    mod below {
+        pub struct Type<T>(T);
+    }
+    struct InsideMain;
+    trait HasFoo {}
+
+    impl<T> Trait<InsideMain> for &Vec<below::Type<(InsideMain, T)>>
+    //~^ WARN non-local `impl` definition
+    where
+        T: HasFoo
+    {}
+}
diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
new file mode 100644
index 00000000000..83557a7b9a2
--- /dev/null
+++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
@@ -0,0 +1,28 @@
+warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
+  --> $DIR/suggest-moving-inner.rs:12:5
+   |
+LL |     impl<T> Trait<InsideMain> for &Vec<below::Type<(InsideMain, T)>>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 outside of the current function `main`
+  --> $DIR/suggest-moving-inner.rs:12:5
+   |
+LL |       impl<T> Trait<InsideMain> for &Vec<below::Type<(InsideMain, T)>>
+   |       ^             ----------           -----------  ---------- may need to be moved as well
+   |       |             |                    |
+   |       |             |                    may need to be moved as well
+   |  _____|             may need to be moved as well
+   | |
+LL | |
+LL | |     where
+LL | |         T: HasFoo
+   | |            ------ may need to be moved as well
+LL | |     {}
+   | |______^
+   = 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
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index b52ea62230a..252296099f6 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -10,10 +10,9 @@ help: move this `impl` block outside of the current function `main`
   --> $DIR/trait-solver-overflow-123573.rs:12:5
    |
 LL |     impl Test for &Local {}
-   |     ^^^^^----^^^^^------^^^
-   |          |        |
-   |          |        may need to be moved as well
-   |          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>
    = note: `#[warn(non_local_definitions)]` on by default
 
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index d49e2b777dd..e8cd4ffef09 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -10,10 +10,7 @@ help: move this `impl` block outside of the current constant expression `<unname
   --> $DIR/weird-exprs.rs:8:5
    |
 LL |     impl Uto for *mut 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>
    = note: `#[warn(non_local_definitions)]` on by default
 
@@ -29,10 +26,7 @@ help: move this `impl` block outside of the current constant expression `<unname
   --> $DIR/weird-exprs.rs:16:9
    |
 LL |         impl Uto 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
@@ -45,10 +39,7 @@ LL |         impl Test {
 help: move this `impl` block outside of the current constant expression `<unnameable>` and up 2 bodies
   --> $DIR/weird-exprs.rs:25:9
    |
-LL |           impl Test {
-   |           ^    ---- may need to be moved as well
-   |  _________|
-   | |
+LL | /         impl Test {
 LL | |
 LL | |             fn bar() {}
 LL | |         }
@@ -67,10 +58,7 @@ help: move this `impl` block outside of the current constant expression `<unname
   --> $DIR/weird-exprs.rs:34:9
    |
 LL |         impl Uto 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
@@ -85,10 +73,7 @@ help: move this `impl` block outside of the current constant expression `<unname
   --> $DIR/weird-exprs.rs:41:9
    |
 LL |         impl Uto 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
@@ -103,10 +88,7 @@ help: move this `impl` block outside of the current constant expression `<unname
   --> $DIR/weird-exprs.rs:48:9
    |
 LL |         impl Uto for &(Test,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: 6 warnings emitted

From ab23fd8dea02b9e525771ed8ec6cca1ff6d414e4 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Wed, 15 May 2024 14:17:30 +0200
Subject: [PATCH 08/11] non_local_defs: improve main without a trait note

---
 compiler/rustc_lint/messages.ftl                | 2 +-
 tests/ui/lint/non-local-defs/consts.stderr      | 6 +++---
 tests/ui/lint/non-local-defs/exhaustive.stderr  | 6 +++---
 tests/ui/lint/non-local-defs/weird-exprs.stderr | 2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 13f6d116b81..f1273b8bf4b 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -548,7 +548,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
             [one] `{$body_name}`
            *[other] `{$body_name}` and up {$depth} bodies
         }
-    .without_trait = 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
+    .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`
     .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`
     .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
     .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index 820e3a2d6e0..0528f63ac9c 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -56,7 +56,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 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
+   = 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`
 help: move this `impl` block outside of the current function `main`
   --> $DIR/consts.rs:43:5
    |
@@ -73,7 +73,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 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
+   = 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`
 help: move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
   --> $DIR/consts.rs:50:9
    |
@@ -90,7 +90,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 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
+   = 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`
 help: move this `impl` block outside of the current constant `_` and up 2 bodies
   --> $DIR/consts.rs:59:9
    |
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index c6b8dc26e31..29f5f14ef0d 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -4,7 +4,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 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
+   = 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`
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:10:5
    |
@@ -42,7 +42,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |     impl dyn Trait {}
    |     ^^^^^^^^^^^^^^
    |
-   = 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
+   = 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`
 help: move this `impl` block outside of the current function `main`
   --> $DIR/exhaustive.rs:22:5
    |
@@ -313,7 +313,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 LL |         impl InsideMain {
    |         ^^^^^^^^^^^^^^^
    |
-   = 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
+   = 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`
 help: move this `impl` block outside of the current function `inside_inside` and up 2 bodies
   --> $DIR/exhaustive.rs:79:9
    |
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index e8cd4ffef09..cced1171903 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -35,7 +35,7 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
 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
+   = 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`
 help: move this `impl` block outside of the current constant expression `<unnameable>` and up 2 bodies
   --> $DIR/weird-exprs.rs:25:9
    |

From b71952904df8b48eb78ba54a1706680c722cb2cb Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Wed, 15 May 2024 14:55:40 +0200
Subject: [PATCH 09/11] non_local_defs: suggest removing leading ref/ptr to
 make the impl local

---
 compiler/rustc_lint/messages.ftl              |  3 +-
 compiler/rustc_lint/src/lints.rs              | 14 +++-
 compiler/rustc_lint/src/non_local_def.rs      | 80 ++++++++++++-------
 .../ui/lint/non-local-defs/exhaustive.stderr  |  4 +-
 .../from-local-for-global.stderr              |  4 +-
 .../trait-solver-overflow-123573.stderr       |  4 +-
 6 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index f1273b8bf4b..f93534c316f 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -543,11 +543,12 @@ lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may
 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>
 
 lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
-    .help =
+    .move_help =
         move this `impl` block outside of the current {$body_kind_descr} {$depth ->
             [one] `{$body_name}`
            *[other] `{$body_name}` and up {$depth} bodies
         }
+    .remove_help = remove `{$may_remove_part}` to make the `impl` local
     .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`
     .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`
     .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
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index ad6e7b958c7..ca980d33e8e 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1338,6 +1338,7 @@ pub enum NonLocalDefinitionsDiag {
         const_anon: Option<Option<Span>>,
         move_help: Span,
         may_move: Vec<Span>,
+        may_remove: Option<(Span, String)>,
         has_trait: bool,
     },
     MacroRules {
@@ -1361,6 +1362,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 const_anon,
                 move_help,
                 may_move,
+                may_remove,
                 has_trait,
             } => {
                 diag.primary_message(fluent::lint_non_local_definitions_impl);
@@ -1379,7 +1381,17 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 for sp in may_move {
                     ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
                 }
-                diag.span_help(ms, fluent::lint_help);
+                diag.span_help(ms, fluent::lint_move_help);
+
+                if let Some((span, part)) = may_remove {
+                    diag.arg("may_remove_part", part);
+                    diag.span_suggestion(
+                        span,
+                        fluent::lint_remove_help,
+                        "",
+                        Applicability::MaybeIncorrect,
+                    );
+                }
 
                 if let Some(cargo_update) = cargo_update {
                     diag.subdiagnostic(&diag.dcx, cargo_update);
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 0805c2e2766..ed932e1c235 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -136,35 +136,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 };
 
                 // Part 1: Is the Self type local?
-                let self_ty_has_local_parent = match impl_.self_ty.kind {
-                    TyKind::Path(QPath::Resolved(_, ty_path)) => {
-                        path_has_local_parent(ty_path, cx, parent, parent_parent)
-                    }
-                    TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
-                        path_has_local_parent(
-                            principle_poly_trait_ref.trait_ref.path,
-                            cx,
-                            parent,
-                            parent_parent,
-                        )
-                    }
-                    TyKind::TraitObject([], _, _)
-                    | TyKind::InferDelegation(_, _)
-                    | TyKind::Slice(_)
-                    | TyKind::Array(_, _)
-                    | TyKind::Ptr(_)
-                    | TyKind::Ref(_, _)
-                    | TyKind::BareFn(_)
-                    | TyKind::Never
-                    | TyKind::Tup(_)
-                    | TyKind::Path(_)
-                    | TyKind::Pat(..)
-                    | TyKind::AnonAdt(_)
-                    | TyKind::OpaqueDef(_, _, _)
-                    | TyKind::Typeof(_)
-                    | TyKind::Infer
-                    | TyKind::Err(_) => false,
-                };
+                let self_ty_has_local_parent =
+                    ty_has_local_parent(&impl_.self_ty.kind, cx, parent, parent_parent);
 
                 if self_ty_has_local_parent {
                     return;
@@ -242,6 +215,18 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. })
                     .then_some(span_for_const_anon_suggestion);
 
+                let may_remove = match &impl_.self_ty.kind {
+                    TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty)
+                        if ty_has_local_parent(&mut_ty.ty.kind, cx, parent, parent_parent) =>
+                    {
+                        let type_ =
+                            if matches!(impl_.self_ty.kind, TyKind::Ptr(_)) { "*" } else { "&" };
+                        let part = format!("{}{}", type_, mut_ty.mutbl.prefix_str());
+                        Some((impl_.self_ty.span.shrink_to_lo().until(mut_ty.ty.span), part))
+                    }
+                    _ => None,
+                };
+
                 cx.emit_span_lint(
                     NON_LOCAL_DEFINITIONS,
                     item.span.shrink_to_lo().to(impl_.self_ty.span),
@@ -255,6 +240,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                         cargo_update: cargo_update(),
                         const_anon,
                         may_move,
+                        may_remove,
                         has_trait: impl_.of_trait.is_some(),
                     },
                 )
@@ -384,6 +370,42 @@ impl<'tcx> Visitor<'tcx> for PathCollector<'tcx> {
     }
 }
 
+/// Given a `Ty` we check if the (outermost) type is local.
+fn ty_has_local_parent(
+    ty_kind: &TyKind<'_>,
+    cx: &LateContext<'_>,
+    impl_parent: DefId,
+    impl_parent_parent: Option<DefId>,
+) -> bool {
+    match ty_kind {
+        TyKind::Path(QPath::Resolved(_, ty_path)) => {
+            path_has_local_parent(ty_path, cx, impl_parent, impl_parent_parent)
+        }
+        TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => path_has_local_parent(
+            principle_poly_trait_ref.trait_ref.path,
+            cx,
+            impl_parent,
+            impl_parent_parent,
+        ),
+        TyKind::TraitObject([], _, _)
+        | TyKind::InferDelegation(_, _)
+        | TyKind::Slice(_)
+        | TyKind::Array(_, _)
+        | TyKind::Ptr(_)
+        | TyKind::Ref(_, _)
+        | TyKind::BareFn(_)
+        | TyKind::Never
+        | TyKind::Tup(_)
+        | TyKind::Path(_)
+        | TyKind::Pat(..)
+        | TyKind::AnonAdt(_)
+        | TyKind::OpaqueDef(_, _, _)
+        | TyKind::Typeof(_)
+        | TyKind::Infer
+        | TyKind::Err(_) => false,
+    }
+}
+
 /// Given a path and a parent impl def id, this checks if the if parent resolution
 /// def id correspond to the def id of the parent impl definition.
 ///
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index 29f5f14ef0d..7316182a4df 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -189,7 +189,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:58:5
    |
 LL |     impl Trait for *mut InsideMain {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^-----^^^^^^^^^^
+   |                    |
+   |                    help: remove `*mut ` to make the `impl` local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index 27ffe35532a..683f80acbac 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -46,7 +46,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:32:5
    |
 LL |     impl StillNonLocal for &Foo {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^-^^^
+   |                            |
+   |                            help: remove `&` to make the `impl` local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index 252296099f6..de4eacbecca 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -2,7 +2,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/trait-solver-overflow-123573.rs:12:5
    |
 LL |     impl Test for &Local {}
-   |     ^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^-^^^^^
+   |                   |
+   |                   help: remove `&` to make the `impl` local
    |
    = 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`

From 98273ec61272644b8bc14f2039f5c00cfa5dab95 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Wed, 15 May 2024 19:13:02 +0200
Subject: [PATCH 10/11] non_local_defs: point to Self and Trait to give more
 context

---
 Cargo.lock                                    |   1 +
 compiler/rustc_lint/Cargo.toml                |   1 +
 compiler/rustc_lint/messages.ftl              |   4 +
 compiler/rustc_lint/src/lints.rs              |   8 ++
 compiler/rustc_lint/src/non_local_def.rs      |  83 +++++++++++++--
 .../lint/non-local-defs/cargo-update.stderr   |   3 +
 tests/ui/lint/non-local-defs/consts.stderr    |  37 +++++--
 .../non-local-defs/exhaustive-trait.stderr    |  30 ++++--
 .../ui/lint/non-local-defs/exhaustive.stderr  | 100 ++++++++++++++----
 .../from-local-for-global.stderr              |  27 +++--
 tests/ui/lint/non-local-defs/generics.stderr  |  39 +++++--
 .../non-local-defs/inside-macro_rules.stderr  |   5 +-
 .../suggest-moving-inner.stderr               |   5 +-
 .../trait-solver-overflow-123573.stderr       |   8 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr |  29 +++--
 15 files changed, 311 insertions(+), 69 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 5e8d179e536..2f2b6e34474 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4062,6 +4062,7 @@ dependencies = [
  "rustc_feature",
  "rustc_fluent_macro",
  "rustc_hir",
+ "rustc_hir_pretty",
  "rustc_index",
  "rustc_infer",
  "rustc_macros",
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
index fa1133e7780..232d4c18fa4 100644
--- a/compiler/rustc_lint/Cargo.toml
+++ b/compiler/rustc_lint/Cargo.toml
@@ -13,6 +13,7 @@ rustc_errors = { path = "../rustc_errors" }
 rustc_feature = { path = "../rustc_feature" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
+rustc_hir_pretty = { path = "../rustc_hir_pretty" }
 rustc_index = { path = "../rustc_index" }
 rustc_infer = { path = "../rustc_infer" }
 rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index f93534c316f..8d1f7e150bc 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -567,6 +567,10 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#
 
 lint_non_local_definitions_may_move = may need to be moved as well
 
+lint_non_local_definitions_of_trait_not_local = `{$of_trait_str}` is not local
+
+lint_non_local_definitions_self_ty_not_local = `{$self_ty_str}` is not local
+
 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
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index ca980d33e8e..8c8ab4e0f37 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1340,6 +1340,8 @@ pub enum NonLocalDefinitionsDiag {
         may_move: Vec<Span>,
         may_remove: Option<(Span, String)>,
         has_trait: bool,
+        self_ty_str: String,
+        of_trait_str: Option<String>,
     },
     MacroRules {
         depth: u32,
@@ -1364,11 +1366,17 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 may_move,
                 may_remove,
                 has_trait,
+                self_ty_str,
+                of_trait_str,
             } => {
                 diag.primary_message(fluent::lint_non_local_definitions_impl);
                 diag.arg("depth", depth);
                 diag.arg("body_kind_descr", body_kind_descr);
                 diag.arg("body_name", body_name);
+                diag.arg("self_ty_str", self_ty_str);
+                if let Some(of_trait_str) = of_trait_str {
+                    diag.arg("of_trait_str", of_trait_str);
+                }
 
                 if has_trait {
                     diag.note(fluent::lint_bounds);
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index ed932e1c235..d88c774ed80 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -1,3 +1,4 @@
+use rustc_errors::MultiSpan;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
 use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, TyKind};
@@ -9,12 +10,13 @@ use rustc_middle::ty::{EarlyBinder, TraitRef, TypeSuperFoldable};
 use rustc_session::{declare_lint, impl_lint_pass};
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::Span;
-use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
+use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind, Symbol};
 use rustc_trait_selection::infer::TyCtxtInferExt;
 use rustc_trait_selection::traits::error_reporting::ambiguity::{
     compute_applicable_impls_for_diagnostics, CandidateSource,
 };
 
+use crate::fluent_generated as fluent;
 use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
 use crate::{LateContext, LateLintPass, LintContext};
 
@@ -201,11 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     .into_iter()
                     .filter_map(|path| {
                         if path_has_local_parent(&path, cx, parent, parent_parent) {
-                            if let Some(args) = &path.segments.last().unwrap().args {
-                                Some(path.span.until(args.span_ext))
-                            } else {
-                                Some(path.span)
-                            }
+                            Some(path_span_without_args(&path))
                         } else {
                             None
                         }
@@ -227,9 +225,29 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     _ => None,
                 };
 
+                let impl_span = item.span.shrink_to_lo().to(impl_.self_ty.span);
+                let mut ms = MultiSpan::from_span(impl_span);
+
+                let (self_ty_span, self_ty_str) =
+                    self_ty_kind_for_diagnostic(&impl_.self_ty, cx.tcx);
+
+                ms.push_span_label(
+                    self_ty_span,
+                    fluent::lint_non_local_definitions_self_ty_not_local,
+                );
+                let of_trait_str = if let Some(of_trait) = &impl_.of_trait {
+                    ms.push_span_label(
+                        path_span_without_args(&of_trait.path),
+                        fluent::lint_non_local_definitions_of_trait_not_local,
+                    );
+                    Some(path_name_to_string(&of_trait.path))
+                } else {
+                    None
+                };
+
                 cx.emit_span_lint(
                     NON_LOCAL_DEFINITIONS,
-                    item.span.shrink_to_lo().to(impl_.self_ty.span),
+                    ms,
                     NonLocalDefinitionsDiag::Impl {
                         depth: self.body_depth,
                         move_help: item.span,
@@ -239,6 +257,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                             .unwrap_or_else(|| "<unnameable>".to_string()),
                         cargo_update: cargo_update(),
                         const_anon,
+                        self_ty_str,
+                        of_trait_str,
                         may_move,
                         may_remove,
                         has_trait: impl_.of_trait.is_some(),
@@ -447,3 +467,52 @@ fn did_has_local_parent(
             false
         }
 }
+
+/// Return for a given `Path` the span until the last args
+fn path_span_without_args(path: &Path<'_>) -> Span {
+    if let Some(args) = &path.segments.last().unwrap().args {
+        path.span.until(args.span_ext)
+    } else {
+        path.span
+    }
+}
+
+/// Return a "error message-able" ident for the last segment of the `Path`
+fn path_name_to_string(path: &Path<'_>) -> String {
+    path.segments.last().unwrap().ident.name.to_ident_string()
+}
+
+/// Compute the `Span` and visual representation for the `Self` we want to point at;
+/// It follows part of the actual logic of non-local, and if possible return the least
+/// amount possible for the span and representation.
+fn self_ty_kind_for_diagnostic(ty: &rustc_hir::Ty<'_>, tcx: TyCtxt<'_>) -> (Span, String) {
+    match ty.kind {
+        TyKind::Path(QPath::Resolved(_, ty_path)) => (
+            path_span_without_args(ty_path),
+            ty_path
+                .res
+                .opt_def_id()
+                .map(|did| tcx.opt_item_name(did))
+                .flatten()
+                .as_ref()
+                .map(|s| Symbol::as_str(s))
+                .unwrap_or("<unnameable>")
+                .to_string(),
+        ),
+        TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
+            let path = &principle_poly_trait_ref.trait_ref.path;
+            (
+                path_span_without_args(path),
+                path.res
+                    .opt_def_id()
+                    .map(|did| tcx.opt_item_name(did))
+                    .flatten()
+                    .as_ref()
+                    .map(|s| Symbol::as_str(s))
+                    .unwrap_or("<unnameable>")
+                    .to_string(),
+            )
+        }
+        _ => (ty.span, rustc_hir_pretty::ty_to_string(&tcx, ty)),
+    }
+}
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index 30696b0f8e5..091c6f3d564 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -3,6 +3,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
    |
 LL | non_local_macro::non_local_impl!(LocalStruct);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | `LocalStruct` is not local
+   | `Debug` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index 0528f63ac9c..bf2b1541b2d 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -5,7 +5,10 @@ LL | const Z: () = {
    |       - help: use a const-anon item to suppress this lint: `_`
 ...
 LL |     impl Uto for &Test {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---^^^^^-----
+   |          |       |
+   |          |       `&'_ Test` is not local
+   |          `Uto` is not local
    |
    = 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`
@@ -22,7 +25,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:24:5
    |
 LL |     impl Uto2 for Test {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^----
+   |          |        |
+   |          |        `Test` is not local
+   |          `Uto2` is not local
    |
    = 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`
@@ -38,7 +44,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:32:5
    |
 LL |     impl Uto3 for Test {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^----
+   |          |        |
+   |          |        `Test` is not local
+   |          `Uto3` is not local
    |
    = 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`
@@ -54,7 +63,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:43:5
    |
 LL |     impl Test {
-   |     ^^^^^^^^^
+   |     ^^^^^----
+   |          |
+   |          `Test` is not local
    |
    = 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`
 help: move this `impl` block outside of the current function `main`
@@ -71,7 +82,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:50:9
    |
 LL |         impl Test {
-   |         ^^^^^^^^^
+   |         ^^^^^----
+   |              |
+   |              `Test` is not local
    |
    = 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`
 help: move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
@@ -88,7 +101,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:59:9
    |
 LL |         impl Test {
-   |         ^^^^^^^^^
+   |         ^^^^^----
+   |              |
+   |              `Test` is not local
    |
    = 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`
 help: move this `impl` block outside of the current constant `_` and up 2 bodies
@@ -106,7 +121,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:72:9
    |
 LL |         impl Uto9 for Test {}
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^^^^----^^^^^----
+   |              |        |
+   |              |        `Test` is not local
+   |              `Uto9` is not local
    |
    = 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`
@@ -121,7 +139,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:79:9
    |
 LL |         impl Uto10 for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^-----^^^^^----
+   |              |         |
+   |              |         `Test` is not local
+   |              `Uto10` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index a9e3624fde5..8164a16b4d1 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive-trait.rs:7:5
    |
 LL |     impl PartialEq<()> for Dog {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^^---
+   |          |                 |
+   |          |                 `Dog` is not local
+   |          `PartialEq` is not local
    |
    = 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`
@@ -23,7 +26,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive-trait.rs:14:5
    |
 LL |     impl PartialEq<()> for &Dog {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^^----
+   |          |                 |
+   |          |                 `&'_ Dog` is not local
+   |          `PartialEq` is not local
    |
    = 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`
@@ -43,7 +49,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive-trait.rs:21:5
    |
 LL |     impl PartialEq<Dog> for () {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^^^--
+   |          |                  |
+   |          |                  `()` is not local
+   |          `PartialEq` is not local
    |
    = 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`
@@ -63,7 +72,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive-trait.rs:28:5
    |
 LL |     impl PartialEq<&Dog> for () {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^^^^--
+   |          |                   |
+   |          |                   `()` is not local
+   |          `PartialEq` is not local
    |
    = 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`
@@ -83,7 +95,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive-trait.rs:35:5
    |
 LL |     impl PartialEq<Dog> for &Dog {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^^^----
+   |          |                  |
+   |          |                  `&'_ Dog` is not local
+   |          `PartialEq` is not local
    |
    = 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`
@@ -103,7 +118,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive-trait.rs:42:5
    |
 LL |     impl PartialEq<&Dog> for &Dog {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^^^^----
+   |          |                   |
+   |          |                   `&'_ Dog` is not local
+   |          `PartialEq` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index 7316182a4df..d6d269674bd 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -2,7 +2,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:10:5
    |
 LL |     impl Test {
-   |     ^^^^^^^^^
+   |     ^^^^^----
+   |          |
+   |          `Test` is not local
    |
    = 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`
 help: move this `impl` block outside of the current function `main`
@@ -20,7 +22,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:15:5
    |
 LL |     impl Display for Test {
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-------^^^^^----
+   |          |           |
+   |          |           `Test` is not local
+   |          `Display` is not local
    |
    = 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`
@@ -40,7 +45,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:22:5
    |
 LL |     impl dyn Trait {}
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^-----
+   |              |
+   |              `Trait` is not local
    |
    = 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`
 help: move this `impl` block outside of the current function `main`
@@ -54,7 +61,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:25:5
    |
 LL |     impl<T: Trait> Trait for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^-----^^^^^---^^^
+   |                    |         |
+   |                    |         `Vec` is not local
+   |                    `Trait` is not local
    |
    = 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`
@@ -69,7 +79,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:28:5
    |
 LL |     impl Trait for &dyn Trait {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^----------
+   |          |         |
+   |          |         `&'_ dyn Trait` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -84,7 +97,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:31:5
    |
 LL |     impl Trait for *mut Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^---------
+   |          |         |
+   |          |         `*mut Test` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -99,7 +115,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:34:5
    |
 LL |     impl Trait for *mut [Test] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^-----------
+   |          |         |
+   |          |         `*mut [Test]` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -114,7 +133,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:37:5
    |
 LL |     impl Trait for [Test; 8] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^---------
+   |          |         |
+   |          |         `[Test; 8]` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -129,7 +151,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:40:5
    |
 LL |     impl Trait for (Test,) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^-------
+   |          |         |
+   |          |         `(Test,)` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -144,7 +169,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:43:5
    |
 LL |     impl Trait for fn(Test) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^--------------
+   |          |         |
+   |          |         `fn(: Test) -> ()` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -159,7 +187,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:46:5
    |
 LL |     impl Trait for fn() -> Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^------------
+   |          |         |
+   |          |         `fn() -> Test` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -174,7 +205,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:50:9
    |
 LL |         impl Trait for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^-----^^^^^----
+   |              |         |
+   |              |         `Test` is not local
+   |              `Trait` is not local
    |
    = 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`
@@ -189,9 +223,11 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:58:5
    |
 LL |     impl Trait for *mut InsideMain {}
-   |     ^^^^^^^^^^^^^^^-----^^^^^^^^^^
-   |                    |
-   |                    help: remove `*mut ` to make the `impl` local
+   |     ^^^^^-----^^^^^---------------
+   |          |         |
+   |          |         `*mut InsideMain` is not local
+   |          |         help: remove `*mut ` to make the `impl` local
+   |          `Trait` is not local
    |
    = 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`
@@ -208,7 +244,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:60:5
    |
 LL |     impl Trait for *mut [InsideMain] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^-----------------
+   |          |         |
+   |          |         `*mut [InsideMain]` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -225,7 +264,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:62:5
    |
 LL |     impl Trait for [InsideMain; 8] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^---------------
+   |          |         |
+   |          |         `[InsideMain; 8]` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -242,7 +284,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:64:5
    |
 LL |     impl Trait for (InsideMain,) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^-------------
+   |          |         |
+   |          |         `(InsideMain,)` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -259,7 +304,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:66:5
    |
 LL |     impl Trait for fn(InsideMain) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^--------------------
+   |          |         |
+   |          |         `fn(: InsideMain) -> ()` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -276,7 +324,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:68:5
    |
 LL |     impl Trait for fn() -> InsideMain {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^------------------
+   |          |         |
+   |          |         `fn() -> InsideMain` is not local
+   |          `Trait` is not local
    |
    = 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`
@@ -293,7 +344,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:72:9
    |
 LL |         impl Display for InsideMain {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^-------^^^^^----------
+   |              |           |
+   |              |           `InsideMain` is not local
+   |              `Display` is not local
    |
    = 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`
@@ -313,7 +367,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/exhaustive.rs:79:9
    |
 LL |         impl InsideMain {
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^----------
+   |              |
+   |              `InsideMain` is not local
    |
    = 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`
 help: move this `impl` block outside of the current function `inside_inside` and up 2 bodies
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index 683f80acbac..1c1dcb65abc 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:8:5
    |
 LL |     impl From<Cat> for () {
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^^^^^^--
+   |          |             |
+   |          |             `()` is not local
+   |          `From` is not local
    |
    = 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`
@@ -23,7 +26,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:18:5
    |
 LL |     impl From<Wrap<Wrap<Elephant>>> for () {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^--
+   |          |                              |
+   |          `From` is not local            `()` is not local
    |
    = 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`
@@ -46,9 +51,11 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:32:5
    |
 LL |     impl StillNonLocal for &Foo {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^-^^^
-   |                            |
-   |                            help: remove `&` to make the `impl` local
+   |     ^^^^^-------------^^^^^----
+   |          |                 |
+   |          |                 `&'_ Foo` is not local
+   |          |                 help: remove `&` to make the `impl` local
+   |          `StillNonLocal` is not local
    |
    = 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`
@@ -65,7 +72,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:40:5
    |
 LL |     impl From<Local1> for GlobalSameFunction {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^^^^^^^^^------------------
+   |          |                |
+   |          |                `GlobalSameFunction` is not local
+   |          `From` is not local
    |
    = 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`
@@ -88,7 +98,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/from-local-for-global.rs:48:5
    |
 LL |     impl From<Local2> for GlobalSameFunction {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^^^^^^^^^------------------
+   |          |                |
+   |          |                `GlobalSameFunction` is not local
+   |          `From` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index 1adefd40ffb..7d64d9b1b09 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:9:5
    |
 LL |     impl<T: Local> Global for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^------^^^^^---^^^
+   |                    |          |
+   |                    |          `Vec` is not local
+   |                    `Global` is not local
    |
    = 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`
@@ -20,7 +23,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:20:5
    |
 LL |     impl Uto7 for Test where Local: std::any::Any {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^----
+   |          |        |
+   |          |        `Test` is not local
+   |          `Uto7` is not local
    |
    = 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`
@@ -37,7 +43,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:23:5
    |
 LL |     impl<T> Uto8 for T {}
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^----^^^^^-
+   |             |        |
+   |             |        `T` is not local
+   |             `Uto8` is not local
    |
    = 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`
@@ -52,7 +61,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:32:5
    |
 LL |     impl Default for UwU<OwO> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-------^^^^^---^^^^^
+   |          |           |
+   |          |           `UwU` is not local
+   |          `Default` is not local
    |
    = 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`
@@ -75,7 +87,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:43:5
    |
 LL |     impl AsRef<Cat> for () {
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^-----^^^^^^^^^^--
+   |          |              |
+   |          |              `()` is not local
+   |          `AsRef` is not local
    |
    = 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`
@@ -96,7 +111,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:54:5
    |
 LL |     impl PartialEq<B> for G {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---------^^^^^^^^-
+   |          |                |
+   |          |                `G` is not local
+   |          `PartialEq` is not local
    |
    = 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`
@@ -119,7 +137,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:69:5
    |
 LL |     impl From<Wrap<Wrap<Lion>>> for () {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^--
+   |          |                          |
+   |          `From` is not local        `()` is not local
    |
    = 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`
@@ -142,7 +162,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/generics.rs:76:5
    |
 LL |     impl From<()> for Wrap<Lion> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^----^^^^^^^^^----^^^^^^
+   |          |            |
+   |          |            `Wrap` is not local
+   |          `From` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index fea211a4e50..f83894b3082 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/inside-macro_rules.rs:9:13
    |
 LL |             impl MacroTrait for OutsideStruct {}
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^----------^^^^^-------------
+   |                  |              |
+   |                  |              `OutsideStruct` is not local
+   |                  `MacroTrait` is not local
 ...
 LL | m!();
    | ---- in this macro invocation
diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
index 83557a7b9a2..557258d2aef 100644
--- a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
+++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/suggest-moving-inner.rs:12:5
    |
 LL |     impl<T> Trait<InsideMain> for &Vec<below::Type<(InsideMain, T)>>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^-----^^^^^^^^^^^^^^^^^----------------------------------
+   |             |                     |
+   |             |                     `&'_ Vec<below::Type<(InsideMain, T)>>` is not local
+   |             `Trait` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index de4eacbecca..04db22f213b 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -2,9 +2,11 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/trait-solver-overflow-123573.rs:12:5
    |
 LL |     impl Test for &Local {}
-   |     ^^^^^^^^^^^^^^-^^^^^
-   |                   |
-   |                   help: remove `&` to make the `impl` local
+   |     ^^^^^----^^^^^------
+   |          |        |
+   |          |        `&'_ Local` is not local
+   |          |        help: remove `&` to make the `impl` local
+   |          `Test` is not local
    |
    = 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`
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index cced1171903..c77dab2ef34 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:8:5
    |
 LL |     impl Uto for *mut Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^---^^^^^---------
+   |          |       |
+   |          |       `*mut Test` is not local
+   |          `Uto` is not local
    |
    = 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`
@@ -18,7 +21,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:16:9
    |
 LL |         impl Uto for Test {}
-   |         ^^^^^^^^^^^^^^^^^
+   |         ^^^^^---^^^^^----
+   |              |       |
+   |              |       `Test` is not local
+   |              `Uto` is not local
    |
    = 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`
@@ -33,7 +39,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:25:9
    |
 LL |         impl Test {
-   |         ^^^^^^^^^
+   |         ^^^^^----
+   |              |
+   |              `Test` is not local
    |
    = 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`
 help: move this `impl` block outside of the current constant expression `<unnameable>` and up 2 bodies
@@ -50,7 +58,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:34:9
    |
 LL |         impl Uto for &Test {}
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^^^^---^^^^^-----
+   |              |       |
+   |              |       `&'_ Test` is not local
+   |              `Uto` is not local
    |
    = 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`
@@ -65,7 +76,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:41:9
    |
 LL |         impl Uto for &(Test,) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^---^^^^^--------
+   |              |       |
+   |              |       `&'_ (Test,)` is not local
+   |              `Uto` is not local
    |
    = 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`
@@ -80,7 +94,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/weird-exprs.rs:48:9
    |
 LL |         impl Uto for &(Test,Test) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^---^^^^^------------
+   |              |       |
+   |              |       `&'_ (Test, Test)` is not local
+   |              `Uto` is not local
    |
    = 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`

From c7d300442ff94cbe60a22400750cd03dbf15bcef Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Sat, 18 May 2024 15:07:28 +0200
Subject: [PATCH 11/11] non_local_defs: point the parent item when appropriate

---
 compiler/rustc_lint/messages.ftl              |  11 +-
 compiler/rustc_lint/src/lints.rs              |  16 +-
 compiler/rustc_lint/src/non_local_def.rs      |  22 +-
 .../lint/non-local-defs/cargo-update.stderr   |   6 +-
 tests/ui/lint/non-local-defs/consts.stderr    |  96 ++++-----
 .../non-local-defs/exhaustive-trait.stderr    |  77 ++-----
 .../ui/lint/non-local-defs/exhaustive.stderr  | 203 +++++++-----------
 .../from-local-for-global.stderr              |  80 +++----
 tests/ui/lint/non-local-defs/generics.stderr  | 123 +++++------
 .../non-local-defs/inside-macro_rules.stderr  |  10 +-
 .../suggest-moving-inner.stderr               |  26 ++-
 .../trait-solver-overflow-123573.stderr       |  12 +-
 .../ui/lint/non-local-defs/weird-exprs.stderr | 129 +++++------
 13 files changed, 330 insertions(+), 481 deletions(-)

diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 8d1f7e150bc..0b164550096 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -543,11 +543,6 @@ lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may
 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>
 
 lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
-    .move_help =
-        move this `impl` block outside of the current {$body_kind_descr} {$depth ->
-            [one] `{$body_name}`
-           *[other] `{$body_name}` and up {$depth} bodies
-        }
     .remove_help = remove `{$may_remove_part}` to make the `impl` local
     .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`
     .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`
@@ -555,6 +550,12 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
     .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
     .const_anon = use a const-anon item to suppress this lint
 
+lint_non_local_definitions_impl_move_help =
+    move the `impl` block outside of this {$body_kind_descr} {$depth ->
+        [one] `{$body_name}`
+       *[other] `{$body_name}` and up {$depth} bodies
+    }
+
 lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
     .help =
         remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 8c8ab4e0f37..2edfb8d3df4 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1336,8 +1336,7 @@ pub enum NonLocalDefinitionsDiag {
         body_name: String,
         cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
         const_anon: Option<Option<Span>>,
-        move_help: Span,
-        may_move: Vec<Span>,
+        move_to: Option<(Span, Vec<Span>)>,
         may_remove: Option<(Span, String)>,
         has_trait: bool,
         self_ty_str: String,
@@ -1362,8 +1361,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                 body_name,
                 cargo_update,
                 const_anon,
-                move_help,
-                may_move,
+                move_to,
                 may_remove,
                 has_trait,
                 self_ty_str,
@@ -1385,11 +1383,13 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
                     diag.note(fluent::lint_without_trait);
                 }
 
-                let mut ms = MultiSpan::from_span(move_help);
-                for sp in may_move {
-                    ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
+                if let Some((move_help, may_move)) = move_to {
+                    let mut ms = MultiSpan::from_span(move_help);
+                    for sp in may_move {
+                        ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
+                    }
+                    diag.span_help(ms, fluent::lint_non_local_definitions_impl_move_help);
                 }
-                diag.span_help(ms, fluent::lint_move_help);
 
                 if let Some((span, part)) = may_remove {
                     diag.arg("may_remove_part", part);
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index d88c774ed80..42b03f47a5b 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -198,17 +198,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 }
                 collector.visit_generics(&impl_.generics);
 
-                let may_move: Vec<Span> = collector
+                let mut may_move: Vec<Span> = collector
                     .paths
                     .into_iter()
                     .filter_map(|path| {
-                        if path_has_local_parent(&path, cx, parent, parent_parent) {
-                            Some(path_span_without_args(&path))
+                        if let Some(did) = path.res.opt_def_id()
+                            && did_has_local_parent(did, cx.tcx, parent, parent_parent)
+                        {
+                            Some(cx.tcx.def_span(did))
                         } else {
                             None
                         }
                     })
                     .collect();
+                may_move.sort();
+                may_move.dedup();
 
                 let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. })
                     .then_some(span_for_const_anon_suggestion);
@@ -244,13 +248,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 } else {
                     None
                 };
+                let move_to = if may_move.is_empty() {
+                    ms.push_span_label(
+                        cx.tcx.def_span(parent),
+                        fluent::lint_non_local_definitions_impl_move_help,
+                    );
+                    None
+                } else {
+                    Some((cx.tcx.def_span(parent), may_move))
+                };
 
                 cx.emit_span_lint(
                     NON_LOCAL_DEFINITIONS,
                     ms,
                     NonLocalDefinitionsDiag::Impl {
                         depth: self.body_depth,
-                        move_help: item.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())
@@ -259,7 +271,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                         const_anon,
                         self_ty_str,
                         of_trait_str,
-                        may_move,
+                        move_to,
                         may_remove,
                         has_trait: impl_.of_trait.is_some(),
                     },
diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr
index 091c6f3d564..888fd2e6183 100644
--- a/tests/ui/lint/non-local-defs/cargo-update.stderr
+++ b/tests/ui/lint/non-local-defs/cargo-update.stderr
@@ -6,14 +6,10 @@ LL | non_local_macro::non_local_impl!(LocalStruct);
    | |
    | `LocalStruct` is not local
    | `Debug` is not local
+   | move the `impl` block outside of this constant `_IMPL_DEBUG`
    |
    = 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 outside of the current constant `_IMPL_DEBUG`
-  --> $DIR/cargo-update.rs:17:1
-   |
-LL | non_local_macro::non_local_impl!(LocalStruct);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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 --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index bf2b1541b2d..2756ea40138 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -2,7 +2,10 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam
   --> $DIR/consts.rs:13:5
    |
 LL | const Z: () = {
-   |       - help: use a const-anon item to suppress this lint: `_`
+   | -----------
+   | |     |
+   | |     help: use a const-anon item to suppress this lint: `_`
+   | move the `impl` block outside of this constant `Z`
 ...
 LL |     impl Uto for &Test {}
    |     ^^^^^---^^^^^-----
@@ -12,11 +15,6 @@ 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 outside of the current constant `Z`
-  --> $DIR/consts.rs:13:5
-   |
-LL |     impl Uto for &Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
    = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
@@ -24,6 +22,8 @@ LL |     impl Uto for &Test {}
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/consts.rs:24:5
    |
+LL | static A: u32 = {
+   | ------------- move the `impl` block outside of this static `A`
 LL |     impl Uto2 for Test {}
    |     ^^^^^----^^^^^----
    |          |        |
@@ -32,17 +32,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 outside of the current static `A`
-  --> $DIR/consts.rs:24:5
-   |
-LL |     impl Uto2 for Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
    = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
   --> $DIR/consts.rs:32:5
    |
+LL | const B: u32 = {
+   | ------------ move the `impl` block outside of this constant `B`
 LL |     impl Uto3 for Test {}
    |     ^^^^^----^^^^^----
    |          |        |
@@ -51,75 +48,60 @@ 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 outside of the current constant `B`
-  --> $DIR/consts.rs:32:5
-   |
-LL |     impl Uto3 for Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
    = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
   --> $DIR/consts.rs:43:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
 LL |     impl Test {
    |     ^^^^^----
    |          |
    |          `Test` is not local
    |
    = 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`
-help: move this `impl` block outside of the current function `main`
-  --> $DIR/consts.rs:43:5
-   |
-LL | /     impl Test {
-LL | |
-LL | |         fn foo() {}
-LL | |     }
-   | |_____^
    = 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
   --> $DIR/consts.rs:50:9
    |
-LL |         impl Test {
-   |         ^^^^^----
-   |              |
-   |              `Test` is not local
-   |
-   = 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`
-help: move this `impl` block outside of the current inline constant `<unnameable>` and up 2 bodies
-  --> $DIR/consts.rs:50:9
-   |
-LL | /         impl Test {
+LL |       const {
+   |  ___________-
+LL | |         impl Test {
+   | |         ^^^^^----
+   | |              |
+   | |              `Test` is not local
 LL | |
 LL | |             fn hoo() {}
-LL | |         }
-   | |_________^
+...  |
+LL | |         1
+LL | |     };
+   | |_____- move the `impl` block outside of this inline constant `<unnameable>` and up 2 bodies
+   |
+   = 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`
    = 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
   --> $DIR/consts.rs:59:9
    |
+LL |     const _: u32 = {
+   |     ------------ move the `impl` block outside of this constant `_` and up 2 bodies
 LL |         impl Test {
    |         ^^^^^----
    |              |
    |              `Test` is not local
    |
    = 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`
-help: move this `impl` block outside of the current constant `_` and up 2 bodies
-  --> $DIR/consts.rs:59:9
-   |
-LL | /         impl Test {
-LL | |
-LL | |             fn foo2() {}
-LL | |         }
-   | |_________^
    = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration
    = 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
   --> $DIR/consts.rs:72:9
    |
+LL |     let _a = || {
+   |              -- move the `impl` block outside of this closure `<unnameable>` and up 2 bodies
 LL |         impl Uto9 for Test {}
    |         ^^^^^----^^^^^----
    |              |        |
@@ -128,29 +110,25 @@ 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 outside of the current closure `<unnameable>` and up 2 bodies
-  --> $DIR/consts.rs:72:9
-   |
-LL |         impl Uto9 for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/consts.rs:79:9
    |
-LL |         impl Uto10 for Test {}
-   |         ^^^^^-----^^^^^----
-   |              |         |
-   |              |         `Test` is not local
-   |              `Uto10` is not local
+LL |       type A = [u32; {
+   |  ____________________-
+LL | |         impl Uto10 for Test {}
+   | |         ^^^^^-----^^^^^----
+   | |              |         |
+   | |              |         `Test` is not local
+   | |              `Uto10` is not local
+LL | |
+...  |
+LL | |     }];
+   | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
    |
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
-  --> $DIR/consts.rs:79:9
-   |
-LL |         impl Uto10 for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^
    = 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
diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
index 8164a16b4d1..67df0e31d5b 100644
--- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr
@@ -1,6 +1,8 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:7:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
 LL |     impl PartialEq<()> for Dog {
    |     ^^^^^---------^^^^^^^^^---
    |          |                 |
@@ -9,22 +11,15 @@ 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 outside of the current function `main`
-  --> $DIR/exhaustive-trait.rs:7:5
-   |
-LL | /     impl PartialEq<()> for Dog {
-LL | |
-LL | |         fn eq(&self, _: &()) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
 
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive-trait.rs:14:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl PartialEq<()> for &Dog {
    |     ^^^^^---------^^^^^^^^^----
    |          |                 |
@@ -33,21 +28,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 outside of the current function `main`
-  --> $DIR/exhaustive-trait.rs:14:5
-   |
-LL | /     impl PartialEq<()> for &Dog {
-LL | |
-LL | |         fn eq(&self, _: &()) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
   --> $DIR/exhaustive-trait.rs:21:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl PartialEq<Dog> for () {
    |     ^^^^^---------^^^^^^^^^^--
    |          |                  |
@@ -56,21 +44,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 outside of the current function `main`
-  --> $DIR/exhaustive-trait.rs:21:5
-   |
-LL | /     impl PartialEq<Dog> for () {
-LL | |
-LL | |         fn eq(&self, _: &Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
   --> $DIR/exhaustive-trait.rs:28:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl PartialEq<&Dog> for () {
    |     ^^^^^---------^^^^^^^^^^^--
    |          |                   |
@@ -79,21 +60,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 outside of the current function `main`
-  --> $DIR/exhaustive-trait.rs:28:5
-   |
-LL | /     impl PartialEq<&Dog> for () {
-LL | |
-LL | |         fn eq(&self, _: &&Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
   --> $DIR/exhaustive-trait.rs:35:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl PartialEq<Dog> for &Dog {
    |     ^^^^^---------^^^^^^^^^^----
    |          |                  |
@@ -102,21 +76,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 outside of the current function `main`
-  --> $DIR/exhaustive-trait.rs:35:5
-   |
-LL | /     impl PartialEq<Dog> for &Dog {
-LL | |
-LL | |         fn eq(&self, _: &Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
   --> $DIR/exhaustive-trait.rs:42:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl PartialEq<&Dog> for &Dog {
    |     ^^^^^---------^^^^^^^^^^^----
    |          |                   |
@@ -125,16 +92,6 @@ 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 outside of the current function `main`
-  --> $DIR/exhaustive-trait.rs:42:5
-   |
-LL | /     impl PartialEq<&Dog> for &Dog {
-LL | |
-LL | |         fn eq(&self, _: &&Dog) -> bool {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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: 6 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr
index d6d269674bd..1e0d5caec38 100644
--- a/tests/ui/lint/non-local-defs/exhaustive.stderr
+++ b/tests/ui/lint/non-local-defs/exhaustive.stderr
@@ -1,26 +1,23 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:10:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
 LL |     impl Test {
    |     ^^^^^----
    |          |
    |          `Test` is not local
    |
    = 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`
-help: move this `impl` block outside of the current function `main`
-  --> $DIR/exhaustive.rs:10:5
-   |
-LL | /     impl Test {
-LL | |
-LL | |         fn foo() {}
-LL | |     }
-   | |_____^
    = 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
 
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/exhaustive.rs:15:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Display for Test {
    |     ^^^^^-------^^^^^----
    |          |           |
@@ -29,37 +26,28 @@ LL |     impl Display 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:15:5
-   |
-LL | /     impl Display for Test {
-LL | |
-LL | |         fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
   --> $DIR/exhaustive.rs:22:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl dyn Trait {}
    |     ^^^^^^^^^-----
    |              |
    |              `Trait` is not local
    |
    = 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`
-help: move this `impl` block outside of the current function `main`
-  --> $DIR/exhaustive.rs:22:5
-   |
-LL |     impl dyn Trait {}
-   |     ^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:25:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl<T: Trait> Trait for Vec<T> { }
    |     ^^^^^^^^^^^^^^^-----^^^^^---^^^
    |                    |         |
@@ -68,16 +56,14 @@ LL |     impl<T: Trait> Trait for Vec<T> { }
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:25:5
-   |
-LL |     impl<T: Trait> Trait for Vec<T> { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:28:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for &dyn Trait {}
    |     ^^^^^-----^^^^^----------
    |          |         |
@@ -86,16 +72,14 @@ LL |     impl Trait for &dyn Trait {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:28:5
-   |
-LL |     impl Trait for &dyn Trait {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:31:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for *mut Test {}
    |     ^^^^^-----^^^^^---------
    |          |         |
@@ -104,16 +88,14 @@ LL |     impl Trait for *mut 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:31:5
-   |
-LL |     impl Trait for *mut Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:34:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for *mut [Test] {}
    |     ^^^^^-----^^^^^-----------
    |          |         |
@@ -122,16 +104,14 @@ LL |     impl Trait for *mut [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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:34:5
-   |
-LL |     impl Trait for *mut [Test] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:37:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for [Test; 8] {}
    |     ^^^^^-----^^^^^---------
    |          |         |
@@ -140,16 +120,14 @@ LL |     impl Trait for [Test; 8] {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:37:5
-   |
-LL |     impl Trait for [Test; 8] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:40:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for (Test,) {}
    |     ^^^^^-----^^^^^-------
    |          |         |
@@ -158,16 +136,14 @@ LL |     impl Trait 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:40:5
-   |
-LL |     impl Trait for (Test,) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:43:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for fn(Test) -> () {}
    |     ^^^^^-----^^^^^--------------
    |          |         |
@@ -176,16 +152,14 @@ LL |     impl Trait for fn(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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:43:5
-   |
-LL |     impl Trait for fn(Test) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:46:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
+...
 LL |     impl Trait for fn() -> Test {}
    |     ^^^^^-----^^^^^------------
    |          |         |
@@ -194,16 +168,13 @@ LL |     impl Trait for fn() -> 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:46:5
-   |
-LL |     impl Trait for fn() -> Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/exhaustive.rs:50:9
    |
+LL |     let _a = || {
+   |              -- move the `impl` block outside of this closure `<unnameable>` and up 2 bodies
 LL |         impl Trait for Test {}
    |         ^^^^^-----^^^^^----
    |              |         |
@@ -212,11 +183,6 @@ LL |         impl Trait 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 outside of the current closure `<unnameable>` and up 2 bodies
-  --> $DIR/exhaustive.rs:50:9
-   |
-LL |         impl Trait for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^
    = 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
@@ -231,13 +197,14 @@ LL |     impl Trait for *mut InsideMain {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:58:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/exhaustive.rs:9:1
    |
-LL |     impl Trait for *mut InsideMain {}
-   |     ^^^^^^^^^^^^^^^^^^^^----------^^^
-   |                         |
-   |                         may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct InsideMain;
+   |     ----------------- 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
@@ -251,13 +218,14 @@ LL |     impl Trait for *mut [InsideMain] {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:60:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/exhaustive.rs:9:1
    |
-LL |     impl Trait for *mut [InsideMain] {}
-   |     ^^^^^^^^^^^^^^^^^^^^^----------^^^^
-   |                          |
-   |                          may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct InsideMain;
+   |     ----------------- 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
@@ -271,13 +239,14 @@ LL |     impl Trait for [InsideMain; 8] {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:62:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/exhaustive.rs:9:1
    |
-LL |     impl Trait for [InsideMain; 8] {}
-   |     ^^^^^^^^^^^^^^^^----------^^^^^^^
-   |                     |
-   |                     may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct InsideMain;
+   |     ----------------- 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
@@ -291,13 +260,14 @@ LL |     impl Trait for (InsideMain,) {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:64:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/exhaustive.rs:9:1
    |
-LL |     impl Trait for (InsideMain,) {}
-   |     ^^^^^^^^^^^^^^^^----------^^^^^
-   |                     |
-   |                     may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct InsideMain;
+   |     ----------------- 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
@@ -311,13 +281,14 @@ LL |     impl Trait for fn(InsideMain) -> () {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:66:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/exhaustive.rs:9:1
    |
-LL |     impl Trait for fn(InsideMain) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^----------^^^^^^^^^^
-   |                       |
-   |                       may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct InsideMain;
+   |     ----------------- 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
@@ -331,18 +302,21 @@ LL |     impl Trait for fn() -> InsideMain {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/exhaustive.rs:68:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/exhaustive.rs:9:1
    |
-LL |     impl Trait for fn() -> InsideMain {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^----------^^^
-   |                            |
-   |                            may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct InsideMain;
+   |     ----------------- 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
   --> $DIR/exhaustive.rs:72:9
    |
+LL |     fn inside_inside() {
+   |     ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies
 LL |         impl Display for InsideMain {
    |         ^^^^^-------^^^^^----------
    |              |           |
@@ -351,35 +325,20 @@ LL |         impl Display for InsideMain {
    |
    = 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 outside of the current function `inside_inside` and up 2 bodies
-  --> $DIR/exhaustive.rs:72:9
-   |
-LL | /         impl Display for InsideMain {
-LL | |
-LL | |             fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-LL | |                 todo!()
-LL | |             }
-LL | |         }
-   | |_________^
    = 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
   --> $DIR/exhaustive.rs:79:9
    |
+LL |     fn inside_inside() {
+   |     ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies
+...
 LL |         impl InsideMain {
    |         ^^^^^----------
    |              |
    |              `InsideMain` is not local
    |
    = 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`
-help: move this `impl` block outside of the current function `inside_inside` and up 2 bodies
-  --> $DIR/exhaustive.rs:79:9
-   |
-LL | /         impl InsideMain {
-LL | |
-LL | |             fn bar() {}
-LL | |         }
-   | |_________^
    = 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: 20 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
index 1c1dcb65abc..67fd937d134 100644
--- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr
+++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr
@@ -1,6 +1,8 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/from-local-for-global.rs:8:5
    |
+LL | fn main() {
+   | --------- move the `impl` block outside of this function `main`
 LL |     impl From<Cat> for () {
    |     ^^^^^----^^^^^^^^^^--
    |          |             |
@@ -9,16 +11,6 @@ LL |     impl From<Cat> 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 outside of the current function `main`
-  --> $DIR/from-local-for-global.rs:8:5
-   |
-LL | /     impl From<Cat> for () {
-LL | |
-LL | |         fn from(_: Cat) -> () {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
    = 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
 
@@ -32,19 +24,14 @@ LL |     impl From<Wrap<Wrap<Elephant>>> 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 outside of the current function `main`
-  --> $DIR/from-local-for-global.rs:18:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/from-local-for-global.rs:7:1
    |
-LL |       impl From<Wrap<Wrap<Elephant>>> for () {
-   |       ^                   -------- may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn from(_: Wrap<Wrap<Elephant>>) -> Self {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn main() {
+   | ^^^^^^^^^
+...
+LL |     struct Elephant;
+   |     --------------- 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
@@ -59,13 +46,13 @@ LL |     impl StillNonLocal for &Foo {}
    |
    = 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 outside of the current function `only_global`
-  --> $DIR/from-local-for-global.rs:32:5
+help: move the `impl` block outside of this function `only_global`
+  --> $DIR/from-local-for-global.rs:30:1
    |
-LL |     impl StillNonLocal for &Foo {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^---^^^
-   |                             |
-   |                             may need to be moved as well
+LL | fn only_global() {
+   | ^^^^^^^^^^^^^^^^
+LL |     struct Foo;
+   |     ---------- 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
@@ -79,19 +66,13 @@ LL |     impl From<Local1> for GlobalSameFunction {
    |
    = 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 outside of the current function `same_function`
-  --> $DIR/from-local-for-global.rs:40:5
+help: move the `impl` block outside of this function `same_function`
+  --> $DIR/from-local-for-global.rs:38:1
    |
-LL |       impl From<Local1> for GlobalSameFunction {
-   |       ^         ------ may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn from(x: Local1) -> GlobalSameFunction {
-LL | |             x.0
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn same_function() {
+   | ^^^^^^^^^^^^^^^^^^
+LL |     struct Local1(GlobalSameFunction);
+   |     ------------- 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
@@ -105,19 +86,14 @@ LL |     impl From<Local2> for GlobalSameFunction {
    |
    = 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 outside of the current function `same_function`
-  --> $DIR/from-local-for-global.rs:48:5
+help: move the `impl` block outside of this function `same_function`
+  --> $DIR/from-local-for-global.rs:38:1
    |
-LL |       impl From<Local2> for GlobalSameFunction {
-   |       ^         ------ may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn from(x: Local2) -> GlobalSameFunction {
-LL | |             x.0
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn same_function() {
+   | ^^^^^^^^^^^^^^^^^^
+...
+LL |     struct Local2(GlobalSameFunction);
+   |     ------------- 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: 5 warnings emitted
diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr
index 7d64d9b1b09..ed2f87a4ed2 100644
--- a/tests/ui/lint/non-local-defs/generics.stderr
+++ b/tests/ui/lint/non-local-defs/generics.stderr
@@ -9,13 +9,13 @@ LL |     impl<T: Local> Global for Vec<T> { }
    |
    = 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 outside of the current function `main`
-  --> $DIR/generics.rs:9:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/generics.rs:6:1
    |
-LL |     impl<T: Local> Global for Vec<T> { }
-   |     ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
-   |             |
-   |             may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+LL |     trait Local {};
+   |     ----------- 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>
    = note: `#[warn(non_local_definitions)]` on by default
 
@@ -30,18 +30,21 @@ LL |     impl Uto7 for Test where Local: std::any::Any {}
    |
    = 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 outside of the current function `bad`
-  --> $DIR/generics.rs:20:5
+help: move the `impl` block outside of this function `bad`
+  --> $DIR/generics.rs:18:1
    |
-LL |     impl Uto7 for Test where Local: std::any::Any {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^
-   |                              |
-   |                              may need to be moved as well
+LL | fn bad() {
+   | ^^^^^^^^
+LL |     struct Local;
+   |     ------------ 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
   --> $DIR/generics.rs:23:5
    |
+LL | fn bad() {
+   | -------- move the `impl` block outside of this function `bad`
+...
 LL |     impl<T> Uto8 for T {}
    |     ^^^^^^^^----^^^^^-
    |             |        |
@@ -50,11 +53,6 @@ LL |     impl<T> Uto8 for T {}
    |
    = 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 outside of the current function `bad`
-  --> $DIR/generics.rs:23:5
-   |
-LL |     impl<T> Uto8 for T {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
    = 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
@@ -68,19 +66,14 @@ LL |     impl Default for UwU<OwO> {
    |
    = 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 outside of the current function `fun`
-  --> $DIR/generics.rs:32:5
+help: move the `impl` block outside of this function `fun`
+  --> $DIR/generics.rs:29:1
    |
-LL |       impl Default for UwU<OwO> {
-   |       ^                    --- may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn default() -> Self {
-LL | |             UwU(OwO)
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn fun() {
+   | ^^^^^^^^
+LL |     #[derive(Debug)]
+LL |     struct OwO;
+   |     ---------- 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
@@ -94,17 +87,14 @@ LL |     impl AsRef<Cat> 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 outside of the current function `meow`
-  --> $DIR/generics.rs:43:5
+help: move the `impl` block outside of this function `meow`
+  --> $DIR/generics.rs:40:1
    |
-LL |       impl AsRef<Cat> for () {
-   |       ^          --- may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn as_ref(&self) -> &Cat { &Cat }
-LL | |     }
-   | |_____^
+LL | fn meow() {
+   | ^^^^^^^^^
+LL |     #[derive(Debug)]
+LL |     struct Cat;
+   |     ---------- 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
@@ -118,19 +108,14 @@ LL |     impl PartialEq<B> for G {
    |
    = 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 outside of the current function `fun2`
-  --> $DIR/generics.rs:54:5
+help: move the `impl` block outside of this function `fun2`
+  --> $DIR/generics.rs:51:1
    |
-LL |       impl PartialEq<B> for G {
-   |       ^              - may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn eq(&self, _: &B) -> bool {
-LL | |             true
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn fun2() {
+   | ^^^^^^^^^
+LL |     #[derive(Debug, Default)]
+LL |     struct B;
+   |     -------- 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
@@ -143,19 +128,13 @@ LL |     impl From<Wrap<Wrap<Lion>>> 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 outside of the current function `rawr`
-  --> $DIR/generics.rs:69:5
+help: move the `impl` block outside of this function `rawr`
+  --> $DIR/generics.rs:66:1
    |
-LL |       impl From<Wrap<Wrap<Lion>>> for () {
-   |       ^                   ---- may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn from(_: Wrap<Wrap<Lion>>) -> Self {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn rawr() {
+   | ^^^^^^^^^
+LL |     struct Lion;
+   |     ----------- 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
@@ -169,19 +148,13 @@ LL |     impl From<()> for Wrap<Lion> {
    |
    = 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 outside of the current function `rawr`
-  --> $DIR/generics.rs:76:5
+help: move the `impl` block outside of this function `rawr`
+  --> $DIR/generics.rs:66:1
    |
-LL |       impl From<()> for Wrap<Lion> {
-   |       ^                      ---- may need to be moved as well
-   |  _____|
-   | |
-LL | |
-LL | |         fn from(_: ()) -> Self {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
+LL | fn rawr() {
+   | ^^^^^^^^^
+LL |     struct Lion;
+   |     ----------- 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
diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
index f83894b3082..b52301d1aa0 100644
--- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
+++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr
@@ -1,6 +1,8 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/inside-macro_rules.rs:9:13
    |
+LL |         fn my_func() {
+   |         ------------ move the `impl` block outside of this function `my_func`
 LL |             impl MacroTrait for OutsideStruct {}
    |             ^^^^^----------^^^^^-------------
    |                  |              |
@@ -12,14 +14,6 @@ LL | m!();
    |
    = 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 outside of the current function `my_func`
-  --> $DIR/inside-macro_rules.rs:9:13
-   |
-LL |             impl MacroTrait for OutsideStruct {}
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | m!();
-   | ---- in this macro invocation
    = 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
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
index 557258d2aef..f0de0f72e74 100644
--- a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
+++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr
@@ -9,21 +9,19 @@ LL |     impl<T> Trait<InsideMain> for &Vec<below::Type<(InsideMain, T)>>
    |
    = 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 outside of the current function `main`
-  --> $DIR/suggest-moving-inner.rs:12:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/suggest-moving-inner.rs:5:1
    |
-LL |       impl<T> Trait<InsideMain> for &Vec<below::Type<(InsideMain, T)>>
-   |       ^             ----------           -----------  ---------- may need to be moved as well
-   |       |             |                    |
-   |       |             |                    may need to be moved as well
-   |  _____|             may need to be moved as well
-   | |
-LL | |
-LL | |     where
-LL | |         T: HasFoo
-   | |            ------ may need to be moved as well
-LL | |     {}
-   | |______^
+LL | fn main() {
+   | ^^^^^^^^^
+LL |     mod below {
+LL |         pub struct Type<T>(T);
+   |         ------------------ may need to be moved as well
+LL |     }
+LL |     struct InsideMain;
+   |     ----------------- may need to be moved as well
+LL |     trait HasFoo {}
+   |     ------------ 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>
    = note: `#[warn(non_local_definitions)]` on by default
 
diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
index 04db22f213b..80930ce1bcd 100644
--- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
+++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr
@@ -10,13 +10,13 @@ LL |     impl Test for &Local {}
    |
    = 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 outside of the current function `main`
-  --> $DIR/trait-solver-overflow-123573.rs:12:5
+help: move the `impl` block outside of this function `main`
+  --> $DIR/trait-solver-overflow-123573.rs:10:1
    |
-LL |     impl Test for &Local {}
-   |     ^^^^^^^^^^^^^^^-----^^^
-   |                    |
-   |                    may need to be moved as well
+LL | fn main() {
+   | ^^^^^^^^^
+LL |     struct Local {}
+   |     ------------ 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>
    = note: `#[warn(non_local_definitions)]` on by default
 
diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr
index c77dab2ef34..cd414d636d3 100644
--- a/tests/ui/lint/non-local-defs/weird-exprs.stderr
+++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr
@@ -1,111 +1,116 @@
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:8:5
    |
-LL |     impl Uto for *mut Test {}
-   |     ^^^^^---^^^^^---------
-   |          |       |
-   |          |       `*mut Test` is not local
-   |          `Uto` is not local
+LL |   type A = [u32; {
+   |  ________________-
+LL | |     impl Uto for *mut Test {}
+   | |     ^^^^^---^^^^^---------
+   | |          |       |
+   | |          |       `*mut Test` is not local
+   | |          `Uto` is not local
+LL | |
+...  |
+LL | | }];
+   | |_- move the `impl` block outside of this constant expression `<unnameable>`
    |
    = 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 outside of the current constant expression `<unnameable>`
-  --> $DIR/weird-exprs.rs:8:5
-   |
-LL |     impl Uto for *mut Test {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
 
 warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
   --> $DIR/weird-exprs.rs:16:9
    |
-LL |         impl Uto for Test {}
-   |         ^^^^^---^^^^^----
-   |              |       |
-   |              |       `Test` is not local
-   |              `Uto` is not local
+LL |       Discr = {
+   |  _____________-
+LL | |         impl Uto for Test {}
+   | |         ^^^^^---^^^^^----
+   | |              |       |
+   | |              |       `Test` is not local
+   | |              `Uto` is not local
+LL | |
+...  |
+LL | |     }
+   | |_____- move the `impl` block outside of this constant expression `<unnameable>`
    |
    = 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 outside of the current constant expression `<unnameable>`
-  --> $DIR/weird-exprs.rs:16:9
-   |
-LL |         impl Uto for Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/weird-exprs.rs:25:9
    |
-LL |         impl Test {
-   |         ^^^^^----
-   |              |
-   |              `Test` is not local
-   |
-   = 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`
-help: move this `impl` block outside of the current constant expression `<unnameable>` and up 2 bodies
-  --> $DIR/weird-exprs.rs:25:9
-   |
-LL | /         impl Test {
+LL |       let _array = [0i32; {
+   |  _________________________-
+LL | |         impl Test {
+   | |         ^^^^^----
+   | |              |
+   | |              `Test` is not local
 LL | |
 LL | |             fn bar() {}
-LL | |         }
-   | |_________^
+...  |
+LL | |         1
+LL | |     }];
+   | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
+   |
+   = 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`
    = 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
   --> $DIR/weird-exprs.rs:34:9
    |
-LL |         impl Uto for &Test {}
-   |         ^^^^^---^^^^^-----
-   |              |       |
-   |              |       `&'_ Test` is not local
-   |              `Uto` is not local
+LL |       type A = [u32; {
+   |  ____________________-
+LL | |         impl Uto for &Test {}
+   | |         ^^^^^---^^^^^-----
+   | |              |       |
+   | |              |       `&'_ Test` is not local
+   | |              `Uto` is not local
+LL | |
+...  |
+LL | |     }];
+   | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
    |
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
-  --> $DIR/weird-exprs.rs:34:9
-   |
-LL |         impl Uto for &Test {}
-   |         ^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/weird-exprs.rs:41:9
    |
-LL |         impl Uto for &(Test,) {}
-   |         ^^^^^---^^^^^--------
-   |              |       |
-   |              |       `&'_ (Test,)` is not local
-   |              `Uto` is not local
+LL |       fn a(_: [u32; {
+   |  ___________________-
+LL | |         impl Uto for &(Test,) {}
+   | |         ^^^^^---^^^^^--------
+   | |              |       |
+   | |              |       `&'_ (Test,)` is not local
+   | |              `Uto` is not local
+LL | |
+...  |
+LL | |     }]) {}
+   | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
    |
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
-  --> $DIR/weird-exprs.rs:41:9
-   |
-LL |         impl Uto for &(Test,) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
    = 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
   --> $DIR/weird-exprs.rs:48:9
    |
-LL |         impl Uto for &(Test,Test) {}
-   |         ^^^^^---^^^^^------------
-   |              |       |
-   |              |       `&'_ (Test, Test)` is not local
-   |              `Uto` is not local
+LL |       fn b() -> [u32; {
+   |  _____________________-
+LL | |         impl Uto for &(Test,Test) {}
+   | |         ^^^^^---^^^^^------------
+   | |              |       |
+   | |              |       `&'_ (Test, Test)` is not local
+   | |              `Uto` is not local
+LL | |
+...  |
+LL | |     }] { todo!() }
+   | |_____- move the `impl` block outside of this constant expression `<unnameable>` and up 2 bodies
    |
    = 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 outside of the current constant expression `<unnameable>` and up 2 bodies
-  --> $DIR/weird-exprs.rs:48:9
-   |
-LL |         impl Uto for &(Test,Test) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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: 6 warnings emitted