-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Allow #[attr] if
to be passed to proc macros
#68618
Comments
This PR would work correctly, except for the fact that rust-lang/rust#68618 causes a compilation error to be emitted before we even have a chance to run. That issue is independent of the implementation of this PR, so this PR should start working automatically once the issue is resolved.
#[attr] if let
to be passed to proc macros#[attr] if
to be passed to proc macros
From a parsing perspective the current restriction is pretty ad-hoc and annoying, as it complicates things, so if there's no good reason for it to stay, I would also like to see it go, and would be happy to review such a PR (including with tests for the parsing, pretty printing, and ideally some local relevant refactoring). However, to make sure there are no problems, I'd like for @petrochenkov to confirm. |
Yeah, to me, it seems that allowing the attribute to be present during the |
Here's where this rule was introduced - https://github.com/rust-lang/rfcs/blob/master/text/0016-more-attributes.md#if. |
Hmm; seems like the concern was primarily semantic (in terms of macros & lints) as opposed to syntactic? |
As @Centril and @petrochenkov mentioned, the semantic meaning of such an attribute is ambiguous. However, that's not a problem with accepting it syntactically, since the proc macro processing the function can interpret it however it wants. I think it would be a good idea to allow 'normal' proc macro attrs on 'if' expressions as well (e.g. without an attribute on the entire function). The attribute invocation would be passed the entire 'if else' chain, giving the proc macro the maximum flexibility for interpreting it. The decision as to which part of the chain to actually modify would be decided by the macro implementation. However, this would certainly require further discussion. I don't think it needs to block accepting these attributes syntactically - doing so doesn't commit us to accepting them semantically (e.g. we could still emit an error if the post-expansion code contains attributes on 'if' expressions. |
Fixes rust-lang#68618 Previously, attributes on 'if' expressions (e.g. `#[attr] if true {}`) were disallowed during parsing. This made it impossible for macros to perform any custom handling of such attributes (e.g. stripping them away), since a compilation error would be emitted before they ever had a chance to run. This PR permits attributes on 'if' expressions ('if-attrs' from here on) syntactically, i.e. during parsing. We instead deny if-attrs during AST validation, which occurs after all macro expansions have run. This is a conservative change which allows more code to be processed by macros. It does not commit us to *semantically* accepting if-attrs. For example, the following code is not allowed even with this PR: ```rust fn builtin_attr() { #[allow(warnings)] if true {} } fn custom_attr() { #[my_proc_macro_attr] if true {} } ``` However, the following code *is* accepted ```rust #[cfg(FALSE)] fn foo() { #[allow(warnings)] if true {} #[my_custom_attr] if true {} } #[my_custom_attr] fn use_within_body() { #[allow(warnings)] if true {} #[my_custom_attr] if true {} } ```
…=Centril Permit attributes on 'if' expressions Previously, attributes on 'if' expressions (e.g. `#[attr] if true {}`) were disallowed during parsing. This made it impossible for macros to perform any custom handling of such attributes (e.g. stripping them away), since a compilation error would be emitted before they ever had a chance to run. This PR permits attributes on 'if' expressions ('if-attrs' from here on). Both built-in attributes (e.g. `#[allow]`, `#[cfg]`) and proc-macro attributes are supported. We still do *not* accept attributes on 'other parts' of an if-else chain. That is, the following code snippet still fails to parse: ```rust if true {} #[attr] else if false {} else #[attr] if false {} #[attr] else {} ``` Closes rust-lang#68618
…=Centril Permit attributes on 'if' expressions Previously, attributes on 'if' expressions (e.g. `#[attr] if true {}`) were disallowed during parsing. This made it impossible for macros to perform any custom handling of such attributes (e.g. stripping them away), since a compilation error would be emitted before they ever had a chance to run. This PR permits attributes on 'if' expressions ('if-attrs' from here on). Both built-in attributes (e.g. `#[allow]`, `#[cfg]`) and proc-macro attributes are supported. We still do *not* accept attributes on 'other parts' of an if-else chain. That is, the following code snippet still fails to parse: ```rust if true {} #[attr] else if false {} else #[attr] if false {} #[attr] else {} ``` Closes rust-lang#68618
…=Centril Permit attributes on 'if' expressions Previously, attributes on 'if' expressions (e.g. `#[attr] if true {}`) were disallowed during parsing. This made it impossible for macros to perform any custom handling of such attributes (e.g. stripping them away), since a compilation error would be emitted before they ever had a chance to run. This PR permits attributes on 'if' expressions ('if-attrs' from here on). Both built-in attributes (e.g. `#[allow]`, `#[cfg]`) and proc-macro attributes are supported. We still do *not* accept attributes on 'other parts' of an if-else chain. That is, the following code snippet still fails to parse: ```rust if true {} #[attr] else if false {} else #[attr] if false {} #[attr] else {} ``` Closes rust-lang#68618
This PR would work correctly, except for the fact that rust-lang/rust#68618 causes a compilation error to be emitted before we even have a chance to run. That issue is independent of the implementation of this PR, so this PR should start working automatically once the issue is resolved.
181: Allow `#[project]` to be used on `if let` expressions r=taiki-e a=Aaron1011 This PR would work correctly, except for the fact that rust-lang/rust#68618 causes a compilation error to be emitted before we even have a chance to run. That issue is independent of the implementation of this PR, so this PR should start working automatically once the issue is resolved. Co-authored-by: Aaron Hill <aa1ronham@gmail.com>
The following code:
produces this error:
Proc macros like
pin-project
currently use a trick to work around attributes on expressions being unstable: The entire function is annotated with a 'wrapper' attribute, which goes through and manually parses expression attributes. For example:In the example above, the
#[my_attr] let a = 25;
will be processed by the outer#[my_attr] fn foo()
implementation, which will strip away the expression-based#[my_attr]
before emitting the finalTokenStream
.Unfortunately, the current 'attributes are not yet allowed on
if
expressions' check is done during parsing:rust/src/librustc_parse/parser/expr.rs
Line 679 in ac2f3fa
While the proc-macro itself can parse the attribute on the
if let
without any errors, compilation will still fail due to the parsing error that was emitted before any proc-macros were run.It would be extremely useful if this check were to be moved until after parsing, so that proc macros had a chance to remove attributes from
if
expressions.The text was updated successfully, but these errors were encountered: