-
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
syntax: Relax path grammar #43540
syntax: Relax path grammar #43540
Conversation
This seems OK -- I can certainly see the advantage of having a single path grammar that works in any context. |
My only concern here would be whether it's possible to use the "optional" turbofish with a type and have that type ignored. Will the optional turbofish's specified type always get used? Because if it's ever possible to pass Is that ever possible here? |
@joshtriplett No, the two syntax forms result in the same AST/HIR, it's only a disambiguation. |
@eddyb Oh, I see; this isn't making the whole (Now if only we could do the reverse, and allow |
@rfcbot fcp merge I propose that we accept this change. To summarize: the idea is to accept I confess I have some reservations: this doesn't seem actively harmful, but it introduces "more than one way to do it", and I'm not sure how strong the motivation is. But I'm nonetheless proposing to merge in order to spur conversation forward. |
This is probably a FAQ somewhere, but do we have documentation for why there are contexts where we only accept the turbofish ( |
Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, 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. |
Is there an example of a use case for this? Trying to understand #41740, it seems like the macro path matcher could (should) be changed, but that doesn't imply changing the grammar entirely. So far the comments haven't really made this change feel well-motivated. The grammar being simpler doesn't necessarily make the language easier to use. Is anyone actually going to be writing |
Yes, we could add one more path flavor with optional disambiguator and use it only in macros, but I'd prefer to reduce the number of flavors rather than to increase it.
I don't think so, maybe copypaste can produce it.
I guess yes, why writing more symbol noise if you can write less symbol noise. This is true for other optional stuff like trailing separators or |
Arbitrarily large lookahead is required to discern between generic arguments and comparisons in expressions in general case. |
Quick note: could we detect use of this outside a macro, and warn that you should drop the |
(Checking off @pnkfelix's box while he's on PTO). |
I'd like to have an error-by-default lint against this which is turned off in macros, to discourage it ever appearing in surface code. @petrochenkov how burdensome would that be to implement? |
@withoutboats |
@petrochenkov I'd prefer in rustc, and I'm fine with warn by default. |
@withoutboats I would expect to accept both silently, but normalize in rustfmt. I am skeptical of the very concept of an error-by-default lint, and certainly skeptical of using it for style issues. |
It also predates me, but yes -- the constraint against infinite lookahead was (and still is, so far) taken as a hard constraint, and the assumption (which is true) was that I suspect that without |
@withoutboats I agree the motivation is not spelled out very strongly. I think the use case would be: "a macro that accepts a path that will be used for both a type and a path to the constructor". This may in general require type parameters. Put another way, without this, macros really need "type path" and "item path" as two distinct things. They may need that anyway, mind you. |
Ping @withoutboats, are you ready to tick your box? |
I'll tick my box. Really want to see a lint against this though! |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
23322cc
to
804459b
Compare
@withoutboats |
Hmm, a hard-coded warning seems .. unfortunate, no? i.e., the whole point of allowing it is that we expect it to sometimes be used, e.g. in a macro expansion? (But I guess I have to look more closely at when the warning fires...) |
The warning is not reported when a path is passed to a macro, only when we are certainly parsing a type path. |
@petrochenkov but would the warning fire after macro expansion, presuming that a |
@nikomatsakis |
@petrochenkov I see. OK. I'm not a big fan of unconditional warnings, and I tend to agree with you that developers will not intentionally write extra |
The final comment period is now complete. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the code looks fine.
@bors r+ |
📌 Commit 804459b has been approved by |
syntax: Relax path grammar TLDR: Accept the disambiguator `::` in "type" paths (`Type::<Args>`), accept the disambiguator `::` before parenthesized generic arguments (`Fn::(Args)`). The "turbofish" disambiguator `::<>` in expression paths is a necessary evil required for path parsing to be both simple and to give reasonable results. Since paths in expressions usually refer to values (but not necessarily, e.g. `Struct::<u8> { field: 0 }` is disambiguated, but refers to a type), people often consider `::<>` to be inherent to *values*, and not *expressions* and want to write disambiguated paths for values even in contexts where disambiguation is not strictly necessary, for example when a path is passed to a macro `m!(Vec::<i32>::new)`. The problem is that currently, if the disambiguator is not *required*, then it's *prohibited*. This results in confusion - see #41740, https://internals.rust-lang.org/t/macro-path-uses-novel-syntax/5561. This PR makes the disambiguator *optional* instead of prohibited in contexts where it's not strictly required, so people can pass paths to macros in whatever form they consider natural (e.g. disambiguated form for value paths). This PR also accepts the disambiguator in paths with parenthesized arguments (`Fn::(Args)`) for consistency and to simplify testing of stuff like #41856 (comment). Closes #41740 cc @rust-lang/lang r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
Changelog: Version 1.21.0 (2017-10-12) ========================== Language -------- - [You can now use static references for literals.][43838] Example: ```rust fn main() { let x: &'static u32 = &0; } ``` - [Relaxed path syntax. Optional `::` before `<` is now allowed in all contexts.][43540] Example: ```rust my_macro!(Vec<i32>::new); // Always worked my_macro!(Vec::<i32>::new); // Now works ``` Compiler -------- - [Upgraded jemalloc to 4.5.0][43911] - [Enabled unwinding panics on Redox][43917] - [Now runs LLVM in parallel during translation phase.][43506] This should reduce peak memory usage. Libraries --------- - [Generate builtin impls for `Clone` for all arrays and tuples that are `T: Clone`][43690] - [`Stdin`, `Stdout`, and `Stderr` now implement `AsRawFd`.][43459] - [`Rc` and `Arc` now implement `From<&[T]> where T: Clone`, `From<str>`, `From<String>`, `From<Box<T>> where T: ?Sized`, and `From<Vec<T>>`.][42565] Stabilized APIs --------------- [`std::mem::discriminant`] Cargo ----- - [You can now call `cargo install` with multiple package names][cargo/4216] - [Cargo commands inside a virtual workspace will now implicitly pass `--all`][cargo/4335] - [Added a `[patch]` section to `Cargo.toml` to handle prepublication dependencies][cargo/4123] [RFC 1969] - [`include` & `exclude` fields in `Cargo.toml` now accept gitignore like patterns][cargo/4270] - [Added the `--all-targets` option][cargo/4400] - [Using required dependencies as a feature is now deprecated and emits a warning][cargo/4364] Misc ---- - [Cargo docs are moving][43916] to [doc.rust-lang.org/cargo](https://doc.rust-lang.org/cargo) - [The rustdoc book is now available][43863] at [doc.rust-lang.org/rustdoc](https://doc.rust-lang.org/rustdoc) - [Added a preview of RLS has been made available through rustup][44204] Install with `rustup component add rls-preview` - [`std::os` documentation for Unix, Linux, and Windows now appears on doc.rust-lang.org][43348] Previously only showed `std::os::unix`. Compatibility Notes ------------------- - [Changes in method matching against higher-ranked types][43880] This may cause breakage in subtyping corner cases. [A more in-depth explanation is available.][info/43880] - [rustc's JSON error output's byte position start at top of file.][42973] Was previously relative to the rustc's internal `CodeMap` struct which required the unstable library `libsyntax` to correctly use. - [`unused_results` lint no longer ignores booleans][43728] [42565]: rust-lang/rust#42565 [42973]: rust-lang/rust#42973 [43348]: rust-lang/rust#43348 [43459]: rust-lang/rust#43459 [43506]: rust-lang/rust#43506 [43540]: rust-lang/rust#43540 [43690]: rust-lang/rust#43690 [43728]: rust-lang/rust#43728 [43838]: rust-lang/rust#43838 [43863]: rust-lang/rust#43863 [43880]: rust-lang/rust#43880 [43911]: rust-lang/rust#43911 [43916]: rust-lang/rust#43916 [43917]: rust-lang/rust#43917 [44204]: rust-lang/rust#44204 [cargo/4123]: rust-lang/cargo#4123 [cargo/4216]: rust-lang/cargo#4216 [cargo/4270]: rust-lang/cargo#4270 [cargo/4335]: rust-lang/cargo#4335 [cargo/4364]: rust-lang/cargo#4364 [cargo/4400]: rust-lang/cargo#4400 [RFC 1969]: rust-lang/rfcs#1969 [info/43880]: rust-lang/rust#44224 (comment) [`std::mem::discriminant`]: https://doc.rust-lang.org/std/mem/fn.discriminant.html
syntax: Remove warning for unnecessary path disambiguators `rustfmt` is now stable and it removes unnecessary turbofishes, so removing the warning as discussed in rust-lang#43540 (where it was introduced). One hardcoded warning less. Closes rust-lang#58055 r? @nikomatsakis
syntax: Remove warning for unnecessary path disambiguators `rustfmt` is now stable and it removes unnecessary turbofishes, so removing the warning as discussed in rust-lang#43540 (where it was introduced). One hardcoded warning less. Closes rust-lang#58055 r? @nikomatsakis
syntax: Remove warning for unnecessary path disambiguators `rustfmt` is now stable and it removes unnecessary turbofishes, so removing the warning as discussed in rust-lang#43540 (where it was introduced). One hardcoded warning less. Closes rust-lang#58055 r? @nikomatsakis
syntax: Remove warning for unnecessary path disambiguators `rustfmt` is now stable and it removes unnecessary turbofishes, so removing the warning as discussed in rust-lang#43540 (where it was introduced). One hardcoded warning less. Closes rust-lang#58055 r? @nikomatsakis
4667: GRAM: fix type path parsing r=vlad20012 a=Undin After rust-lang/rust#43540 disambiguator `::` is allowed in "type" paths. But our grammar forbade it previously because it had been written before the corresponding changes in rustc. These changes fix the grammar. Also, they highlight redundant `::` in type paths and provide fix to remove it ![2019-11-21 11 25 22](https://user-images.githubusercontent.com/2539310/69320139-a5193b80-0c51-11ea-85ba-2ddfe0a41fcb.gif) Fixes #4430 Co-authored-by: Arseniy Pendryak <[email protected]>
4667: GRAM: fix type path parsing r=vlad20012 a=Undin After rust-lang/rust#43540 disambiguator `::` is allowed in "type" paths. But our grammar forbade it previously because it had been written before the corresponding changes in rustc. These changes fix the grammar. Also, they highlight redundant `::` in type paths and provide fix to remove it ![2019-11-21 11 25 22](https://user-images.githubusercontent.com/2539310/69320139-a5193b80-0c51-11ea-85ba-2ddfe0a41fcb.gif) Fixes #4430 Co-authored-by: Arseniy Pendryak <[email protected]>
TLDR: Accept the disambiguator
::
in "type" paths (Type::<Args>
), accept the disambiguator::
before parenthesized generic arguments (Fn::(Args)
).The "turbofish" disambiguator
::<>
in expression paths is a necessary evil required for path parsing to be both simple and to give reasonable results.Since paths in expressions usually refer to values (but not necessarily, e.g.
Struct::<u8> { field: 0 }
is disambiguated, but refers to a type), people often consider::<>
to be inherent to values, and not expressions and want to write disambiguated paths for values even in contexts where disambiguation is not strictly necessary, for example when a path is passed to a macrom!(Vec::<i32>::new)
.The problem is that currently, if the disambiguator is not required, then it's prohibited. This results in confusion - see #41740, https://internals.rust-lang.org/t/macro-path-uses-novel-syntax/5561.
This PR makes the disambiguator optional instead of prohibited in contexts where it's not strictly required, so people can pass paths to macros in whatever form they consider natural (e.g. disambiguated form for value paths).
This PR also accepts the disambiguator in paths with parenthesized arguments (
Fn::(Args)
) for consistency and to simplify testing of stuff like #41856 (comment).Closes #41740
cc @rust-lang/lang
r? @nikomatsakis