-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
[nightly regression] rustc incorrectly parses attributes as macro invocations in nightly-2018-08-18 #53583
Comments
Currently this is expected behavior - fn-like macros, attribute macros and derive macros share single namespace and can shadow each other (similarly to types being able to shadow traits etc). This change shouldn't affect stable Rust since attribute macros were stabilized only few days ago. |
Ok, but how is this |
@jchlapinski can you say a bit more about the actual code that is breaking for you? cc @rust-lang/lang |
Flagging this for @rust-lang/lang discussion -- do we want all |
In particular, if this is regressing code, it may not be something we can't really do. (Especially stable code -- it's still not clear to me just what the regressed code looks like.) |
The error message seems a bit confusing as I think it leads the user to believe that If you actually wanted that behavior then the invocation should have been
See #53583 (comment) for why it is a stable-to-nightly-regression. @petrochenkov's solution seems like a good one provided that attribute proc macros can be renamed to deal with conflicts. |
@nikomatsakis basically we have custom derive for our diagnostic type trait Now we can of course change either name, however I still do not understand why using same name for attribute AND a macro would clash? By that same logic I can have a field and a method with the same name, since field access and method calls are easily discerned in parsing. Is there a different way to expand a macro, without suffixing macro name with a |
@Centril I am not blaming, I am just reasoning on why those things are sharing the same namespace. In my mind an attribute is something completely different than a macro. same logic for fields and methods as in my comment above. |
Oh; I didn't mean that you are blaming the compiler devs for breaking your code or something, |
Ah, I see this is an inert attribute white-listed by a derive macro, not an attribute macro. My preferred solution would be to increase priority of derive helper attributes during resolution (item 6 in #50911 (comment)), rather than introducing more namespaces.
|
@petrochenkov In short, thanks, that solution would solve our problem, and of course it is one way to do it. But please, if I could take a few more minutes of Your time, explain why You keep referring to attributes, written as |
@petrochenkov Nevermind, please ignore. The magic name "inert attribute" have provided me with some results to read on. Thanks |
@jchlapinski I know you said ignore, but I'll just expand briefly ;) in short, yes, we are aiming to allow macros to be used in those positions which would edit or alter the struct definition and expand it. |
That said, I myself am not entirely clear on the current contours of this design. So perhaps I will pose a few questions that I would like clarified:
|
No, I don't think so. The two kinds of macros have different 'signatures' so whether decl or proc, they have to be used differently. However, they do share the same namespace.
"This position" is item position? In which case it should be fine. I believe with new proc macros there is no distinction between decorators and modifiers, and I don't care either way about old proc macros.
I believe this is currently a special attribute of derive macros. Real proc macros have more power since they consume the input to the macro, they can decide what to allow or disallow. |
Fixed in #54069 |
visited for triage. Seems under control from looking at PR #54069. P-high. |
resolve: Introduce two sub-namespaces in macro namespace Two sub-namespaces are introduced in the macro namespace - one for bang macros and one for attribute-like macros (attributes, derives). "Sub-namespace" means this is not a newly introduced full namespace, the single macro namespace is still in place. I.e. you still can't define/import two macros with the same name in a single module, `use` imports still import only one name in macro namespace (from any sub-namespace) and not possibly two. However, when we are searching for a name used in a `!` macro call context (`my_macro!()`) we skip attribute names in scope, and when we are searching for a name used in attribute context (`#[my_macro]`/`#[derive(my_macro)]`) we are skipping bang macro names in scope. In other words, bang macros cannot shadow attribute macros and vice versa. For a non-macro analogy, we could e.g. skip non-traits when searching for `MyTrait` in `impl MyTrait for Type { ... }`. However we do not do it in non-macro namespaces because we don't have practical issues with e.g. non-traits shadowing traits with the same name, but with macros we do, especially after macro modularization. For `#[test]` and `#[bench]` we have a hack in the compiler right now preventing their shadowing by `macro_rules! test` and similar things. This hack was introduced after making `#[test]`/`#[bench]` built-in macros instead of built-in attributes (#53410), something that needed to be done from the start since they are "active" attributes transforming their inputs. Now they are passed through normal name resolution and can be shadowed, but that's a breaking change, so we have a special hack basically applying this PR for `#[test]` and `#[bench]` only. Soon all potentially built-in attributes will be passed through normal name resolution (#53913) and that uncovers even more cases where the strict "macro namespace is a single namespace" rule needs to be broken. For example, with strict rules, built-in macro `cfg!(...)` would shadow built-in attribute `#[cfg]` (they are different things), standard library macro `thread_local!(...)` would shadow built-in attribute `#[thread_local]` - both of these cases are covered by special hacks in #53913 as well. Crater run uncovered more cases of attributes being shadowed by user-defined macros (`warn`, `doc`, `main`, even `deprecated`), we cannot add exceptions in the compiler for all of them. Regressions with user-defined attributes like #53583 and #53898 also appeared after enabling macro modularization. People are also usually confused (#53205 (comment), #53583 (comment)) when they see conflicts between attributes and non-attribute macros for the first time. So my proposed solution is to solve this issue by introducing two sub-namespaces and thus skipping resolutions of the wrong kind and preventing more error-causing cases of shadowing. Fixes #53583
In the newest nightly all attributes with names identical to existing macros are parsed as macro invocation (note the lack of
!
at the front ofdummy
in the example below).Previous version
nightly-2018-08-17
works as expected.This breaks compilation of some of our custom derives, using same name for attributes and macros, which was previously allowed.
I tried this code:
I expected this to complain about unknown custom attribute
dummy
Instead, I got this error:
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: