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

Extended key value attributes are parsed too eagerly #85882

Closed
XAMPPRocky opened this issue Jun 1, 2021 · 4 comments
Closed

Extended key value attributes are parsed too eagerly #85882

XAMPPRocky opened this issue Jun 1, 2021 · 4 comments
Labels
C-bug Category: This is a bug. F-extended_key_value_attributes `#![feature(extended_key_value_attributes)]

Comments

@XAMPPRocky
Copy link
Member

Consider the following rust code, I would have expected the below to compile on stable today when compiled with rustc src/lib.rs, but in fact it fails to compile citing that arbitrary key values are unstable. Which implies that the include_str! parsing is being handled ahead of handling the cfg predicate. While this specific example won't be an issue when this becomes stable in 1.54.0, but it does point to this feature having some surprising behaviour at the moment, I would have expected the cfg predicate on the module to have been evaluated to false and the whole module would be skipped, regardless of what I used on the right hand side of doc.

#[cfg(feature = "nightly")]
mod test {
    #![doc = include_str!("README.md")]
}
error[E0658]: arbitrary expressions in key-value attributes are unstable
 --> src/lib.rs:4:14
  |
4 |     #![doc = include_str!("README.md")]
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #78835 <https://github.com/rust-lang/rust/issues/78835> for more information

error: aborting due to previous error

There's a workaround if you're okay with double wrapping the modules, as if you embed it in a declarative macro, it will behave how you expect.

#[cfg(feature = "nightly")]
mod nightly {
    macro_rules! tests {
        () => {
            #[doc = include_str!("README.md")]
            mod tests {}
        }
    }

    tests!();
}
@XAMPPRocky XAMPPRocky added C-bug Category: This is a bug. F-extended_key_value_attributes `#![feature(extended_key_value_attributes)] labels Jun 1, 2021
@petrochenkov
Copy link
Contributor

Which implies that the include_str! parsing is being handled ahead of handling the cfg predicate.

Any parsing is performed before handling cfgs though, it's not specific to key-value attributes.

This issue is a duplicate of #82768, which suggests a workaround (for older versions of rustc, since arbitrary expressions in key-value attributes are now stable).

@XAMPPRocky
Copy link
Member Author

XAMPPRocky commented Jun 1, 2021

Any parsing is performed before handling cfgs though, it's not specific to key-value attributes.

Sure, my point was more that it mismatches with my expectation that the item after the #[cfg] is mostly just treated like a token stream, and that it shouldn't matter whether that the stream has an unstable language feature, when to me, the compiler should be throwing it out anyway before it tries to expand. Maybe it would be fairer to say that the feature detection linting is happening earlier than I would expect.

@petrochenkov
Copy link
Contributor

item after the #[cfg] is mostly just treated like a token stream, and that it shouldn't matter whether that the stream has an unstable language feature

That's true for fn-like macro inputs, but attribute macros always receive valid Rust syntax as input.
#65860 contains some more detailed discussion of relevant issues.

@XAMPPRocky
Copy link
Member Author

Thanks for the link, and the explanation, I think we can close this one anyway as it seems to be known, and the impact isn't as bad as initially thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-extended_key_value_attributes `#![feature(extended_key_value_attributes)]
Projects
None yet
Development

No branches or pull requests

2 participants