Refactor parsing of trait object types#40043
Conversation
|
☔ The latest upstream changes (presumably #39419) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Rebased. |
|
@petrochenkov these changes look good to me. Sorry for delay. Will queue up a crater run. |
|
Regression report: https://gist.github.com/nikomatsakis/42c2e8f0ff770878fed845d93c53c05e
So, I think we should fix the parenthesis thing. Not sure what to do about the precedence of |
|
@nikomatsakis
Yeah, I'll send patches to affected crates. |
|
Updated with a warning instead of an error for |
|
@petrochenkov I'm not sure I agree that |
But... that's not true (the lifetime in |
src/libsyntax/parse/parser.rs
Outdated
There was a problem hiding this comment.
in what sense is this a "future-compatiblity warning"?
There was a problem hiding this comment.
specifically, it doesn't seem to mention anything about the future? (and there is no associated tracking issue, right?)
There was a problem hiding this comment.
I repurposed #39318 as a tracking issue, I'll link to it.
|
@petrochenkov Hmm, first, it's not clear that cc @rust-lang/lang -- some questions here about the finer points of our grammar |
That's what I originally did, but then added 63c5c0d just to be conservative and not accept a single lifetime in |
I can't think of any problems, but it feels like we've already made our bed here. As useless as this is, philosophically it seems like a type like This becomes more material in light of rust-lang/rfcs#1733, which would presumably allow these through an alias even if they're ungrammatical directly. That is, this would compile: trait Static = 'static;
fn foo(_: Box<Static>) { }So why wouldn't this? fn foo(_: Box<'static>) { } |
|
Sigh, I hadn't considered the parsing ambiguity here:
But it can be resolved easily enough via some kind of rules that require an explicit paren, I guess, or something. |
Well, this could be considered not object safe, if we had a rule that there must be at least 1 actionable trait or something. |
That's true. I'm okay with that if parsing these types is too complex. |
|
In @rust-lang/compiler meeting, we decided not to beta-backport this: it's a big change, and it doesn't really seem to fix anything tagged as regressions, except for #39318 -- and we're still debating what's the desired behavior here (and it would have a warning period anyhow). |
|
VVV Nevertheless, this is all very strange
|
To be honest, I find this surprising, too.
I read a trait object as |
This is a model dictated by limitations of the current implementation - it is quite reasonable to expect |
|
@petrochenkov Multiple trait object support would definitely change how I think about this, although I would recommend always putting the traits with methods first in the list.
Yeah, that's fair. I do see the sense in relaxing the parsing rules and/or making them more consistent. I'm basically just saying the restriction isn't very strange from a user point-of-view. |
|
Well, I guess my sense is that if I suppose that if we adopted the |
|
So I've just discovered that this is valid: fn foo<'a, T: 'a + ToString>() { }I think trait object syntax should be consistent with bounds syntax, so |
|
@bors r+ |
|
📌 Commit 803e76c has been approved by |
|
🔒 Merge conflict |
|
@bors r=nikomatsakis |
|
📌 Commit b5e8897 has been approved by |
Refactor parsing of trait object types Bugs are fixed and code is cleaned up. User visible changes: - `ty` matcher in macros accepts trait object types like `Write + Send` (#39080) - Buggy priority of `+` in trait object types starting with `for` is fixed (#39317). `&for<'a> Trait<'a> + Send` is now parsed as `(&for<'a> Trait<'a>) + Send` and requires parens `&(for<'a> Trait<'a> + Send)`. For comparison, `&Send + for<'a> Trait<'a>` was parsed like this since [Nov 27, 2014](#19298). - Trailing `+`s are supported in trait objects, like in other bounds. - Better error reporting for trait objects starting with `?Sized`. Fixes #39080 Fixes #39317 [breaking-change] Closes #39298 cc #39085 (fixed, then reverted #40043 (comment)) cc #39318 (fixed, then reverted #40043 (comment)) r? @nikomatsakis
|
☀️ Test successful - status-appveyor, status-travis |
The merge of rust-lang/rust#40043 removes parse_ty_path in the latest nightly, which we depended on. This patch rewrites that code path using parse_path, and in the process eliminates an unreachable!() if let arm.
The merge of rust-lang/rust#40043 removes parse_ty_path in the latest nightly, which we depended on. This patch rewrites that code path using parse_path, and in the process eliminates an unreachable!() if let arm.
syntax: Parse trait object types starting with a lifetime bound Fixes #39085 This was originally implemented in #40043, then reverted, then there was some [agreement](#39318 (comment)) that it should be supported. (This is hopefully the last PR related to bound parsing.)
Bugs are fixed and code is cleaned up.
User visible changes:
tymatcher in macros accepts trait object types likeWrite + Send(macros:tymatcher doesn't accept trait object types with+(type sums) #39080)+in trait object types starting withforis fixed (syntax:+has incorrect priority in trait object types starting withfor#39317).&for<'a> Trait<'a> + Sendis now parsed as(&for<'a> Trait<'a>) + Sendand requires parens&(for<'a> Trait<'a> + Send). For comparison,&Send + for<'a> Trait<'a>was parsed like this since Nov 27, 2014.+s are supported in trait objects, like in other bounds.?Sized.Fixes #39080
Fixes #39317 [breaking-change]
Closes #39298
cc #39085 (fixed, then reverted #40043 (comment))
cc #39318 (fixed, then reverted #40043 (comment))
r? @nikomatsakis