about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs10
-rw-r--r--compiler/rustc_lint/Cargo.toml1
-rw-r--r--compiler/rustc_lint/messages.ftl23
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs39
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs222
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs9
-rw-r--r--compiler/rustc_macros/src/hash_stable.rs2
-rw-r--r--compiler/rustc_macros/src/lift.rs1
-rw-r--r--compiler/rustc_macros/src/serialize.rs12
-rw-r--r--compiler/rustc_macros/src/type_foldable.rs2
-rw-r--r--compiler/rustc_macros/src/type_visitable.rs2
-rw-r--r--library/core/src/convert/mod.rs1
-rw-r--r--library/core/src/hash/mod.rs1
-rw-r--r--library/core/tests/iter/adapters/step_by.rs1
-rw-r--r--library/core/tests/result.rs2
-rw-r--r--src/librustdoc/doctest.rs7
-rw-r--r--src/librustdoc/html/markdown/tests.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs2
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.fixed2
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-4760.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6179.rs1
-rw-r--r--src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed1
-rw-r--r--src/tools/clippy/tests/ui/explicit_into_iter_loop.rs1
-rw-r--r--src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr12
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed3
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs3
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.stderr36
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed1
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs1
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr14
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.stderr20
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr54
-rw-r--r--src/tools/rustfmt/src/source_file.rs1
-rw-r--r--tests/ui/async-await/async-assoc-fn-anon-lifetimes.rs2
-rw-r--r--tests/ui/const-generics/min_const_generics/macro.rs2
-rw-r--r--tests/ui/consts/const_in_pattern/accept_structural.rs1
-rw-r--r--tests/ui/drop/dropck-eyepatch-reorder.rs1
-rw-r--r--tests/ui/drop/dropck-eyepatch.rs1
-rw-r--r--tests/ui/imports/local-modularized-tricky-pass-2.rs1
-rw-r--r--tests/ui/issues/issue-31776.rs1
-rw-r--r--tests/ui/issues/issue-41053.rs2
-rw-r--r--tests/ui/lint/auxiliary/non_local_macro.rs26
-rw-r--r--tests/ui/lint/non_local_definitions.rs385
-rw-r--r--tests/ui/lint/non_local_definitions.stderr640
-rw-r--r--tests/ui/macros/type-macros-simple.rs2
-rw-r--r--tests/ui/packed/issue-46152.rs1
-rw-r--r--tests/ui/privacy/associated-item-privacy-trait.rs2
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.rs1
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.stderr8
-rw-r--r--tests/ui/proc-macro/nested-macro-rules.rs1
-rw-r--r--tests/ui/proc-macro/nested-macro-rules.stderr27
-rw-r--r--tests/ui/rust-2018/uniform-paths/issue-55779.rs2
59 files changed, 1518 insertions, 92 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8518bb2a91f..4e00c9034bd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4101,6 +4101,7 @@ dependencies = [
  "rustc_target",
  "rustc_trait_selection",
  "rustc_type_ir",
+ "smallvec",
  "tracing",
  "unicode-security",
 ]
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 9e1e884d976..3aef29f4ae4 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -24,6 +24,11 @@ struct InherentOverlapChecker<'tcx> {
     tcx: TyCtxt<'tcx>,
 }
 
+rustc_index::newtype_index! {
+    #[orderable]
+    pub struct RegionId {}
+}
+
 impl<'tcx> InherentOverlapChecker<'tcx> {
     /// Checks whether any associated items in impls 1 and 2 share the same identifier and
     /// namespace.
@@ -205,11 +210,6 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
             // This is advantageous to running the algorithm over the
             // entire graph when there are many connected regions.
 
-            rustc_index::newtype_index! {
-                #[orderable]
-                pub struct RegionId {}
-            }
-
             struct ConnectedRegion {
                 idents: SmallVec<[Symbol; 8]>,
                 impl_blocks: FxHashSet<usize>,
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
index fa1133e7780..2271321b8bf 100644
--- a/compiler/rustc_lint/Cargo.toml
+++ b/compiler/rustc_lint/Cargo.toml
@@ -23,6 +23,7 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_type_ir = { path = "../rustc_type_ir" }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 unicode-security = "0.1.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 496ffeddbff..f89cb8ed8b6 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -414,6 +414,29 @@ lint_non_fmt_panic_unused =
     }
     .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
 
+lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`
+
+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
+    .help =
+        move this `impl` block outside the of the current {$body_kind_descr} {$depth ->
+            [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 neither the type nor the trait are at the same nesting level as the `impl` block
+    .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
+    .help =
+        remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->
+            [one] `{$body_name}`
+           *[other] `{$body_name}` and up {$depth} bodies
+        }
+    .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_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/lib.rs b/compiler/rustc_lint/src/lib.rs
index 844f87c3f50..0e446e09d41 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -70,6 +70,7 @@ mod methods;
 mod multiple_supertrait_upcastable;
 mod non_ascii_idents;
 mod non_fmt_panic;
+mod non_local_def;
 mod nonstandard_style;
 mod noop_method_call;
 mod opaque_hidden_inferred_bound;
@@ -105,6 +106,7 @@ use methods::*;
 use multiple_supertrait_upcastable::*;
 use non_ascii_idents::*;
 use non_fmt_panic::NonPanicFmt;
+use non_local_def::*;
 use nonstandard_style::*;
 use noop_method_call::*;
 use opaque_hidden_inferred_bound::*;
@@ -229,6 +231,7 @@ late_lint_methods!(
             MissingDebugImplementations: MissingDebugImplementations,
             MissingDoc: MissingDoc,
             AsyncFnInTrait: AsyncFnInTrait,
+            NonLocalDefinitions: NonLocalDefinitions::default(),
         ]
     ]
 );
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d73b9015ce1..d8a0b75f8bd 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1334,6 +1334,45 @@ pub struct SuspiciousDoubleRefCloneDiag<'a> {
     pub ty: Ty<'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)]
+    #[help]
+    #[note(lint_non_local)]
+    #[note(lint_exception)]
+    #[note(lint_non_local_definitions_deprecation)]
+    MacroRules {
+        depth: u32,
+        body_kind_descr: &'static str,
+        body_name: String,
+        #[subdiagnostic]
+        cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
+    },
+}
+
+#[derive(Subdiagnostic)]
+#[note(lint_non_local_definitions_cargo_update)]
+pub struct NonLocalDefinitionsCargoUpdateNote {
+    pub macro_kind: &'static str,
+    pub macro_name: Symbol,
+    pub crate_name: Symbol,
+}
+
 // pass_by_value.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_pass_by_value)]
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
new file mode 100644
index 00000000000..6cb6fd1cbd5
--- /dev/null
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -0,0 +1,222 @@
+use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
+use rustc_span::def_id::{DefId, LOCAL_CRATE};
+use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
+
+use smallvec::{smallvec, SmallVec};
+
+use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
+use crate::{LateContext, LateLintPass, LintContext};
+
+declare_lint! {
+    /// The `non_local_definitions` lint checks for `impl` blocks and `#[macro_export]`
+    /// macro inside bodies (functions, enum discriminant, ...).
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// trait MyTrait {}
+    /// struct MyStruct;
+    ///
+    /// fn foo() {
+    ///     impl MyTrait for MyStruct {}
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Creating non-local definitions go against expectation and can create discrepancies
+    /// in tooling. It should be avoided. It may become deny-by-default in edition 2024
+    /// and higher, see see the tracking issue <https://github.com/rust-lang/rust/issues/120363>.
+    ///
+    /// An `impl` definition is non-local if it is nested inside an item and neither
+    /// the type nor the trait are at the same nesting level as the `impl` block.
+    ///
+    /// All nested bodies (functions, enum discriminant, array length, consts) (expect for
+    /// `const _: Ty = { ... }` in top-level module, which is still undecided) are checked.
+    pub NON_LOCAL_DEFINITIONS,
+    Warn,
+    "checks for non-local definitions",
+    report_in_external_macro
+}
+
+#[derive(Default)]
+pub struct NonLocalDefinitions {
+    body_depth: u32,
+}
+
+impl_lint_pass!(NonLocalDefinitions => [NON_LOCAL_DEFINITIONS]);
+
+// FIXME(Urgau): Figure out how to handle modules nested in bodies.
+// It's currently not handled by the current logic because modules are not bodies.
+// They don't even follow the correct order (check_body -> check_mod -> check_body_post)
+// instead check_mod is called after every body has been handled.
+
+impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
+    fn check_body(&mut self, _cx: &LateContext<'tcx>, _body: &'tcx Body<'tcx>) {
+        self.body_depth += 1;
+    }
+
+    fn check_body_post(&mut self, _cx: &LateContext<'tcx>, _body: &'tcx Body<'tcx>) {
+        self.body_depth -= 1;
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if self.body_depth == 0 {
+            return;
+        }
+
+        let parent = cx.tcx.parent(item.owner_id.def_id.into());
+        let parent_def_kind = cx.tcx.def_kind(parent);
+        let parent_opt_item_name = cx.tcx.opt_item_name(parent);
+
+        // Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in top-level module.
+        if self.body_depth == 1
+            && parent_def_kind == DefKind::Const
+            && parent_opt_item_name == Some(kw::Underscore)
+        {
+            return;
+        }
+
+        let cargo_update = || {
+            let oexpn = item.span.ctxt().outer_expn_data();
+            if let Some(def_id) = oexpn.macro_def_id
+                && let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
+                && def_id.krate != LOCAL_CRATE
+                && std::env::var_os("CARGO").is_some()
+            {
+                Some(NonLocalDefinitionsCargoUpdateNote {
+                    macro_kind: macro_kind.descr(),
+                    macro_name,
+                    crate_name: cx.tcx.crate_name(def_id.krate),
+                })
+            } else {
+                None
+            }
+        };
+
+        match item.kind {
+            ItemKind::Impl(impl_) => {
+                // The RFC states:
+                //
+                // > An item nested inside an expression-containing item (through any
+                // > level of nesting) may not define an impl Trait for Type unless
+                // > either the **Trait** or the **Type** is also nested inside the
+                // > same expression-containing item.
+                //
+                // To achieve this we get try to get the paths of the _Trait_ and
+                // _Type_, and we look inside thoses paths to try a find in one
+                // of them a type whose parent is the same as the impl definition.
+                //
+                // If that's the case this means that this impl block declaration
+                // is using local items and so we don't lint on it.
+
+                // We also ignore anon-const in item by including the anon-const
+                // parent as well; and since it's quite uncommon, we use smallvec
+                // to avoid unnecessary heap allocations.
+                let local_parents: SmallVec<[DefId; 1]> = if parent_def_kind == DefKind::Const
+                    && parent_opt_item_name == Some(kw::Underscore)
+                {
+                    smallvec![parent, cx.tcx.parent(parent)]
+                } else {
+                    smallvec![parent]
+                };
+
+                let self_ty_has_local_parent = match impl_.self_ty.kind {
+                    TyKind::Path(QPath::Resolved(_, ty_path)) => {
+                        path_has_local_parent(ty_path, cx, &*local_parents)
+                    }
+                    TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
+                        path_has_local_parent(
+                            principle_poly_trait_ref.trait_ref.path,
+                            cx,
+                            &*local_parents,
+                        )
+                    }
+                    TyKind::TraitObject([], _, _)
+                    | TyKind::InferDelegation(_, _)
+                    | TyKind::Slice(_)
+                    | TyKind::Array(_, _)
+                    | TyKind::Ptr(_)
+                    | TyKind::Ref(_, _)
+                    | TyKind::BareFn(_)
+                    | TyKind::Never
+                    | TyKind::Tup(_)
+                    | TyKind::Path(_)
+                    | TyKind::AnonAdt(_)
+                    | TyKind::OpaqueDef(_, _, _)
+                    | TyKind::Typeof(_)
+                    | TyKind::Infer
+                    | TyKind::Err(_) => false,
+                };
+
+                let of_trait_has_local_parent = impl_
+                    .of_trait
+                    .map(|of_trait| path_has_local_parent(of_trait.path, cx, &*local_parents))
+                    .unwrap_or(false);
+
+                // If none of them have a local parent (LOGICAL NOR) this means that
+                // this impl definition is a non-local definition and so we lint on it.
+                if !(self_ty_has_local_parent || of_trait_has_local_parent) {
+                    let const_anon = if self.body_depth == 1
+                        && 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)
+                        && let ItemKind::Const(ty, _, _) = item.kind
+                        && let TyKind::Tup(&[]) = ty.kind
+                    {
+                        Some(item.ident.span)
+                    } else {
+                        None
+                    };
+
+                    cx.emit_span_lint(
+                        NON_LOCAL_DEFINITIONS,
+                        item.span,
+                        NonLocalDefinitionsDiag::Impl {
+                            depth: self.body_depth,
+                            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,
+                        },
+                    )
+                }
+            }
+            ItemKind::Macro(_macro, MacroKind::Bang)
+                if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
+            {
+                cx.emit_span_lint(
+                    NON_LOCAL_DEFINITIONS,
+                    item.span,
+                    NonLocalDefinitionsDiag::MacroRules {
+                        depth: self.body_depth,
+                        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(),
+                    },
+                )
+            }
+            _ => {}
+        }
+    }
+}
+
+/// 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.
+///
+/// Given this path, we will look at the path (and ignore any generic args):
+///
+/// ```text
+///    std::convert::PartialEq<Foo<Bar>>
+///    ^^^^^^^^^^^^^^^^^^^^^^^
+/// ```
+fn path_has_local_parent(path: &Path<'_>, cx: &LateContext<'_>, local_parents: &[DefId]) -> bool {
+    path.res.opt_def_id().is_some_and(|did| local_parents.contains(&cx.tcx.parent(did)))
+}
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 33dffe6998a..044bbadf41c 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -55,7 +55,8 @@ use synstructure::Structure;
 ///
 /// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
 /// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
-pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
+pub fn session_diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
+    s.underscore_const(true);
     DiagnosticDerive::new(s).into_tokens()
 }
 
@@ -101,7 +102,8 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 ///
 /// See rustc dev guide for more examples on using the `#[derive(LintDiagnostic)]`:
 /// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html#reference>
-pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
+pub fn lint_diagnostic_derive(mut s: Structure<'_>) -> TokenStream {
+    s.underscore_const(true);
     LintDiagnosticDerive::new(s).into_tokens()
 }
 
@@ -151,6 +153,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 ///
 /// diag.subdiagnostic(RawIdentifierSuggestion { span, applicability, ident });
 /// ```
-pub fn session_subdiagnostic_derive(s: Structure<'_>) -> TokenStream {
+pub fn session_subdiagnostic_derive(mut s: Structure<'_>) -> TokenStream {
+    s.underscore_const(true);
     SubdiagnosticDeriveBuilder::new().into_tokens(s)
 }
diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs
index a6396ba687d..6b3210cad7b 100644
--- a/compiler/rustc_macros/src/hash_stable.rs
+++ b/compiler/rustc_macros/src/hash_stable.rs
@@ -74,6 +74,8 @@ fn hash_stable_derive_with_mode(
         HashStableMode::Generic | HashStableMode::NoContext => parse_quote!(__CTX),
     };
 
+    s.underscore_const(true);
+
     // no_context impl is able to derive by-field, which is closer to a perfect derive.
     s.add_bounds(match mode {
         HashStableMode::Normal | HashStableMode::Generic => synstructure::AddBounds::Generics,
diff --git a/compiler/rustc_macros/src/lift.rs b/compiler/rustc_macros/src/lift.rs
index 3dedd88fb19..f7a84ba1510 100644
--- a/compiler/rustc_macros/src/lift.rs
+++ b/compiler/rustc_macros/src/lift.rs
@@ -4,6 +4,7 @@ use syn::parse_quote;
 pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
     s.add_bounds(synstructure::AddBounds::Generics);
     s.bind_with(|_| synstructure::BindStyle::Move);
+    s.underscore_const(true);
 
     let tcx: syn::Lifetime = parse_quote!('tcx);
     let newtcx: syn::GenericParam = parse_quote!('__lifted);
diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs
index 98b53945b91..5fa11d22f0e 100644
--- a/compiler/rustc_macros/src/serialize.rs
+++ b/compiler/rustc_macros/src/serialize.rs
@@ -15,6 +15,7 @@ pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
 
     s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound });
     s.add_bounds(synstructure::AddBounds::Fields);
+    s.underscore_const(true);
 
     decodable_body(s, decoder_ty)
 }
@@ -26,6 +27,7 @@ pub fn meta_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
     s.add_impl_generic(parse_quote! { '__a });
     let decoder_ty = quote! { DecodeContext<'__a, 'tcx> };
     s.add_bounds(synstructure::AddBounds::Generics);
+    s.underscore_const(true);
 
     decodable_body(s, decoder_ty)
 }
@@ -34,6 +36,7 @@ pub fn decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
     let decoder_ty = quote! { __D };
     s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_span::SpanDecoder});
     s.add_bounds(synstructure::AddBounds::Generics);
+    s.underscore_const(true);
 
     decodable_body(s, decoder_ty)
 }
@@ -42,12 +45,13 @@ pub fn decodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macr
     let decoder_ty = quote! { __D };
     s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_serialize::Decoder});
     s.add_bounds(synstructure::AddBounds::Generics);
+    s.underscore_const(true);
 
     decodable_body(s, decoder_ty)
 }
 
 fn decodable_body(
-    s: synstructure::Structure<'_>,
+    mut s: synstructure::Structure<'_>,
     decoder_ty: TokenStream,
 ) -> proc_macro2::TokenStream {
     if let syn::Data::Union(_) = s.ast().data {
@@ -93,6 +97,7 @@ fn decodable_body(
             }
         }
     };
+    s.underscore_const(true);
 
     s.bound_impl(
         quote!(::rustc_serialize::Decodable<#decoder_ty>),
@@ -130,6 +135,7 @@ pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
     let encoder_ty = quote! { __E };
     s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound });
     s.add_bounds(synstructure::AddBounds::Fields);
+    s.underscore_const(true);
 
     encodable_body(s, encoder_ty, false)
 }
@@ -141,6 +147,7 @@ pub fn meta_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
     s.add_impl_generic(parse_quote! { '__a });
     let encoder_ty = quote! { EncodeContext<'__a, 'tcx> };
     s.add_bounds(synstructure::AddBounds::Generics);
+    s.underscore_const(true);
 
     encodable_body(s, encoder_ty, true)
 }
@@ -149,6 +156,7 @@ pub fn encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke
     let encoder_ty = quote! { __E };
     s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_span::SpanEncoder});
     s.add_bounds(synstructure::AddBounds::Generics);
+    s.underscore_const(true);
 
     encodable_body(s, encoder_ty, false)
 }
@@ -157,6 +165,7 @@ pub fn encodable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_macr
     let encoder_ty = quote! { __E };
     s.add_impl_generic(parse_quote! { #encoder_ty: ::rustc_serialize::Encoder});
     s.add_bounds(synstructure::AddBounds::Generics);
+    s.underscore_const(true);
 
     encodable_body(s, encoder_ty, false)
 }
@@ -170,6 +179,7 @@ fn encodable_body(
         panic!("cannot derive on union")
     }
 
+    s.underscore_const(true);
     s.bind_with(|binding| {
         // Handle the lack of a blanket reference impl.
         if let syn::Type::Reference(_) = binding.ast().ty {
diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs
index 5ee4d879313..5617c53b119 100644
--- a/compiler/rustc_macros/src/type_foldable.rs
+++ b/compiler/rustc_macros/src/type_foldable.rs
@@ -6,6 +6,8 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
         panic!("cannot derive on union")
     }
 
+    s.underscore_const(true);
+
     if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
         s.add_impl_generic(parse_quote! { 'tcx });
     }
diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs
index dcd505a105e..c8430380345 100644
--- a/compiler/rustc_macros/src/type_visitable.rs
+++ b/compiler/rustc_macros/src/type_visitable.rs
@@ -6,6 +6,8 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:
         panic!("cannot derive on union")
     }
 
+    s.underscore_const(true);
+
     // ignore fields with #[type_visitable(ignore)]
     s.filter(|bi| {
         let mut ignored = false;
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 45f6e375e89..85740dce866 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -396,6 +396,7 @@ pub trait AsMut<T: ?Sized> {
 /// For example, take this code:
 ///
 /// ```
+/// # #![cfg_attr(not(bootstrap), allow(non_local_definitions))]
 /// struct Wrapper<T>(Vec<T>);
 /// impl<T> From<Wrapper<T>> for Vec<T> {
 ///     fn from(w: Wrapper<T>) -> Vec<T> {
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 153971a59c5..bfdd28a7399 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -454,6 +454,7 @@ pub trait Hasher {
     /// ```
     /// #![feature(hasher_prefixfree_extras)]
     /// # // Stubs to make the `impl` below pass the compiler
+    /// # #![cfg_attr(not(bootstrap), allow(non_local_definitions))]
     /// # struct MyCollection<T>(Option<T>);
     /// # impl<T> MyCollection<T> {
     /// #     fn len(&self) -> usize { todo!() }
diff --git a/library/core/tests/iter/adapters/step_by.rs b/library/core/tests/iter/adapters/step_by.rs
index b4d61d28cb2..29adf0b42fa 100644
--- a/library/core/tests/iter/adapters/step_by.rs
+++ b/library/core/tests/iter/adapters/step_by.rs
@@ -49,6 +49,7 @@ fn test_iterator_step_by_nth() {
 }
 
 #[test]
+#[cfg_attr(not(bootstrap), allow(non_local_definitions))]
 fn test_iterator_step_by_nth_overflow() {
     #[cfg(target_pointer_width = "16")]
     type Bigger = u32;
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index 6c008ab2cb1..d02dc45da34 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -195,6 +195,7 @@ pub fn test_unwrap_or_default() {
 }
 
 #[test]
+#[cfg_attr(not(bootstrap), allow(non_local_definitions))]
 pub fn test_into_ok() {
     fn infallible_op() -> Result<isize, !> {
         Ok(666)
@@ -217,6 +218,7 @@ pub fn test_into_ok() {
 }
 
 #[test]
+#[cfg_attr(not(bootstrap), allow(non_local_definitions))]
 pub fn test_into_err() {
     fn until_error_op() -> Result<!, isize> {
         Err(666)
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 09a90b62d97..caad56146a7 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1207,6 +1207,13 @@ impl Tester for Collector {
     }
 }
 
+#[cfg(test)] // used in tests
+impl Tester for Vec<usize> {
+    fn add_test(&mut self, _test: String, _config: LangString, line: usize) {
+        self.push(line);
+    }
+}
+
 struct HirCollector<'a, 'hir, 'tcx> {
     sess: &'a Session,
     collector: &'a mut Collector,
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index 4dd176b3a69..1de97e49b83 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -480,11 +480,6 @@ fn test_markdown_html_escape() {
 #[test]
 fn test_find_testable_code_line() {
     fn t(input: &str, expect: &[usize]) {
-        impl crate::doctest::Tester for Vec<usize> {
-            fn add_test(&mut self, _test: String, _config: LangString, line: usize) {
-                self.push(line);
-            }
-        }
         let mut lines = Vec::<usize>::new();
         find_testable_code(input, &mut lines, ErrorCodes::No, false, None, true);
         assert_eq!(lines, expect);
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index a2781398760..8997073c8a5 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -4,7 +4,7 @@
 //@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled
 
 #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
-#![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)]
+#![allow(deref_nullptr, non_local_definitions, clippy::let_unit_value, clippy::missing_safety_doc)]
 #![feature(lint_reasons)]
 
 extern crate proc_macro_unsafe;
diff --git a/src/tools/clippy/tests/ui/bool_comparison.fixed b/src/tools/clippy/tests/ui/bool_comparison.fixed
index 02f1d09b833..600380fd142 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.fixed
+++ b/src/tools/clippy/tests/ui/bool_comparison.fixed
@@ -1,4 +1,4 @@
-#![allow(clippy::needless_if)]
+#![allow(non_local_definitions, clippy::needless_if)]
 #![warn(clippy::bool_comparison)]
 #![allow(clippy::non_canonical_partial_ord_impl)]
 
diff --git a/src/tools/clippy/tests/ui/bool_comparison.rs b/src/tools/clippy/tests/ui/bool_comparison.rs
index 5ef696d855e..910df6151f8 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.rs
+++ b/src/tools/clippy/tests/ui/bool_comparison.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::needless_if)]
+#![allow(non_local_definitions, clippy::needless_if)]
 #![warn(clippy::bool_comparison)]
 #![allow(clippy::non_canonical_partial_ord_impl)]
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-4760.rs b/src/tools/clippy/tests/ui/crashes/ice-4760.rs
index 08b06961760..e1265169762 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-4760.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-4760.rs
@@ -1,3 +1,5 @@
+#![allow(non_local_definitions)]
+
 const COUNT: usize = 2;
 struct Thing;
 trait Dummy {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6179.rs b/src/tools/clippy/tests/ui/crashes/ice-6179.rs
index ce1895851e2..fffc0f7d0d4 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6179.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6179.rs
@@ -3,6 +3,7 @@
 
 #![warn(clippy::use_self)]
 #![allow(dead_code, clippy::let_with_type_underscore)]
+#![allow(non_local_definitions)]
 
 struct Foo;
 
diff --git a/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed
index 2521bce6a58..6d67488a713 100644
--- a/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed
@@ -1,3 +1,4 @@
+#![allow(non_local_definitions)]
 #![warn(clippy::explicit_into_iter_loop)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs
index 9eac96d182b..14630c07c5c 100644
--- a/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs
@@ -1,3 +1,4 @@
+#![allow(non_local_definitions)]
 #![warn(clippy::explicit_into_iter_loop)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr b/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr
index c03647ab433..a1e632271ed 100644
--- a/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr
+++ b/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr
@@ -1,5 +1,5 @@
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/explicit_into_iter_loop.rs:9:18
+  --> $DIR/explicit_into_iter_loop.rs:10:18
    |
 LL |         for _ in iterator.into_iter() {}
    |                  ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`
@@ -8,31 +8,31 @@ LL |         for _ in iterator.into_iter() {}
    = help: to override `-D warnings` add `#[allow(clippy::explicit_into_iter_loop)]`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/explicit_into_iter_loop.rs:22:14
+  --> $DIR/explicit_into_iter_loop.rs:23:14
    |
 LL |     for _ in t.into_iter() {}
    |              ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/explicit_into_iter_loop.rs:25:14
+  --> $DIR/explicit_into_iter_loop.rs:26:14
    |
 LL |     for _ in r.into_iter() {}
    |              ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/explicit_into_iter_loop.rs:33:14
+  --> $DIR/explicit_into_iter_loop.rs:34:14
    |
 LL |     for _ in mr.into_iter() {}
    |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*mr`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/explicit_into_iter_loop.rs:45:14
+  --> $DIR/explicit_into_iter_loop.rs:46:14
    |
 LL |     for _ in u.into_iter() {}
    |              ^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut u`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/explicit_into_iter_loop.rs:48:14
+  --> $DIR/explicit_into_iter_loop.rs:49:14
    |
 LL |     for _ in mr.into_iter() {}
    |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr`
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index f08397defa5..06229a52a18 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -5,7 +5,8 @@
     clippy::needless_borrow,
     clippy::deref_addrof,
     clippy::unnecessary_mut_passed,
-    dead_code
+    dead_code,
+    non_local_definitions,
 )]
 
 use core::slice;
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index 2ee6825d445..c2bf45ab2e9 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -5,7 +5,8 @@
     clippy::needless_borrow,
     clippy::deref_addrof,
     clippy::unnecessary_mut_passed,
-    dead_code
+    dead_code,
+    non_local_definitions,
 )]
 
 use core::slice;
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.stderr b/src/tools/clippy/tests/ui/explicit_iter_loop.stderr
index 725d9b63cf8..007606b52c2 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.stderr
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.stderr
@@ -1,5 +1,5 @@
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:17:14
+  --> $DIR/explicit_iter_loop.rs:18:14
    |
 LL |     for _ in vec.iter() {}
    |              ^^^^^^^^^^ help: to write this more concisely, try: `&vec`
@@ -11,103 +11,103 @@ LL | #![deny(clippy::explicit_iter_loop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:18:14
+  --> $DIR/explicit_iter_loop.rs:19:14
    |
 LL |     for _ in vec.iter_mut() {}
    |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:21:14
+  --> $DIR/explicit_iter_loop.rs:22:14
    |
 LL |     for _ in rvec.iter() {}
    |              ^^^^^^^^^^^ help: to write this more concisely, try: `rvec`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:30:14
+  --> $DIR/explicit_iter_loop.rs:31:14
    |
 LL |     for _ in [1, 2, 3].iter() {}
    |              ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:34:14
+  --> $DIR/explicit_iter_loop.rs:35:14
    |
 LL |     for _ in [0; 32].iter() {}
    |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:35:14
+  --> $DIR/explicit_iter_loop.rs:36:14
    |
 LL |     for _ in [0; 33].iter() {}
    |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 33]`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:38:14
+  --> $DIR/explicit_iter_loop.rs:39:14
    |
 LL |     for _ in ll.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&ll`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:40:14
+  --> $DIR/explicit_iter_loop.rs:41:14
    |
 LL |     for _ in rll.iter() {}
    |              ^^^^^^^^^^ help: to write this more concisely, try: `rll`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:43:14
+  --> $DIR/explicit_iter_loop.rs:44:14
    |
 LL |     for _ in vd.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&vd`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:45:14
+  --> $DIR/explicit_iter_loop.rs:46:14
    |
 LL |     for _ in rvd.iter() {}
    |              ^^^^^^^^^^ help: to write this more concisely, try: `rvd`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:48:14
+  --> $DIR/explicit_iter_loop.rs:49:14
    |
 LL |     for _ in bh.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&bh`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:51:14
+  --> $DIR/explicit_iter_loop.rs:52:14
    |
 LL |     for _ in hm.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&hm`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:54:14
+  --> $DIR/explicit_iter_loop.rs:55:14
    |
 LL |     for _ in bt.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&bt`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:57:14
+  --> $DIR/explicit_iter_loop.rs:58:14
    |
 LL |     for _ in hs.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&hs`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:60:14
+  --> $DIR/explicit_iter_loop.rs:61:14
    |
 LL |     for _ in bs.iter() {}
    |              ^^^^^^^^^ help: to write this more concisely, try: `&bs`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:149:14
+  --> $DIR/explicit_iter_loop.rs:150:14
    |
 LL |     for _ in x.iter() {}
    |              ^^^^^^^^ help: to write this more concisely, try: `&x`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:150:14
+  --> $DIR/explicit_iter_loop.rs:151:14
    |
 LL |     for _ in x.iter_mut() {}
    |              ^^^^^^^^^^^^ help: to write this more concisely, try: `&mut x`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/explicit_iter_loop.rs:153:14
+  --> $DIR/explicit_iter_loop.rs:154:14
    |
 LL |     for _ in r.iter() {}
    |              ^^^^^^^^ help: to write this more concisely, try: `r`
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index 4a68505ee0b..a33c1ea5738 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -1,5 +1,6 @@
 #![feature(type_alias_impl_trait)]
 #![warn(clippy::from_over_into)]
+#![allow(non_local_definitions)]
 #![allow(unused)]
 
 // this should throw an error
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index bf3ed0c2b64..6cd811ae401 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -1,5 +1,6 @@
 #![feature(type_alias_impl_trait)]
 #![warn(clippy::from_over_into)]
+#![allow(non_local_definitions)]
 #![allow(unused)]
 
 // this should throw an error
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index f1370ed844f..15b4e02a264 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -1,5 +1,5 @@
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:8:1
+  --> $DIR/from_over_into.rs:9:1
    |
 LL | impl Into<StringWrapper> for String {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -14,7 +14,7 @@ LL ~         StringWrapper(val)
    |
 
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:16:1
+  --> $DIR/from_over_into.rs:17:1
    |
 LL | impl Into<SelfType> for String {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL ~         SelfType(String::new())
    |
 
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:31:1
+  --> $DIR/from_over_into.rs:32:1
    |
 LL | impl Into<SelfKeywords> for X {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL ~         let _: X = val;
    |
 
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:43:1
+  --> $DIR/from_over_into.rs:44:1
    |
 LL | impl core::convert::Into<bool> for crate::ExplicitPaths {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL ~         val.0
    |
 
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:63:1
+  --> $DIR/from_over_into.rs:64:1
    |
 LL | impl Into<String> for PathInExpansion {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -74,7 +74,7 @@ LL ~     fn from(val: PathInExpansion) -> Self {
    |
 
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:85:5
+  --> $DIR/from_over_into.rs:86:5
    |
 LL |     impl<T> Into<FromOverInto<T>> for Vec<T> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL ~             FromOverInto(val)
    |
 
 error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
-  --> $DIR/from_over_into.rs:95:5
+  --> $DIR/from_over_into.rs:96:5
    |
 LL |     impl Into<()> for Hello {
    |     ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.fixed b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
index 888a466278c..5f2f1bd9916 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.fixed
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
@@ -1,3 +1,4 @@
+#![allow(non_local_definitions)]
 #![warn(clippy::manual_str_repeat)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.rs b/src/tools/clippy/tests/ui/manual_str_repeat.rs
index a366351ffa4..3e3c7f4db4a 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.rs
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.rs
@@ -1,3 +1,4 @@
+#![allow(non_local_definitions)]
 #![warn(clippy::manual_str_repeat)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.stderr b/src/tools/clippy/tests/ui/manual_str_repeat.stderr
index 9a13aa97227..6eb6f2b85a8 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.stderr
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.stderr
@@ -1,5 +1,5 @@
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:7:21
+  --> $DIR/manual_str_repeat.rs:8:21
    |
 LL |     let _: String = std::iter::repeat("test").take(10).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)`
@@ -8,55 +8,55 @@ LL |     let _: String = std::iter::repeat("test").take(10).collect();
    = help: to override `-D warnings` add `#[allow(clippy::manual_str_repeat)]`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:8:21
+  --> $DIR/manual_str_repeat.rs:9:21
    |
 LL |     let _: String = std::iter::repeat('x').take(10).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"x".repeat(10)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:9:21
+  --> $DIR/manual_str_repeat.rs:10:21
    |
 LL |     let _: String = std::iter::repeat('\'').take(10).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"'".repeat(10)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:10:21
+  --> $DIR/manual_str_repeat.rs:11:21
    |
 LL |     let _: String = std::iter::repeat('"').take(10).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"\"".repeat(10)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:14:13
+  --> $DIR/manual_str_repeat.rs:15:13
    |
 LL |     let _ = repeat(x).take(count + 2).collect::<String>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count + 2)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:23:21
+  --> $DIR/manual_str_repeat.rs:24:21
    |
 LL |     let _: String = repeat(*x).take(count).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*x).repeat(count)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:32:21
+  --> $DIR/manual_str_repeat.rs:33:21
    |
 LL |     let _: String = repeat(x).take(count).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:44:21
+  --> $DIR/manual_str_repeat.rs:45:21
    |
 LL |     let _: String = repeat(Cow::Borrowed("test")).take(count).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Cow::Borrowed("test").repeat(count)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:47:21
+  --> $DIR/manual_str_repeat.rs:48:21
    |
 LL |     let _: String = repeat(x).take(count).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)`
 
 error: manual implementation of `str::repeat` using iterators
-  --> $DIR/manual_str_repeat.rs:62:21
+  --> $DIR/manual_str_repeat.rs:63:21
    |
 LL |     let _: String = std::iter::repeat("test").take(10).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)`
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index 23e8bf8a468..998f5430fdf 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -1,6 +1,7 @@
 #![feature(lint_reasons)]
 #![allow(
     unused,
+    non_local_definitions,
     clippy::uninlined_format_args,
     clippy::unnecessary_mut_passed,
     clippy::unnecessary_to_owned,
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 27771a8f15b..acb2c74d849 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -1,6 +1,7 @@
 #![feature(lint_reasons)]
 #![allow(
     unused,
+    non_local_definitions,
     clippy::uninlined_format_args,
     clippy::unnecessary_mut_passed,
     clippy::unnecessary_to_owned,
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index a21ed8382c1..9034bd83a0b 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -1,5 +1,5 @@
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:15:15
+  --> $DIR/needless_borrow.rs:16:15
    |
 LL |     let _ = x(&&a); // warn
    |               ^^^ help: change this to: `&a`
@@ -8,157 +8,157 @@ LL |     let _ = x(&&a); // warn
    = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:19:13
+  --> $DIR/needless_borrow.rs:20:13
    |
 LL |     mut_ref(&mut &mut b); // warn
    |             ^^^^^^^^^^^ help: change this to: `&mut b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:31:13
+  --> $DIR/needless_borrow.rs:32:13
    |
 LL |             &&a
    |             ^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:33:15
+  --> $DIR/needless_borrow.rs:34:15
    |
 LL |         46 => &&a,
    |               ^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:39:27
+  --> $DIR/needless_borrow.rs:40:27
    |
 LL |                     break &ref_a;
    |                           ^^^^^^ help: change this to: `ref_a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:46:15
+  --> $DIR/needless_borrow.rs:47:15
    |
 LL |     let _ = x(&&&a);
    |               ^^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:47:15
+  --> $DIR/needless_borrow.rs:48:15
    |
 LL |     let _ = x(&mut &&a);
    |               ^^^^^^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:48:15
+  --> $DIR/needless_borrow.rs:49:15
    |
 LL |     let _ = x(&&&mut b);
    |               ^^^^^^^^ help: change this to: `&mut b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:49:15
+  --> $DIR/needless_borrow.rs:50:15
    |
 LL |     let _ = x(&&ref_a);
    |               ^^^^^^^ help: change this to: `ref_a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:52:11
+  --> $DIR/needless_borrow.rs:53:11
    |
 LL |         x(&b);
    |           ^^ help: change this to: `b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:59:13
+  --> $DIR/needless_borrow.rs:60:13
    |
 LL |     mut_ref(&mut x);
    |             ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:60:13
+  --> $DIR/needless_borrow.rs:61:13
    |
 LL |     mut_ref(&mut &mut x);
    |             ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:61:23
+  --> $DIR/needless_borrow.rs:62:23
    |
 LL |     let y: &mut i32 = &mut x;
    |                       ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:62:23
+  --> $DIR/needless_borrow.rs:63:23
    |
 LL |     let y: &mut i32 = &mut &mut x;
    |                       ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:71:14
+  --> $DIR/needless_borrow.rs:72:14
    |
 LL |         0 => &mut x,
    |              ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:77:14
+  --> $DIR/needless_borrow.rs:78:14
    |
 LL |         0 => &mut x,
    |              ^^^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:89:13
+  --> $DIR/needless_borrow.rs:90:13
    |
 LL |     let _ = (&x).0;
    |             ^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:91:22
+  --> $DIR/needless_borrow.rs:92:22
    |
 LL |     let _ = unsafe { (&*x).0 };
    |                      ^^^^^ help: change this to: `(*x)`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:101:5
+  --> $DIR/needless_borrow.rs:102:5
    |
 LL |     (&&()).foo();
    |     ^^^^^^ help: change this to: `(&())`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:110:5
+  --> $DIR/needless_borrow.rs:111:5
    |
 LL |     (&&5).foo();
    |     ^^^^^ help: change this to: `(&5)`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:136:23
+  --> $DIR/needless_borrow.rs:137:23
    |
 LL |     let x: (&str,) = (&"",);
    |                       ^^^ help: change this to: `""`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:178:13
+  --> $DIR/needless_borrow.rs:179:13
    |
 LL |             (&self.f)()
    |             ^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:187:13
+  --> $DIR/needless_borrow.rs:188:13
    |
 LL |             (&mut self.f)()
    |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:224:22
+  --> $DIR/needless_borrow.rs:225:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:231:22
+  --> $DIR/needless_borrow.rs:232:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:235:22
+  --> $DIR/needless_borrow.rs:236:22
    |
 LL |         let _ = &mut (&mut x.u).x;
    |                      ^^^^^^^^^^ help: change this to: `x.u`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:236:22
+  --> $DIR/needless_borrow.rs:237:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
diff --git a/src/tools/rustfmt/src/source_file.rs b/src/tools/rustfmt/src/source_file.rs
index 958f9b0154f..512a8593c27 100644
--- a/src/tools/rustfmt/src/source_file.rs
+++ b/src/tools/rustfmt/src/source_file.rs
@@ -66,6 +66,7 @@ where
         }
     }
 
+    #[cfg_attr(not(bootstrap), allow(non_local_definitions))]
     impl From<&FileName> for rustc_span::FileName {
         fn from(filename: &FileName) -> rustc_span::FileName {
             match filename {
diff --git a/tests/ui/async-await/async-assoc-fn-anon-lifetimes.rs b/tests/ui/async-await/async-assoc-fn-anon-lifetimes.rs
index 28705bfc0c8..1a2aae8fb23 100644
--- a/tests/ui/async-await/async-assoc-fn-anon-lifetimes.rs
+++ b/tests/ui/async-await/async-assoc-fn-anon-lifetimes.rs
@@ -5,6 +5,8 @@
 
 //@ edition:2018
 
+#![allow(non_local_definitions)]
+
 struct A<'a, 'b>(&'a &'b i32);
 struct B<'a>(&'a i32);
 
diff --git a/tests/ui/const-generics/min_const_generics/macro.rs b/tests/ui/const-generics/min_const_generics/macro.rs
index b7e8083a861..52f47628f8f 100644
--- a/tests/ui/const-generics/min_const_generics/macro.rs
+++ b/tests/ui/const-generics/min_const_generics/macro.rs
@@ -1,4 +1,6 @@
 //@ run-pass
+#![allow(non_local_definitions)]
+
 struct Example<const N: usize>;
 
 macro_rules! external_macro {
diff --git a/tests/ui/consts/const_in_pattern/accept_structural.rs b/tests/ui/consts/const_in_pattern/accept_structural.rs
index 09142c56157..31d3b6e7331 100644
--- a/tests/ui/consts/const_in_pattern/accept_structural.rs
+++ b/tests/ui/consts/const_in_pattern/accept_structural.rs
@@ -1,5 +1,6 @@
 //@ run-pass
 
+#![allow(non_local_definitions)]
 #![warn(indirect_structural_match)]
 
 // This test is checking our logic for structural match checking by enumerating
diff --git a/tests/ui/drop/dropck-eyepatch-reorder.rs b/tests/ui/drop/dropck-eyepatch-reorder.rs
index 6b394414bae..b985beee9ec 100644
--- a/tests/ui/drop/dropck-eyepatch-reorder.rs
+++ b/tests/ui/drop/dropck-eyepatch-reorder.rs
@@ -1,5 +1,6 @@
 //@ run-pass
 #![feature(dropck_eyepatch)]
+#![allow(non_local_definitions)]
 
 // The point of this test is to test uses of `#[may_dangle]` attribute
 // where the formal declaration order (in the impl generics) does not
diff --git a/tests/ui/drop/dropck-eyepatch.rs b/tests/ui/drop/dropck-eyepatch.rs
index 2f27b72da5a..2dffe6aba17 100644
--- a/tests/ui/drop/dropck-eyepatch.rs
+++ b/tests/ui/drop/dropck-eyepatch.rs
@@ -1,5 +1,6 @@
 //@ run-pass
 #![feature(dropck_eyepatch)]
+#![allow(non_local_definitions)]
 
 // The point of this test is to illustrate that the `#[may_dangle]`
 // attribute specifically allows, in the context of a type
diff --git a/tests/ui/imports/local-modularized-tricky-pass-2.rs b/tests/ui/imports/local-modularized-tricky-pass-2.rs
index 581bab467f5..1cf97c5aa06 100644
--- a/tests/ui/imports/local-modularized-tricky-pass-2.rs
+++ b/tests/ui/imports/local-modularized-tricky-pass-2.rs
@@ -4,6 +4,7 @@
 // into the root module soon enough to act as usual items and shadow globs and preludes.
 
 #![feature(decl_macro)]
+#![allow(non_local_definitions)]
 
 // `macro_export` shadows globs
 use inner1::*;
diff --git a/tests/ui/issues/issue-31776.rs b/tests/ui/issues/issue-31776.rs
index 632defbcf27..4b342a0e3b2 100644
--- a/tests/ui/issues/issue-31776.rs
+++ b/tests/ui/issues/issue-31776.rs
@@ -1,6 +1,7 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
+#![allow(non_local_definitions)]
 // Various scenarios in which `pub` is required in blocks
 
 struct S;
diff --git a/tests/ui/issues/issue-41053.rs b/tests/ui/issues/issue-41053.rs
index f46bf6b4aa1..18f9e209c33 100644
--- a/tests/ui/issues/issue-41053.rs
+++ b/tests/ui/issues/issue-41053.rs
@@ -1,6 +1,8 @@
 //@ run-pass
 //@ aux-build:issue-41053.rs
 
+#![allow(non_local_definitions)]
+
 pub trait Trait { fn foo(&self) {} }
 
 pub struct Foo;
diff --git a/tests/ui/lint/auxiliary/non_local_macro.rs b/tests/ui/lint/auxiliary/non_local_macro.rs
new file mode 100644
index 00000000000..8c0ff8adda1
--- /dev/null
+++ b/tests/ui/lint/auxiliary/non_local_macro.rs
@@ -0,0 +1,26 @@
+#[macro_export]
+macro_rules! non_local_impl {
+    ($a:ident) => {
+        const _IMPL_DEBUG: () = {
+            impl ::std::fmt::Debug for $a {
+                fn fmt(&self, _: &mut ::std::fmt::Formatter<'_>)
+                    -> ::std::result::Result<(), ::std::fmt::Error>
+                {
+                    todo!()
+                }
+            }
+        };
+    }
+}
+
+#[macro_export]
+macro_rules! non_local_macro_rules {
+    ($a:ident) => {
+        const _MACRO_EXPORT: () = {
+            #[macro_export]
+            macro_rules! $a {
+                () => {}
+            }
+        };
+    }
+}
diff --git a/tests/ui/lint/non_local_definitions.rs b/tests/ui/lint/non_local_definitions.rs
new file mode 100644
index 00000000000..c9aaa049346
--- /dev/null
+++ b/tests/ui/lint/non_local_definitions.rs
@@ -0,0 +1,385 @@
+//@ check-pass
+//@ edition:2021
+//@ aux-build:non_local_macro.rs
+//@ rustc-env:CARGO=/usr/bin/cargo
+
+#![feature(inline_const)]
+
+extern crate non_local_macro;
+
+use std::fmt::{Debug, Display};
+
+struct Test;
+
+impl Debug for Test {
+    fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        todo!()
+    }
+}
+
+mod do_not_lint_mod {
+    pub trait Tait {}
+
+    impl super::Test {
+        fn hugo() {}
+    }
+
+    impl Tait for super::Test {}
+}
+
+trait Uto {}
+const Z: () = {
+    trait Uto1 {}
+
+    impl Uto1 for Test {} // the trait is local, don't lint
+
+    impl Uto for &Test {}
+    //~^ WARN non-local `impl` definition
+};
+
+trait Ano {}
+const _: () = {
+    impl Ano for &Test {} // ignored since the parent is an anon-const
+};
+
+type A = [u32; {
+    impl Uto for *mut Test {}
+    //~^ WARN non-local `impl` definition
+
+    1
+}];
+
+enum Enum {
+    Discr = {
+        impl Uto for Test {}
+        //~^ WARN non-local `impl` definition
+
+        1
+    }
+}
+
+trait Uto2 {}
+static A: u32 = {
+    impl Uto2 for Test {}
+    //~^ WARN non-local `impl` definition
+
+    1
+};
+
+trait Uto3 {}
+const B: u32 = {
+    impl Uto3 for Test {}
+    //~^ WARN non-local `impl` definition
+
+    #[macro_export]
+    macro_rules! m0 { () => { } };
+    //~^ WARN non-local `macro_rules!` definition
+
+    trait Uto4 {}
+    impl Uto4 for Test {}
+
+    1
+};
+
+trait Uto5 {}
+fn main() {
+    #[macro_export]
+    macro_rules! m { () => { } };
+    //~^ WARN non-local `macro_rules!` definition
+
+    impl Test {
+    //~^ WARN non-local `impl` definition
+        fn foo() {}
+    }
+
+    let _array = [0i32; {
+        impl Test {
+        //~^ WARN non-local `impl` definition
+            fn bar() {}
+        }
+
+        1
+    }];
+
+    const {
+        impl Test {
+        //~^ WARN non-local `impl` definition
+            fn hoo() {}
+        }
+
+        1
+    };
+
+    const _: u32 = {
+        impl Test {
+        //~^ WARN non-local `impl` definition
+            fn foo2() {}
+        }
+
+        1
+    };
+
+    impl Display for Test {
+    //~^ WARN non-local `impl` definition
+        fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            todo!()
+        }
+    }
+
+    impl dyn Uto5 {}
+    //~^ WARN non-local `impl` definition
+
+    impl<T: Uto5> Uto5 for Vec<T> { }
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for &dyn Uto5 {}
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for *mut Test {}
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for *mut [Test] {}
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for [Test; 8] {}
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for (Test,) {}
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for fn(Test) -> () {}
+    //~^ WARN non-local `impl` definition
+
+    impl Uto5 for fn() -> Test {}
+    //~^ WARN non-local `impl` definition
+
+    let _a = || {
+        impl Uto5 for Test {}
+        //~^ WARN non-local `impl` definition
+
+        1
+    };
+
+    type A = [u32; {
+        impl Uto5 for &Test {}
+        //~^ WARN non-local `impl` definition
+
+        1
+    }];
+
+    fn a(_: [u32; {
+        impl Uto5 for &(Test,) {}
+        //~^ WARN non-local `impl` definition
+
+        1
+    }]) {}
+
+    fn b() -> [u32; {
+        impl Uto5 for &(Test,Test) {}
+        //~^ WARN non-local `impl` definition
+
+        1
+    }] { todo!() }
+
+    struct InsideMain;
+
+    impl Uto5 for *mut InsideMain {}
+    //~^ WARN non-local `impl` definition
+    impl Uto5 for *mut [InsideMain] {}
+    //~^ WARN non-local `impl` definition
+    impl Uto5 for [InsideMain; 8] {}
+    //~^ WARN non-local `impl` definition
+    impl Uto5 for (InsideMain,) {}
+    //~^ WARN non-local `impl` definition
+    impl Uto5 for fn(InsideMain) -> () {}
+    //~^ WARN non-local `impl` definition
+    impl Uto5 for fn() -> InsideMain {}
+    //~^ WARN non-local `impl` definition
+
+    impl Debug for InsideMain {
+        fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            todo!()
+        }
+    }
+
+    impl InsideMain {
+        fn foo() {}
+    }
+
+    fn inside_inside() {
+        impl Display for InsideMain {
+        //~^ WARN non-local `impl` definition
+            fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                todo!()
+            }
+        }
+
+        impl InsideMain {
+        //~^ WARN non-local `impl` definition
+            fn bar() {
+                #[macro_export]
+                macro_rules! m2 { () => { } };
+                //~^ WARN non-local `macro_rules!` definition
+            }
+        }
+    }
+
+    trait Uto6 {}
+    impl dyn Uto6 {}
+    impl Uto5 for dyn Uto6 {}
+
+    impl<T: Uto6> Uto3 for Vec<T> { }
+    //~^ WARN non-local `impl` definition
+}
+
+trait Uto7 {}
+trait Uto8 {}
+
+fn bad() {
+    struct Local;
+    impl Uto7 for Test where Local: std::any::Any {}
+    //~^ WARN non-local `impl` definition
+
+    impl<T> Uto8 for T {}
+    //~^ WARN non-local `impl` definition
+}
+
+struct UwU<T>(T);
+
+fn fun() {
+    #[derive(Debug)]
+    struct OwO;
+    impl Default for UwU<OwO> {
+    //~^ WARN non-local `impl` definition
+        fn default() -> Self {
+            UwU(OwO)
+        }
+    }
+}
+
+struct Cat;
+
+fn meow() {
+    impl From<Cat> for () {
+    //~^ WARN non-local `impl` definition
+        fn from(_: Cat) -> () {
+            todo!()
+        }
+    }
+
+    #[derive(Debug)]
+    struct Cat;
+    impl AsRef<Cat> for () {
+    //~^ WARN non-local `impl` definition
+        fn as_ref(&self) -> &Cat { &Cat }
+    }
+}
+
+struct G;
+
+fn fun2() {
+    #[derive(Debug, Default)]
+    struct B;
+    impl PartialEq<B> for G {
+    //~^ WARN non-local `impl` definition
+        fn eq(&self, _: &B) -> bool {
+            true
+        }
+    }
+}
+
+fn side_effects() {
+    dbg!(().as_ref()); // prints `Cat`
+    dbg!(UwU::default().0);
+    let _ = G::eq(&G, dbg!(&<_>::default()));
+}
+
+struct Dog;
+
+fn woof() {
+    impl PartialEq<Dog> for &Dog {
+    //~^ WARN non-local `impl` definition
+        fn eq(&self, _: &Dog) -> bool {
+            todo!()
+        }
+    }
+
+    impl PartialEq<()> for Dog {
+    //~^ WARN non-local `impl` definition
+        fn eq(&self, _: &()) -> bool {
+            todo!()
+        }
+    }
+
+    impl PartialEq<()> for &Dog {
+    //~^ WARN non-local `impl` definition
+        fn eq(&self, _: &()) -> bool {
+            todo!()
+        }
+    }
+
+    impl PartialEq<Dog> for () {
+    //~^ WARN non-local `impl` definition
+        fn eq(&self, _: &Dog) -> bool {
+            todo!()
+        }
+    }
+
+    struct Test;
+    impl PartialEq<Dog> for Test {
+        fn eq(&self, _: &Dog) -> bool {
+            todo!()
+        }
+    }
+}
+
+struct Wrap<T>(T);
+
+impl Wrap<Wrap<Wrap<()>>> {}
+
+fn rawr() {
+    struct Lion;
+
+    impl From<Wrap<Wrap<Lion>>> for () {
+    //~^ WARN non-local `impl` definition
+        fn from(_: Wrap<Wrap<Lion>>) -> Self {
+            todo!()
+        }
+    }
+
+    impl From<()> for Wrap<Lion> {
+    //~^ WARN non-local `impl` definition
+        fn from(_: ()) -> Self {
+            todo!()
+        }
+    }
+}
+
+macro_rules! m {
+    () => {
+        trait MacroTrait {}
+        struct OutsideStruct;
+        fn my_func() {
+            impl MacroTrait for OutsideStruct {}
+            //~^ WARN non-local `impl` definition
+        }
+    }
+}
+
+m!();
+
+struct CargoUpdate;
+
+non_local_macro::non_local_impl!(CargoUpdate);
+//~^ WARN non-local `impl` definition
+
+non_local_macro::non_local_macro_rules!(my_macro);
+//~^ WARN non-local `macro_rules!` definition
+
+fn bitflags() {
+    struct Flags;
+
+    const _: () = {
+        impl Flags {}
+    };
+}
diff --git a/tests/ui/lint/non_local_definitions.stderr b/tests/ui/lint/non_local_definitions.stderr
new file mode 100644
index 00000000000..f9f29ec63a8
--- /dev/null
+++ b/tests/ui/lint/non_local_definitions.stderr
@@ -0,0 +1,640 @@
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:36:5
+   |
+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: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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: `#[warn(non_local_definitions)]` on by default
+
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:46:5
+   |
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:54:9
+   |
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:63:5
+   |
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:71:5
+   |
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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 `macro_rules!` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:75:5
+   |
+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>
+
+warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:87:5
+   |
+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 `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:90:5
+   |
+LL | /     impl Test {
+LL | |
+LL | |         fn foo() {}
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:96:9
+   |
+LL | /         impl Test {
+LL | |
+LL | |             fn bar() {}
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:105:9
+   |
+LL | /         impl Test {
+LL | |
+LL | |             fn hoo() {}
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:114:9
+   |
+LL | /         impl Test {
+LL | |
+LL | |             fn foo2() {}
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:122:5
+   |
+LL | /     impl Display for Test {
+LL | |
+LL | |         fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+LL | |             todo!()
+LL | |         }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:129:5
+   |
+LL |     impl dyn Uto5 {}
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:132:5
+   |
+LL |     impl<T: Uto5> Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:135:5
+   |
+LL |     impl Uto5 for &dyn Uto5 {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:138:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:141:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:144:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:147:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:150:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:153:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:157:9
+   |
+LL |         impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:164:9
+   |
+LL |         impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:171:9
+   |
+LL |         impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:178:9
+   |
+LL |         impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:186:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:188:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:190:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:192:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:194:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:196:5
+   |
+LL |     impl Uto5 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:210:9
+   |
+LL | /         impl Display for InsideMain {
+LL | |
+LL | |             fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+LL | |                 todo!()
+LL | |             }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:217:9
+   |
+LL | /         impl InsideMain {
+LL | |
+LL | |             fn bar() {
+LL | |                 #[macro_export]
+...  |
+LL | |             }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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 `macro_rules!` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:221:17
+   |
+LL |                 macro_rules! m2 { () => { } };
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current associated function `bar` and up 3 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: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:231:5
+   |
+LL |     impl<T: Uto6> Uto3 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:240:5
+   |
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:243:5
+   |
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:252:5
+   |
+LL | /     impl Default for UwU<OwO> {
+LL | |
+LL | |         fn default() -> Self {
+LL | |             UwU(OwO)
+LL | |         }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:263:5
+   |
+LL | /     impl From<Cat> for () {
+LL | |
+LL | |         fn from(_: Cat) -> () {
+LL | |             todo!()
+LL | |         }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:272:5
+   |
+LL | /     impl AsRef<Cat> for () {
+LL | |
+LL | |         fn as_ref(&self) -> &Cat { &Cat }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:283:5
+   |
+LL | /     impl PartialEq<B> for G {
+LL | |
+LL | |         fn eq(&self, _: &B) -> bool {
+LL | |             true
+LL | |         }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:300:5
+   |
+LL | /     impl PartialEq<Dog> for &Dog {
+LL | |
+LL | |         fn eq(&self, _: &Dog) -> bool {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `woof`
+   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:307:5
+   |
+LL | /     impl PartialEq<()> for Dog {
+LL | |
+LL | |         fn eq(&self, _: &()) -> bool {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `woof`
+   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:314:5
+   |
+LL | /     impl PartialEq<()> for &Dog {
+LL | |
+LL | |         fn eq(&self, _: &()) -> bool {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `woof`
+   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:321:5
+   |
+LL | /     impl PartialEq<Dog> for () {
+LL | |
+LL | |         fn eq(&self, _: &Dog) -> bool {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `woof`
+   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:343:5
+   |
+LL | /     impl From<Wrap<Wrap<Lion>>> for () {
+LL | |
+LL | |         fn from(_: Wrap<Wrap<Lion>>) -> Self {
+LL | |             todo!()
+LL | |         }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:350:5
+   |
+LL | /     impl From<()> for Wrap<Lion> {
+LL | |
+LL | |         fn from(_: ()) -> Self {
+LL | |             todo!()
+LL | |         }
+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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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
+  --> $DIR/non_local_definitions.rs:363:13
+   |
+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: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:373:1
+   |
+LL | non_local_macro::non_local_impl!(CargoUpdate);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 neither the type nor the trait are at the same nesting level as the `impl` block
+   = 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: 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: this warning originates in the macro `non_local_macro::non_local_impl` (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
+  --> $DIR/non_local_definitions.rs:376:1
+   |
+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)
+
+warning: 50 warnings emitted
+
diff --git a/tests/ui/macros/type-macros-simple.rs b/tests/ui/macros/type-macros-simple.rs
index 4d1001baf59..d189b881f7d 100644
--- a/tests/ui/macros/type-macros-simple.rs
+++ b/tests/ui/macros/type-macros-simple.rs
@@ -1,6 +1,8 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
+#![allow(non_local_definitions)]
+
 macro_rules! Tuple {
     { $A:ty,$B:ty } => { ($A, $B) }
 }
diff --git a/tests/ui/packed/issue-46152.rs b/tests/ui/packed/issue-46152.rs
index e38b445107b..5b2e4bbfdf2 100644
--- a/tests/ui/packed/issue-46152.rs
+++ b/tests/ui/packed/issue-46152.rs
@@ -1,6 +1,7 @@
 //@ run-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
+#![allow(non_local_definitions)]
 #![feature(unsize, coerce_unsized)]
 
 #[repr(packed)]
diff --git a/tests/ui/privacy/associated-item-privacy-trait.rs b/tests/ui/privacy/associated-item-privacy-trait.rs
index f038ae9e261..655d892e244 100644
--- a/tests/ui/privacy/associated-item-privacy-trait.rs
+++ b/tests/ui/privacy/associated-item-privacy-trait.rs
@@ -1,5 +1,5 @@
 #![feature(decl_macro, associated_type_defaults)]
-#![allow(private_interfaces, private_bounds)]
+#![allow(private_interfaces, private_bounds, non_local_definitions)]
 
 mod priv_trait {
     trait PrivTr {
diff --git a/tests/ui/privacy/private-in-public-non-principal.rs b/tests/ui/privacy/private-in-public-non-principal.rs
index e348a181651..8dc90919bc9 100644
--- a/tests/ui/privacy/private-in-public-non-principal.rs
+++ b/tests/ui/privacy/private-in-public-non-principal.rs
@@ -1,5 +1,6 @@
 #![feature(auto_traits)]
 #![feature(negative_impls)]
+#![allow(non_local_definitions)]
 
 pub trait PubPrincipal {}
 auto trait PrivNonPrincipal {}
diff --git a/tests/ui/privacy/private-in-public-non-principal.stderr b/tests/ui/privacy/private-in-public-non-principal.stderr
index 73f2249bc6c..5aa08d3f071 100644
--- a/tests/ui/privacy/private-in-public-non-principal.stderr
+++ b/tests/ui/privacy/private-in-public-non-principal.stderr
@@ -1,24 +1,24 @@
 warning: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
-  --> $DIR/private-in-public-non-principal.rs:7:1
+  --> $DIR/private-in-public-non-principal.rs:8:1
    |
 LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `leak_dyn_nonprincipal` is reachable at visibility `pub`
    |
 note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public-non-principal.rs:5:1
+  --> $DIR/private-in-public-non-principal.rs:6:1
    |
 LL | auto trait PrivNonPrincipal {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(private_interfaces)]` on by default
 
 error: missing documentation for an associated function
-  --> $DIR/private-in-public-non-principal.rs:13:9
+  --> $DIR/private-in-public-non-principal.rs:14:9
    |
 LL |         pub fn check_doc_lint() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/private-in-public-non-principal.rs:10:8
+  --> $DIR/private-in-public-non-principal.rs:11:8
    |
 LL | #[deny(missing_docs)]
    |        ^^^^^^^^^^^^
diff --git a/tests/ui/proc-macro/nested-macro-rules.rs b/tests/ui/proc-macro/nested-macro-rules.rs
index bb25b97df50..0dce3c408c2 100644
--- a/tests/ui/proc-macro/nested-macro-rules.rs
+++ b/tests/ui/proc-macro/nested-macro-rules.rs
@@ -19,5 +19,6 @@ fn main() {
     nested_macro_rules::inner_macro!(print_bang, print_attr);
 
     nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
+    //~^ WARN non-local `macro_rules!` definition
     inner_macro!(print_bang, print_attr);
 }
diff --git a/tests/ui/proc-macro/nested-macro-rules.stderr b/tests/ui/proc-macro/nested-macro-rules.stderr
new file mode 100644
index 00000000000..111be882771
--- /dev/null
+++ b/tests/ui/proc-macro/nested-macro-rules.stderr
@@ -0,0 +1,27 @@
+warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
+  --> $DIR/auxiliary/nested-macro-rules.rs:7:9
+   |
+LL |   macro_rules! outer_macro {
+   |   ------------------------ in this expansion of `nested_macro_rules::outer_macro!`
+...
+LL | /         macro_rules! inner_macro {
+LL | |             ($bang_macro:ident, $attr_macro:ident) => {
+LL | |                 $bang_macro!($name);
+LL | |                 #[$attr_macro] struct $attr_struct_name {}
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+  ::: $DIR/nested-macro-rules.rs:21:5
+   |
+LL |       nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
+   |       ---------------------------------------------------------------- in this macro invocation
+   |
+   = 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: `#[warn(non_local_definitions)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/rust-2018/uniform-paths/issue-55779.rs b/tests/ui/rust-2018/uniform-paths/issue-55779.rs
index 350ab324682..246b8dd82c5 100644
--- a/tests/ui/rust-2018/uniform-paths/issue-55779.rs
+++ b/tests/ui/rust-2018/uniform-paths/issue-55779.rs
@@ -2,6 +2,8 @@
 //@ edition:2018
 //@ aux-crate:issue_55779_extern_trait=issue-55779-extern-trait.rs
 
+#![allow(non_local_definitions)]
+
 use issue_55779_extern_trait::Trait;
 
 struct Local;