Skip to content
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 error on trait fns with destructured args #2847

Closed
tobz1000 opened this issue Jan 14, 2020 · 4 comments · Fixed by #3040
Closed

Syntax error on trait fns with destructured args #2847

tobz1000 opened this issue Jan 14, 2020 · 4 comments · Fixed by #3040

Comments

@tobz1000
Copy link
Contributor

tobz1000 commented Jan 14, 2020

Trait functions with destructured arguments do not parse successfully. Some examples:

struct S { a: usize, b: usize }
struct NewType(usize);

trait T {
    // Syntax Error: expected COMMA/expected type
    fn f1((a, b): (usize, usize)) {}

    // Syntax Error: expected COMMA/expected value parameter/expected R_PAREN...
    fn f2(S { a, b }: S) {}

    // Syntax Error: expected COMMA
    fn f4(NewType(a): NewType) {}

    // Syntax Error: expected COMMA
    fn f3(&&a: &&usize) {}
}

These all parse okay as free-standing functions, or in a type impl-block.

The double-deref example is mentioned here, so apologies if this is a known issue.

Running in VS Code, built from commit ea0ee8e.

@tobz1000
Copy link
Contributor Author

tobz1000 commented Feb 4, 2020

It looks like the problem is within params::param_list_opt_patterns - because trait functions are parsed as having optional parameter bindings.

The parser looks ahead by 4 tokens for one of the following sequences before parsing a pattern:

  • _:
  • foo:
  • mut foo:
  • &foo:
  • &mut foo:

Anything else, and it will just attempt to parse a type.

To detect anything more complex, it looks as though it needs to perform something close to the actual pattern::pattern(...) routine, but on encountering an error, backtracking and parsing just as a type instead.

I haven't seen any other examples of backtracking/"retrying" in this fashion, although I'm not too familiar with the project as a whole.

@matklad
Copy link
Member

matklad commented Feb 4, 2020

Lol, TIL that my first Rust RFC is actually implemented: rust-lang/rfcs#1685

How could I have missed that?

I think the best thing to do would be to support only 2018 edition and always parse patterns in arguments as required, removing the old lookahead special case.

@tobz1000
Copy link
Contributor Author

tobz1000 commented Feb 4, 2020

Okay - does rust-analyzer generally not support 2015, or is it an just an acceptable lack of coverage in this case?

I'd be happy to put up a PR in the next day or so for this.

@matklad
Copy link
Member

matklad commented Feb 4, 2020 via email

tobz1000 added a commit to tobz1000/rust-analyzer that referenced this issue Feb 4, 2020
tobz1000 added a commit to tobz1000/rust-analyzer that referenced this issue Feb 4, 2020
@bors bors bot closed this as completed in 6d6a995 Feb 7, 2020
@bors bors bot closed this as completed in #3040 Feb 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants