Skip to content

non_local_definitions lint is unhappy with multiple nested anonymous constants #131474

Closed
@clarfonthey

Description

@clarfonthey

I tried this code:

struct Test;
const _: () = {
    const _: () = {
        impl Default for Test {
            fn default() -> Test {
                Test
            }
        }
    };
};

This should be completely okay, since the impl is only nested within anonymous constant blocks.

Instead, you get this backwards-compatibility warning:

warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
 --> src/lib.rs:5:9
  |
4 |     const _: () = {
  |     ----------- move the `impl` block outside of this constant `_` and up 2 bodies
5 |         impl Default for Test {
  |         ^^^^^-------^^^^^----
  |              |           |
  |              |           `Test` is not local
  |              `Default` is not local
  |
  = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
  = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint
  = note: this 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

Meta

rustc --version --verbose:

rustc 1.83.0-nightly (6f4ae0f34 2024-10-08)
binary: rustc
commit-hash: 6f4ae0f34503601e54680a137c1db0b81b56cc3d
commit-date: 2024-10-08
host: x86_64-unknown-linux-gnu
release: 1.83.0-nightly
LLVM version: 19.1.1

This is currently affecting the bevy_reflect crate, which has a few instances of doubly-nested anonymous constants generated by macros. Particularly, the impl_type_path! macro nests its result in an anonymous constant, and the impl_reflect_for_atomic! calls this macro inside an anonymous constant. The anonymous constants exist to allow local imports without affecting the larger scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.L-non_local_definitionsLint: non_local_definitionsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions