Skip to content

Weird diagnostic when typing a . instead of a , #44339

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

Closed
oli-obk opened this issue Sep 5, 2017 · 8 comments
Closed

Weird diagnostic when typing a . instead of a , #44339

oli-obk opened this issue Sep 5, 2017 · 8 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics

Comments

@oli-obk
Copy link
Contributor

oli-obk commented Sep 5, 2017

Compiling

use std::{foo. bar};
fn main() {}

yields

error: expected one of `,` or `as`, found `.`
 --> src/main.rs:2:14
  |
2 | use std::{foo. bar};
  |              ^ expected one of `,` or `as` here

error: expected one of `;` or `as`, found `.`
 --> src/main.rs:2:14
  |
2 | use std::{foo. bar};
  |              ^ expected one of `;` or `as` here

error: aborting due to 2 previous errors

The first error makes sense, but the second one seems pretty bogus to me.

@Freyskeyd
Copy link
Contributor

Yes I agree, I will take a look at the code.

@TimNN TimNN added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 17, 2017
@estebank
Copy link
Contributor

estebank commented Sep 21, 2017

I could have sworn that there was a dupe for this ticket.

parse_view_path parses only the path of an use statement. It uses parse_path_list_items to parse the contents within braces ({...}). This ends up calling parse_unspanned_seq, which uses parse_seq_to_before_end that just raises errors when it finds them, but you can use parse_seq_to_before_tokens which lets you provide a closure/fn to handle errors. With this you could keep a hashmap of spans, only emit one per span and cancel the rest.

We could go the extra mile and 1) try to be eager in what is accepted by attempting to parse the idents regardless and when finding errors skipping until the next thing that looks like an ident or }, and 2) suggest using commas in these places.

@estebank estebank added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Sep 21, 2017
@nikomatsakis nikomatsakis added the WG-diagnostics Working group: Diagnostics label Sep 25, 2017
@nikomatsakis
Copy link
Contributor

Another example, from #33188 (closed as a duplicate of this issue):

Compiling the following:

struct S(pub () ());

produces:

<anon>:1:17: 1:18 error: expected one of `+` or `,`, found `(`
<anon>:1 struct S(pub () ());
                         ^
<anon>:1:17: 1:18 error: expected one of `+`, `;`, or `where`, found `(`
<anon>:1 struct S(pub () ());
                         ^

@thombles
Copy link
Contributor

Hi, I'm working on solving this now

@estebank
Copy link
Contributor

@thombles, great! You probably want to modify parse_seq_to_before_end to collect all the errors (by passing a closure that captures a hashmap in that method's body to parse_seq_to_before_tokens, and compare the spans to only emit once per span. This should catch all these cases then.

@thombles
Copy link
Contributor

I've replaced parse_seq_to_before_end with my own function. It turns out it is only responsible for the first emit(), so my HashSet isn't doing any good. Not sure where the second one is coming from yet but I'll track it down.

@estebank
Copy link
Contributor

estebank commented Oct 1, 2017

I see. Let me know if you need any help tracking it down.

@thombles
Copy link
Contributor

I have a new solution coming together. I think it will need to be fairly conservative. The basic problem is that parse_seq_to_before_tokens aborts as soon as it hits a separator error. The calling code assumes that we've parsed up to the end of the sequence when really we're still in the middle of it and this creates new and confusing errors.

The general improvement is to make parse_seq_to_before_tokens consume up to the end of the sequence even when it suffers an error, where possible. This works well. A bit too well.

use std::{foo. bar}; // consumes up to }. Great!
callback(path.as_ref(); // proceeds to next line until it finds ) - Not good. Even worse errors.

So I think we can handle two cases:

  1. Missing separators like struct S(pub () ()); - if the "separator" actually parses as a sequence value, emit the error, then attempt to continue.
  2. Specific hard-coded wrong characters like use std::{foo. bar};. This was suggested by @petrochenkov in reviewing my first PR. i.e., if we're looking for a , and find a . we will emit an error and continue, but if we find a ; then we need to terminate immediately. It's more likely that the ket is missing and we don't want to eat the following tokens.

I'm working towards a new pull request but I thought I'd write this up here in case anyone has any thoughts!

bors added a commit that referenced this issue Oct 28, 2017
Improve diagnostics when list of tokens has incorrect separators

Make `parse_seq_to_before_tokens` more resilient to error conditions. Where possible it is better if it can consume up to the final bracket before returning. This change improves the diagnostics in a couple of situations:

```
struct S(pub () ()); // omitted separator
use std::{foo. bar}; // used a similar but wrong separator
```

Fixes #44339
r? @petrochenkov
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

No branches or pull requests

7 participants