Uh oh!
There was an error while loading. Please reload this page.
Bounds parsing refactoring - #37511
Conversation
Require at least one predicate for a lifetime in a where clause
rust-highfive
commented
Nov 1, 2016
r? @pnkfelix (rust_highfive has picked a reviewer for you, use r? to override) |
| })); | ||
| parsed_something = true; | ||
| } else if self.eat(&token::Eq) { |
There was a problem hiding this comment.
For some reason I can't use else if here: #37510 :(
| return Ok(None); | ||
| } | ||
| let bounds = self.parse_ty_param_bounds(mode)?; |
There was a problem hiding this comment.
I'd rather remove plain parse_ty_param_bounds and leave only the opt version, but unfortunately this wont work for parse_impl_trait_type, because it used a keyword (impl) as an introducing_token, and you can't eat a keyword token. Or can you?
There was a problem hiding this comment.
Or can you?
parser.eat(&token::Ident(keywords::Impl.ident())) should work.
bluss
commented
Nov 1, 2016
This kind of change would normally first have warnings, then enable the breaking change later. |
matklad
commented
Nov 1, 2016
Yep, a warning is a good idea. But perhaps we need a crater run first, to estimate the amount of breakage just in case? Or is crater capable of reporting a diff in warnings? |
bluss
commented
Nov 1, 2016
A deny by default warning works well just for crater (how it was done in /pull/37378 ). That also helps to only catch the actual crates that regress. |
matklad
commented
Nov 2, 2016
And can I emit a deny by default warning directly from the parser? I believe I can't do this in An alternative which I do know should work is to run crater with |
matklad
commented
Nov 7, 2016
@pnkfelix ping :) |
alexcrichton
commented
Nov 10, 2016
@jseyfried you may also be able to take a look and help with review |
| at least one bound in it"); | ||
| } | ||
| if let Some(bounds) = self.parse_opt_ty_param_bounds(&token::Colon, | ||
| BoundParsingMode::Bare)? { |
There was a problem hiding this comment.
If you refactor this to
let opt_bounds = self.parse_opt_ty_param_bounds(&token::Colon,BoundParsingMode::Bare)?;ifletSome(bounds) = opt_bounds {then you can continue using else if below.
jseyfried
commented
Nov 11, 2016
If I understand correctly, there are three separate [breaking-change]s here:
Could someone do a Crater run to determine which of these changes need a warning cycle? |
I haven't read the patch, but always requiring type after |
jseyfried
commented
Nov 11, 2016
I think of |
eddyb
commented
Nov 11, 2016
Started crater run (sorry for the delay). |
eddyb
commented
Nov 11, 2016
Crater report shows 8 regressions (only |
@eddyb I think a macro generating empty lists of bounds could have a legitimate use case, but it looks like the macro-expanded bounds from the Crater run are always empty and can be easily avoided. Also, we already forbid empty lists of bounds in other contexts today. @matklad The all the breakage appears to be due to empty bounds lists after |
I've audited
Basically, I think this should be valid, even if it looks somewhat weird: |
I admit it may be interpreted as addition in type sums like |
matklad
commented
Nov 12, 2016
Looks like it is not clear if empty parameter bounds should be allowed. So I've resurrected #37278 which only fixes a clear bug with lifetimes in the where clause. So I think we need to tag this with T-lang and decide what syntax should be allowed. Here is the status quo: // These are acceptedtraitA:{}fnb<'a:,U:>(){}typeC = for<'a> Clone+;// These are forbidden// bounds on where clauses must be non emptyfnd<T>()whereT:{}// In type grammar, `+` is treated like a binary operator,// and hence both L and R side are required.fne(f:&(A+)){} |
jseyfried
commented
Nov 14, 2016
I'm leaning toward @petrochenkov's proposal to allow empty bounds lists (e.g. @rust-lang/lang do we want to allow empty bounds lists and/or trailing |
bors
commented
Nov 14, 2016
☔ The latest upstream changes (presumably #37278) made this pull request unmergeable. Please resolve the merge conflicts. |
nrc
commented
Nov 15, 2016
IMO we should allow neither empty bounds lists nor trailing |
matklad
commented
Nov 15, 2016
Worth mentioning that currently Valid: Invalid: |
nikomatsakis
commented
Dec 1, 2016
At the @rust-lang/lang meeting recently we settled on:
Sound good? |
matklad
commented
Dec 5, 2016
Yep. Stuff like |
pnkfelix
commented
Dec 22, 2016
@matklad does the current PR encode that semantics yet, or does it need further revision? |
matklad
commented
Dec 23, 2016
@pnkfelix yep, this does not implement the suggestion yet. I'll try to look into that, thanks for the reminder! |
matklad
commented
Jan 10, 2017
Looks like I don't have enough free time after all to actually make a fix :( |
@matklad |
matklad
commented
Jan 11, 2017
@petrochenkov that'd be great! Not sure that rebasing makes sense though: the current implementation is rather different from the final proposal we arrived at! |
petrochenkov
commented
Jan 18, 2017
#39158 is submitted. |
aturon
commented
Jan 26, 2017
Should we close this PR in favor of #39158? |
matklad
commented
Jan 26, 2017
Surely! |
Bounds parsing refactoring 2 See #37511 for previous discussion. cc @matklad Relaxed parsing rules: - zero bounds after `:` are allowed in all contexts. - zero predicates are allowed after `where`. - trailing separator `,` is allowed after predicates in `where` clauses not followed by `{`. Other parsing rules: - trailing separator `+` is still allowed in all bound lists. Code is also cleaned up and tests added. I haven't touched parsing of trait object types yet, I'll do it later.
A follow up of #37278.
parse_opt_ty_param_boundsis introduced to make sure that we don't parse empty bonds. This fixes a couple of bugs along the way, where the check was missing. This is [breaking-change].