Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

non_local_definitions triggers on macro-generated code #125681

Closed
Nemo157 opened this issue May 28, 2024 · 14 comments · Fixed by #125722
Closed

non_local_definitions triggers on macro-generated code #125681

Nemo157 opened this issue May 28, 2024 · 14 comments · Fixed by #125722
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-discussion Category: Discussion or questions that doesn't represent real issues. L-non_local_definitions Lint: non_local_definitions T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Nemo157
Copy link
Member

Nemo157 commented May 28, 2024

I tried this code:

> cargo new foo && cd foo
    Creating binary (application) `foo` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

> cargo add displaydoc
    Updating crates.io index
      Adding displaydoc v0.2.4 to dependencies
             Features:
             + std
    Updating crates.io index
     Locking 6 packages to latest compatible versions

> echo '#[derive(displaydoc::Display)] pub enum Foo { #[doc = "test"] Test }' >> src/main.rs

I expected to see this happen: no warnings

Instead, this happened:

> cargo check
    Checking foo v0.1.0 (/tmp/scratch.rust.2024-05-28T21-14.UGSjii/foo)
warning: non-local `impl` definition, they should be avoided as they go against expectation
 --> src/main.rs:4:10
  |
4 | #[derive(displaydoc::Display)] pub enum Foo { #[doc = "test"] Test }
  |          ^^^^^^^^^^^^^^^^^^^
  |
  = help: move this `impl` block outside the of the current constant `_DERIVE_Display_FOR_Foo`
  = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
  = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
  = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
  = note: the derive macro `displaydoc::Display` may come from an old version of the `displaydoc` crate, try updating your dependency with `cargo update -p displaydoc`
  = note: `#[warn(non_local_definitions)]` on by default
  = note: this warning originates in the derive macro `displaydoc::Display` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: `foo` (bin "foo") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s

Meta

rustc --version --verbose:

rustc 1.80.0 (84b40fc90 2024-05-27)
binary: rustc
commit-hash: 84b40fc908c3adc7e0e470b3fbaa264df0e122b8
commit-date: 2024-05-27
host: x86_64-unknown-linux-gnu
release: 1.80.0
LLVM version: 18.1.6

cc #120363

@Nemo157 Nemo157 added A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. L-non_local_definitions Lint: non_local_definitions labels May 28, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 28, 2024
@Nemo157
Copy link
Member Author

Nemo157 commented May 28, 2024

It looks like there is an upstream issue about this yaahc/displaydoc#46, but it seems like this shouldn't be an issue for dependents as long as displaydoc is on edition < 2024.

@Urgau
Copy link
Member

Urgau commented May 28, 2024

It is expected for the non_local_definitions lint to lint on macro-generated code.
It is also expected for the lint to lint on all editions (it is not a edition dependent lint).

@Nemo157
Copy link
Member Author

Nemo157 commented May 28, 2024

What am I meant to do as a downstream of a macro crate that hasn't fixed it then? I don't want to be #[allow]ing a FCW, but there's nothing else I can do to clear this warning from my code. (And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)

@Urgau
Copy link
Member

Urgau commented May 28, 2024

What am I meant to do as a downstream of a macro crate that hasn't fixed it then?

Allow the lint. Report the issue upstream. Consider switching to an unaffected crate.

I don't want to be #[allow]ing a FCW

That's understandable, but until the upstream crate is fixed I don't have a better solution.

Note, that it is quite unlikely that this point that the lint will become deny-by-default in Rust 2024.

(And that implies that the planned "hard error in 2027" actually means for all editions, not just Edition 2027?)

No, if hard-error there is, it would only be for edition 2027 and higher, not below.

@workingjubilee
Copy link
Member

It is expected for the non_local_definitions lint to lint on macro-generated code.

Why?

@workingjubilee
Copy link
Member

Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.

@Urgau
Copy link
Member

Urgau commented May 28, 2024

Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or macro_rules!.

Detecting and ignoring macro-generated code for a lint where possible is the expected behavior of rustc.

Yes, but we must still emit the warning in macro-generated code, since the goal is to make the lint deny-by-default and then hard-error in a future edition, and without the warn it would go straight to hard-error which is not good.

@workingjubilee
Copy link
Member

Because, in particular for macro-generated code, we can't lint at the source since, well it is only generated when using the proc-macro or macro_rules!.

macro authors write tests.

@workingjubilee
Copy link
Member

workingjubilee commented May 28, 2024

Is there no ability to enable the lint when in the same crate/workspace but disable it for "foreign" macro-generated spans?

@Urgau
Copy link
Member

Urgau commented May 28, 2024

macro authors write tests.

Yes, but can't rely on this. Also, not all macros have tests. The lint is only warn-by-default so it wouldn't break any test yet.

Is there no ability to enable the lint when in the same crate/workspace?

If you mean: "don't lint on external macro", that is possible for macro_rules! but not for proc-macro since they are always external.


We did an crater run, to evaluate the impact, before merging the lint in #120393 (comment). We had many cases with derive-macro, most of them (82.2%) where fixable by a cargo update, the rest would need manual intervention, the crate in question here displaydoc was detected, and I reported the issue upstream with the fix that would fix the issue.

@workingjubilee
Copy link
Member

If you mean: "don't lint on external macro", that is possible for macro_rules! but not for proc-macro since they are always external.

that was why I was thinking of trying to reason cross-workspace, but hmm, true.

And actually, proc macros are worse: they can either generate spans or assign themselves arbitrary spans, so at least some are going to almost certainly slip through either way.

@Urgau
Copy link
Member

Urgau commented May 28, 2024

that was why I was thinking of trying to reason cross-workspace, but hmm, true.

I would love if we had the ability to do that, but unfortunately rustc doesn't have that information. Workspaces are a Cargo-only concept.

And actually, proc macros are worse: they can either generate spans or assign themselves arbitrary spans, so at least some are going to almost certainly slip through either way.

👀

@workingjubilee
Copy link
Member

I would love if we had the ability to do that, but unfortunately rustc doesn't have that information. Workspaces are a Cargo-only concept.

I was hoping that we could do something where cargo helps us out here by describing which things we pay attention to, but I am fully prepared to believe that such is not tractable, even if only because no one has figured out if the infra for doing such a thing is even possible.

@jieyouxu jieyouxu removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 29, 2024
@Urgau
Copy link
Member

Urgau commented Jun 8, 2024

Yeah, unfortunately there isn't really anything else the compiler can do, it would be great if we could lint at the macro definition but due to the way they work that isn't possible, we are therefore forced to do the second "best" thing and lint at the usage.

#125722 should be make it clearer that the "macro needs to change".

So let's reclassify this issue as not-a-bug but as a discussion.

@rustbot labels -C-bug +C-discussion

@rustbot rustbot added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. labels Jun 8, 2024
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Jun 13, 2024
…ge, r=estebank

Indicate in `non_local_defs` lint that the macro needs to change

This PR adds a note to indicate that the macro needs to change in the `non_local_definitions` lint output.

Address rust-lang#125089 (comment)
Fixes rust-lang#125681
r? `@estebank`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 14, 2024
…ge, r=estebank

Indicate in `non_local_defs` lint that the macro needs to change

This PR adds a note to indicate that the macro needs to change in the `non_local_definitions` lint output.

Address rust-lang#125089 (comment)
Fixes rust-lang#125681
r? ``@estebank``
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 14, 2024
…ge, r=estebank

Indicate in `non_local_defs` lint that the macro needs to change

This PR adds a note to indicate that the macro needs to change in the `non_local_definitions` lint output.

Address rust-lang#125089 (comment)
Fixes rust-lang#125681
r? ```@estebank```
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 14, 2024
…ge, r=estebank

Indicate in `non_local_defs` lint that the macro needs to change

This PR adds a note to indicate that the macro needs to change in the `non_local_definitions` lint output.

Address rust-lang#125089 (comment)
Fixes rust-lang#125681
r? ````@estebank````
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 14, 2024
…ge, r=estebank

Indicate in `non_local_defs` lint that the macro needs to change

This PR adds a note to indicate that the macro needs to change in the `non_local_definitions` lint output.

Address rust-lang#125089 (comment)
Fixes rust-lang#125681
r? `````@estebank`````
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 15, 2024
…ge, r=estebank

Indicate in `non_local_defs` lint that the macro needs to change

This PR adds a note to indicate that the macro needs to change in the `non_local_definitions` lint output.

Address rust-lang#125089 (comment)
Fixes rust-lang#125681
r? ``````@estebank``````
@bors bors closed this as completed in 1d1356d Jun 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-discussion Category: Discussion or questions that doesn't represent real issues. L-non_local_definitions Lint: non_local_definitions T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants