-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Stabilize unrestricted_attribute_tokens
#57367
Conversation
r? @Centril |
Minor note: it might make sense to frame this not as "stabilizing So my "suggestion" is to make the stabilized subset stable under Also, cc rust-lang/wg-grammar#13, @eddyb. This grammar is the current grammar in that (permissive) grammar draft, but this probably should be linked. |
☔ The latest upstream changes (presumably #57379) made this pull request unmergeable. Please resolve the merge conflicts. |
Implement basic input validation for built-in attributes Correct top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is enforced for built-in attributes, built-in attributes must also fit into the "meta-item" syntax (aka the "classic attribute syntax"). For some subset of attributes (found by crater run), errors are lowered to deprecation warnings. NOTE: This PR previously included #57367 as well.
Stabilization proposalI propose that we stabilize @rfcbot merge Version targetThe next version is 1.34 which goes into beta around 2019-03-01. What is stabilizedThe formal grammar (in the lyg notation) of attributes becomes: OuterAttr = "#" attr:Attr;
InnerAttr = "#" "!" attr:Attr;
Attr = "[" path:Path input:AttrInput? "]";
AttrInput =
| "(" TOKEN_STREAM ")"
| "[" TOKEN_STREAM "]"
| "{" TOKEN_STREAM "}"
| "=" LITERAL // Unsuffixed literals only.
; As a result, users may for example write MotivationThe general motivation for allowing this is to facilitate more natural and expressive EDSLs in attributes as opposed to wrapping things in strings. Moreover, this brings the grammar of attributes closer to that of regular macros. Tests
What is notUsers are not yet permitted to write:
History
|
Team member @Centril has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
Review pings @cramertj, @joshtriplett, @nikomatsakis, @pnkfelix, @scottmcm, and @withoutboats -- have a look? :) |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
@petrochenkov If you want to rebase quickly, we could try to get this into 1.34 even tho FCP has not completed... at the risk of beta-backporting out if it should not complete, but that risks seems quite small. As for the implementation, r=me with the additional tests I asked for in #57367 (comment). @bors p=10 |
fcccd6b
to
eccc199
Compare
@bors r=Centril |
📌 Commit eccc199 has been approved by |
Stabilize `unrestricted_attribute_tokens` In accordance with a plan described in https://internals.rust-lang.org/t/unrestricted-attribute-tokens-feature-status/8561/3. Delimited non-macro non-builtin attributes now support the same syntax as macro attributes: ``` PATH PATH `(` TOKEN_STREAM `)` PATH `[` TOKEN_STREAM `]` PATH `{` TOKEN_STREAM `}` ``` Such attributes mostly serve as inert proc macro helpers or tool attributes. To some extent these attributes are de-facto stable due to a hole in feature gate checking (feature gating is done too late - after macro expansion.) So if macro *removes* such helper attributes during expansion (and it must remove them, unless it's a derive macro), then the code will work on stable. Key-value non-macro non-builtin attributes are now restricted to bare minimum required to support what we support on stable - unsuffixed literals (#34981). ``` PATH `=` LITERAL ``` (Key-value macro attributes are not supported at all right now.) Crater run in #57321 found no regressions for this change. There are multiple possible ways to extend key-value attributes (#57321 (comment)), but I'd expect an RFC for that and it's not a pressing enough issue to block stabilization of delimited attributes. Built-in attributes are still restricted to the "classic" meta-item syntax, nothing changes here. #57321 goes further and adds some additional restrictions (more consistent input checking) to built-in attributes. Closes #55208
☀️ Test successful - checks-travis, status-appveyor |
☀️ Test successful - checks-travis, status-appveyor |
why are only literals allowed with the |
@withoutboats (For key-value attributes we can't "just accept what attribute macros accept", because attribute macros do not accept key-value forms at all, that is blocked on implementing querying currently used delimiter from a proc macro.) |
This change is necessary due to the recent change in the rustc parser that the following attribute has become a hard parser error: ```rust struct Foo; ``` cc rust-lang/rust#57367.
Pkgsrc changes: * Bump required rust version to build to 1.33.0. * Adapt patches to changed file locations. * (I worry about 32-bit ports, now that Atomic64 apparently is First-Class; this has been built on NetBSD/amd64 so far) Upstream changes: Version 1.34.0 (2019-04-11) ========================== Language -------- - [You can now use `#[deprecated = "reason"]`][58166] as a shorthand for `#[deprecated(note = "reason")]`. This was previously allowed by mistake but had no effect. - [You can now accept token streams in `#[attr()]`,`#[attr[]]`, and `#[attr{}]` procedural macros.][57367] - [You can now write `extern crate self as foo;`][57407] to import your crate's root into the extern prelude. Compiler -------- - [You can now target `riscv64imac-unknown-none-elf` and `riscv64gc-unknown-none-elf`.][58406] - [You can now enable linker plugin LTO optimisations with `-C linker-plugin-lto`.][58057] This allows rustc to compile your Rust code into LLVM bitcode allowing LLVM to perform LTO optimisations across C/C++ FFI boundaries. - [You can now target `powerpc64-unknown-freebsd`.][57809] Libraries --------- - [The trait bounds have been removed on some of `HashMap<K, V, S>`'s and `HashSet<T, S>`'s basic methods.][58370] Most notably you no longer require the `Hash` trait to create an iterator. - [The `Ord` trait bounds have been removed on some of `BinaryHeap<T>`'s basic methods.][58421] Most notably you no longer require the `Ord` trait to create an iterator. - [The methods `overflowing_neg` and `wrapping_neg` are now `const` functions for all numeric types.][58044] - [Indexing a `str` is now generic over all types that implement `SliceIndex<str>`.][57604] - [`str::trim`, `str::trim_matches`, `str::trim_{start, end}`, and `str::trim_{start, end}_matches` are now `#[must_use]`][57106] and will produce a warning if their returning type is unused. - [The methods `checked_pow`, `saturating_pow`, `wrapping_pow`, and `overflowing_pow` are now available for all numeric types.][57873] These are equivalvent to methods such as `wrapping_add` for the `pow` operation. Stabilized APIs --------------- #### std & core * [`Any::type_id`] * [`Error::type_id`] * [`atomic::AtomicI16`] * [`atomic::AtomicI32`] * [`atomic::AtomicI64`] * [`atomic::AtomicI8`] * [`atomic::AtomicU16`] * [`atomic::AtomicU32`] * [`atomic::AtomicU64`] * [`atomic::AtomicU8`] * [`convert::Infallible`] * [`convert::TryFrom`] * [`convert::TryInto`] * [`iter::from_fn`] * [`iter::successors`] * [`num::NonZeroI128`] * [`num::NonZeroI16`] * [`num::NonZeroI32`] * [`num::NonZeroI64`] * [`num::NonZeroI8`] * [`num::NonZeroIsize`] * [`slice::sort_by_cached_key`] * [`str::escape_debug`] * [`str::escape_default`] * [`str::escape_unicode`] * [`str::split_ascii_whitespace`] #### std * [`Instant::checked_add`] * [`Instant::checked_sub`] * [`SystemTime::checked_add`] * [`SystemTime::checked_sub`] Cargo ----- - [You can now use alternative registries to crates.io.][cargo/6654] Misc ---- - [You can now use the `?` operator in your documentation tests without manually adding `fn main() -> Result<(), _> {}`.][56470] Compatibility Notes ------------------- - [`Command::before_exec` is now deprecated in favor of the unsafe method `Command::pre_exec`.][58059] - [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you can now use `const` functions in `static` variables. [58370]: rust-lang/rust#58370 [58406]: rust-lang/rust#58406 [58421]: rust-lang/rust#58421 [58166]: rust-lang/rust#58166 [58044]: rust-lang/rust#58044 [58057]: rust-lang/rust#58057 [58059]: rust-lang/rust#58059 [57809]: rust-lang/rust#57809 [57873]: rust-lang/rust#57873 [57604]: rust-lang/rust#57604 [57367]: rust-lang/rust#57367 [57407]: rust-lang/rust#57407 [57425]: rust-lang/rust#57425 [57106]: rust-lang/rust#57106 [56470]: rust-lang/rust#56470 [cargo/6654]: rust-lang/cargo#6654 [`Any::type_id`]: https://doc.rust-lang.org/std/any/trait.Any.html#tymethod.type_id [`Error::type_id`]: https://doc.rust-lang.org/std/error/trait.Error.html#tymethod.type_id [`atomic::AtomicI16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI16.html [`atomic::AtomicI32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI32.html [`atomic::AtomicI64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI64.html [`atomic::AtomicI8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI8.html [`atomic::AtomicU16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU16.html [`atomic::AtomicU32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU32.html [`atomic::AtomicU64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU64.html [`atomic::AtomicU8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU8.html [`convert::Infallible`]: https://doc.rust-lang.org/std/convert/enum.Infallible.html [`convert::TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html [`convert::TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html [`iter::from_fn`]: https://doc.rust-lang.org/std/iter/fn.from_fn.html [`iter::successors`]: https://doc.rust-lang.org/std/iter/fn.successors.html [`num::NonZeroI128`]: https://doc.rust-lang.org/std/num/struct.NonZeroI128.html [`num::NonZeroI16`]: https://doc.rust-lang.org/std/num/struct.NonZeroI16.html [`num::NonZeroI32`]: https://doc.rust-lang.org/std/num/struct.NonZeroI32.html [`num::NonZeroI64`]: https://doc.rust-lang.org/std/num/struct.NonZeroI64.html [`num::NonZeroI8`]: https://doc.rust-lang.org/std/num/struct.NonZeroI8.html [`num::NonZeroIsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroIsize.html [`slice::sort_by_cached_key`]: https://doc.rust-lang.org/std/slice/fn.sort_by_cached_key [`str::escape_debug`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_debug [`str::escape_default`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_default [`str::escape_unicode`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_unicode [`str::split_ascii_whitespace`]: https://doc.rust-lang.org/std/primitive.str.html#method.split_ascii_whitespace [`Instant::checked_add`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_add [`Instant::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_sub [`SystemTime::checked_add`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_add [`SystemTime::checked_sub`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_sub
Pkgsrc changes: * Bump required rust version to build to 1.33.0. * Adapt patches to changed file locations. * (I worry about 32-bit ports, now that Atomic64 apparently is First-Class; this has been built on NetBSD/amd64 so far) Upstream changes: Version 1.34.0 (2019-04-11) ========================== Language -------- - [You can now use `#[deprecated = "reason"]`][58166] as a shorthand for `#[deprecated(note = "reason")]`. This was previously allowed by mistake but had no effect. - [You can now accept token streams in `#[attr()]`,`#[attr[]]`, and `#[attr{}]` procedural macros.][57367] - [You can now write `extern crate self as foo;`][57407] to import your crate's root into the extern prelude. Compiler -------- - [You can now target `riscv64imac-unknown-none-elf` and `riscv64gc-unknown-none-elf`.][58406] - [You can now enable linker plugin LTO optimisations with `-C linker-plugin-lto`.][58057] This allows rustc to compile your Rust code into LLVM bitcode allowing LLVM to perform LTO optimisations across C/C++ FFI boundaries. - [You can now target `powerpc64-unknown-freebsd`.][57809] Libraries --------- - [The trait bounds have been removed on some of `HashMap<K, V, S>`'s and `HashSet<T, S>`'s basic methods.][58370] Most notably you no longer require the `Hash` trait to create an iterator. - [The `Ord` trait bounds have been removed on some of `BinaryHeap<T>`'s basic methods.][58421] Most notably you no longer require the `Ord` trait to create an iterator. - [The methods `overflowing_neg` and `wrapping_neg` are now `const` functions for all numeric types.][58044] - [Indexing a `str` is now generic over all types that implement `SliceIndex<str>`.][57604] - [`str::trim`, `str::trim_matches`, `str::trim_{start, end}`, and `str::trim_{start, end}_matches` are now `#[must_use]`][57106] and will produce a warning if their returning type is unused. - [The methods `checked_pow`, `saturating_pow`, `wrapping_pow`, and `overflowing_pow` are now available for all numeric types.][57873] These are equivalvent to methods such as `wrapping_add` for the `pow` operation. Stabilized APIs --------------- #### std & core * [`Any::type_id`] * [`Error::type_id`] * [`atomic::AtomicI16`] * [`atomic::AtomicI32`] * [`atomic::AtomicI64`] * [`atomic::AtomicI8`] * [`atomic::AtomicU16`] * [`atomic::AtomicU32`] * [`atomic::AtomicU64`] * [`atomic::AtomicU8`] * [`convert::Infallible`] * [`convert::TryFrom`] * [`convert::TryInto`] * [`iter::from_fn`] * [`iter::successors`] * [`num::NonZeroI128`] * [`num::NonZeroI16`] * [`num::NonZeroI32`] * [`num::NonZeroI64`] * [`num::NonZeroI8`] * [`num::NonZeroIsize`] * [`slice::sort_by_cached_key`] * [`str::escape_debug`] * [`str::escape_default`] * [`str::escape_unicode`] * [`str::split_ascii_whitespace`] #### std * [`Instant::checked_add`] * [`Instant::checked_sub`] * [`SystemTime::checked_add`] * [`SystemTime::checked_sub`] Cargo ----- - [You can now use alternative registries to crates.io.][cargo/6654] Misc ---- - [You can now use the `?` operator in your documentation tests without manually adding `fn main() -> Result<(), _> {}`.][56470] Compatibility Notes ------------------- - [`Command::before_exec` is now deprecated in favor of the unsafe method `Command::pre_exec`.][58059] - [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you can now use `const` functions in `static` variables. [58370]: rust-lang/rust#58370 [58406]: rust-lang/rust#58406 [58421]: rust-lang/rust#58421 [58166]: rust-lang/rust#58166 [58044]: rust-lang/rust#58044 [58057]: rust-lang/rust#58057 [58059]: rust-lang/rust#58059 [57809]: rust-lang/rust#57809 [57873]: rust-lang/rust#57873 [57604]: rust-lang/rust#57604 [57367]: rust-lang/rust#57367 [57407]: rust-lang/rust#57407 [57425]: rust-lang/rust#57425 [57106]: rust-lang/rust#57106 [56470]: rust-lang/rust#56470 [cargo/6654]: rust-lang/cargo#6654 [`Any::type_id`]: https://doc.rust-lang.org/std/any/trait.Any.html#tymethod.type_id [`Error::type_id`]: https://doc.rust-lang.org/std/error/trait.Error.html#tymethod.type_id [`atomic::AtomicI16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI16.html [`atomic::AtomicI32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI32.html [`atomic::AtomicI64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI64.html [`atomic::AtomicI8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicI8.html [`atomic::AtomicU16`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU16.html [`atomic::AtomicU32`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU32.html [`atomic::AtomicU64`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU64.html [`atomic::AtomicU8`]: https://doc.rust-lang.org/std/atomic/struct.AtomicU8.html [`convert::Infallible`]: https://doc.rust-lang.org/std/convert/enum.Infallible.html [`convert::TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html [`convert::TryInto`]: https://doc.rust-lang.org/std/convert/trait.TryInto.html [`iter::from_fn`]: https://doc.rust-lang.org/std/iter/fn.from_fn.html [`iter::successors`]: https://doc.rust-lang.org/std/iter/fn.successors.html [`num::NonZeroI128`]: https://doc.rust-lang.org/std/num/struct.NonZeroI128.html [`num::NonZeroI16`]: https://doc.rust-lang.org/std/num/struct.NonZeroI16.html [`num::NonZeroI32`]: https://doc.rust-lang.org/std/num/struct.NonZeroI32.html [`num::NonZeroI64`]: https://doc.rust-lang.org/std/num/struct.NonZeroI64.html [`num::NonZeroI8`]: https://doc.rust-lang.org/std/num/struct.NonZeroI8.html [`num::NonZeroIsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroIsize.html [`slice::sort_by_cached_key`]: https://doc.rust-lang.org/std/slice/fn.sort_by_cached_key [`str::escape_debug`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_debug [`str::escape_default`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_default [`str::escape_unicode`]: https://doc.rust-lang.org/std/primitive.str.html#method.escape_unicode [`str::split_ascii_whitespace`]: https://doc.rust-lang.org/std/primitive.str.html#method.split_ascii_whitespace [`Instant::checked_add`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_add [`Instant::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Instant.html#method.checked_sub [`SystemTime::checked_add`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_add [`SystemTime::checked_sub`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.checked_sub
syntax: Support modern attribute syntax in the `meta` matcher Where "modern" means #57367: ``` PATH PATH `(` TOKEN_STREAM `)` PATH `[` TOKEN_STREAM `]` PATH `{` TOKEN_STREAM `}` ``` Unfortunately, `meta` wasn't future-proofed using the `FOLLOW` token set like other matchers (#34011), so code like `$meta:meta {` or `$meta:meta [` may break, and we need a crater run to find out how often this happens in practice. Closes #49629 (by fully supporting `meta` rather than removing it.)
syntax: Support modern attribute syntax in the `meta` matcher Where "modern" means rust-lang#57367: ``` PATH PATH `(` TOKEN_STREAM `)` PATH `[` TOKEN_STREAM `]` PATH `{` TOKEN_STREAM `}` ``` Unfortunately, `meta` wasn't future-proofed using the `FOLLOW` token set like other matchers (rust-lang#34011), so code like `$meta:meta {` or `$meta:meta [` may break, and we need a crater run to find out how often this happens in practice. Closes rust-lang#49629 (by fully supporting `meta` rather than removing it.)
syntax: Support modern attribute syntax in the `meta` matcher Where "modern" means rust-lang#57367: ``` PATH PATH `(` TOKEN_STREAM `)` PATH `[` TOKEN_STREAM `]` PATH `{` TOKEN_STREAM `}` ``` Unfortunately, `meta` wasn't future-proofed using the `FOLLOW` token set like other matchers (rust-lang#34011), so code like `$meta:meta {` or `$meta:meta [` may break, and we need a crater run to find out how often this happens in practice. Closes rust-lang#49629 (by fully supporting `meta` rather than removing it.)
In accordance with a plan described in https://internals.rust-lang.org/t/unrestricted-attribute-tokens-feature-status/8561/3.
Delimited non-macro non-builtin attributes now support the same syntax as macro attributes:
Such attributes mostly serve as inert proc macro helpers or tool attributes.
To some extent these attributes are de-facto stable due to a hole in feature gate checking (feature gating is done too late - after macro expansion.)
So if macro removes such helper attributes during expansion (and it must remove them, unless it's a derive macro), then the code will work on stable.
Key-value non-macro non-builtin attributes are now restricted to bare minimum required to support what we support on stable - unsuffixed literals (#34981).
(Key-value macro attributes are not supported at all right now.)
Crater run in #57321 found no regressions for this change.
There are multiple possible ways to extend key-value attributes (#57321 (comment)), but I'd expect an RFC for that and it's not a pressing enough issue to block stabilization of delimited attributes.
Built-in attributes are still restricted to the "classic" meta-item syntax, nothing changes here.
#57321 goes further and adds some additional restrictions (more consistent input checking) to built-in attributes.
Closes #55208