-
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
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
let ty = ts.into_iter().nth(0).unwrap().unwrap(); | ||
match ty.node { | ||
// Accept `(Trait1) + Trait2 + 'a` for now, | ||
// but issue a future compatibility warning. |
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.
in what sense is this a "future-compatiblity warning"?
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
ty
matcher in macros accepts trait object types likeWrite + Send
(macros:ty
matcher doesn't accept trait object types with+
(type sums) #39080)+
in trait object types starting withfor
is fixed (syntax:+
has incorrect priority in trait object types starting withfor
#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.+
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