Uh oh!
There was an error while loading. Please reload this page.
Learn to parse a as usize < b - #42578
Conversation
rust-highfive
commented
Jun 10, 2017
(rust_highfive has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
Is it possible to use mk _ty here? Or is the DUMMY_NODE_ID intentional?
There was a problem hiding this comment.
mk_ty is part of TyCtxt which isn't available yet. This was extracted from parse_ty_common in order to see if this would work at all. I could modify parse_ty_common for this case, but I felt it would muddy the logic of that method.
I'd be okay with this if the unbounded lookahead and parser state saving/restoring machinery were used only for reporting better diagnostics, recovery and fix-it suggestions, not for actually accepting the code. |
Mark-Simulacrum
commented
Jun 11, 2017
Looks like there are some test failures in Travis: https://travis-ci.org/rust-lang/rust/jobs/241424157#L1853, though addressing @petrochenkov's concern first seems like a good idea. |
estebank
commented
Jun 11, 2017
Should Having said that, what would be your preferred output if this were used only for diagnostics? Something like this? |
Parsing `a as usize > b` always works, but `a as usize < b` was a parsing error because the parser would think the `<` started a generic type argument for `usize`. The parser now attempts to parse as before, and if a DiagnosticError is returned, try to parse again as a type with no generic arguments. If this fails, return the original `DiagnosticError`.
petrochenkov
commented
Jun 11, 2017
A specially crafted error would be the best, IMO. After this is reported as a non-fatal error, AST is build as if |
petrochenkov
commented
Jun 11, 2017
It's an edge case, but it has large effect on properties of the grammar as a whole. |
petrochenkov
commented
Jun 11, 2017
|
```
warning: `<` is interpreted as a start of generic arguments for `usize`, not comparison
--> $DIR/issue-22644.rs:16:33
|
16 | println!("{}", a as usize < b);
| ^ expected one of `!`, `(`, `+`, `,`, `::`, or `>` here
|
help: if you want to compare the casted value then write
| println!("{}", (a as usize) < b);
```e53c7a1 to
803d323Compare
I understand and completely agree.
I think I prefer the former, as it'd be less surprising for a newcomer. I got something working which accepts the code as proposed but also emits a warning suggesting a correction.
This is how it looks like right now: |
There was a problem hiding this comment.
Could you make this a struct with field names?
```
warning: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:16:33
|
16 | println!("{}", a as usize < b);
| - ^ interpreted as generic argument
| |
| not interpreted as comparison
|
help: if you want to compare the casted value then write:
| println!("{}", (a as usize) < b);
```nikomatsakis
commented
Jun 12, 2017
As long as we're not changing the grammar, I'm happy if @petrochenkov is happy =) |
nikomatsakis
commented
Jun 12, 2017
@nikomatsakis just to be clear, the code as is accepts it under the assumption that it is correct and only emits a |
| // Parse types, optionally. | ||
| let parameters = if self.eat_lt() { | ||
| let parameters = if self.is_lt() && !dont_parse_generics { |
There was a problem hiding this comment.
if !dont_parse_generics && self.eat_lt() {
&& doesnt run second arg when first arg is false.
There was a problem hiding this comment.
👍
This also makes fn is_lt unnecessary
EDIT: ... and keeps < in the expected set.
nikomatsakis
commented
Jun 13, 2017
Accepts what exactly? And what do you mean by "as is"? You mean, in the PR, or in master? |
estebank
commented
Jun 13, 2017
@nikomatsakis The PR accepts |
| /// - `a::b<T,U>::c(V) -> W` | ||
| /// - `a::b<T,U>::c(V)` | ||
| pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<PathSegment>> { | ||
| pub fn parse_path_segments_without_colons(&mut self, dont_parse_generics: bool) |
There was a problem hiding this comment.
Nit: dont_parse_generics: bool -> parse_generics: bool
| ExprKind::Cast(lhs, rhs), ThinVec::new()); | ||
| } | ||
| Err(mut err) => { | ||
| // Rewind to before attempting to parse the type with generics, to get |
There was a problem hiding this comment.
Could you move the error handling logic into a separate function?
nikomatsakis
commented
Jun 14, 2017
Huh, I'm confused. After all, you can do |
petrochenkov
commented
Jun 15, 2017
r=me with stray note removed. |
- generate error instead of warning - remove `RewindPoint` and just keep a copy of `Parser` to rewind state. - `dont_parse_generics: bool` -> `parse_generics: bool` - remove `eat_lt` - move error handling code to separate method
estebank
commented
Jun 15, 2017
@petrochenkov done @bors r=petrochenkov |
bors
commented
Jun 15, 2017
📌 Commit ad260ff has been approved by |
nikomatsakis
commented
Jun 15, 2017
@bors r- |
nikomatsakis
commented
Jun 15, 2017
I'd like to know if this is changing the grammar that is accepted. I feel like I still don't understand quite what's happening here. =) |
In particular, do we now compile (successfully) more programs than we did before? If so, what set of programs? |
estebank
commented
Jun 15, 2017
@nikomatsakis The first commit of this PR changed the accepted grammar and only emitted a warning. I changed it back to not have any changes in the grammar and emit an error. The parser state changes slightly after finding this case in order to continue parsing successfully the rest of the file (before this PR the rest of the file would not get any diagnostics). No new set of programs will be accepted, the new behaviors are:
|
nikomatsakis
commented
Jun 15, 2017
@estebank perfect =) |
nikomatsakis
commented
Jun 15, 2017
@bors r+ |
bors
commented
Jun 15, 2017
📌 Commit ad260ff has been approved by |
bors
commented
Jun 16, 2017
Learn to parse `a as usize < b` Parsing `a as usize > b` always works, but `a as usize < b` was a parsing error because the parser would think the `<` started a generic type argument for `usize`. The parser now attempts to parse as before, and if a DiagnosticError is returned, try to parse again as a type with no generic arguments. If this fails, return the original `DiagnosticError`. Fix#22644.
bors
commented
Jun 16, 2017
☀️ Test successful - status-appveyor, status-travis |
Add a nicer error message for missing in for loop, fixesrust-lang#40782. As suggested by @estebank in issue rust-lang#40782, this works in the same way as rust-lang#42578: if the in keyword is missing, we continue parsing the expression and if this works correctly an adapted error message is produced. Otherwise we return the old error. A specific test case has also been added. This is my first PR on rust-lang/rust so any feedback is very welcome.
44100hertz
commented
Dec 17, 2017
One last thing: error: `<` is interpreted as a start of generic arguments for `u16`, not a comparison --> /tmp/angle.rs:4:29 | 4 | println!("{}", x asu16 << 4); | -------- ^^ - interpreted as generic arguments | | | | | not interpreted ascomparison | help: try comparing the casted value: `(x asu16)` |
petrochenkov
commented
Dec 17, 2017
@Hertz4 |
Parsing
a as usize > balways works, buta as usize < bwas aparsing error because the parser would think the
<started a generictype argument for
usize. The parser now attempts to parse as before,and if a DiagnosticError is returned, try to parse again as a type with
no generic arguments. If this fails, return the original
DiagnosticError.Fix#22644.