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

Errormessage regarding curly braces in for statement #42982

Closed
Bendrien opened this issue Jun 30, 2017 · 3 comments
Closed

Errormessage regarding curly braces in for statement #42982

Bendrien opened this issue Jun 30, 2017 · 3 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST 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. WG-diagnostics Working group: Diagnostics

Comments

@Bendrien
Copy link

Bendrien commented Jun 30, 2017

I got the following code:

struct StructWithCurlyBraces {
    _foo: usize
}

impl Iterator for StructWithCurlyBraces {
    type Item = ();
    
    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}

pub fn main() {
    // with surrounding parentheses it works
    for _ in (StructWithCurlyBraces { _foo: 42 }) { }
    
    // without it doesn't
    for _ in StructWithCurlyBraces { _foo: 42 } { }
}

I don't know if the case without surrounding parentheses is intended to work but apart from that the error message is somewhat missleading.

error: expected type, found `42`
  --> <anon>:18:44
   |
18 |     for _ in StructWithCurlyBraces { _foo: 42 } { }
   |                                            ^^

error[E0423]: expected value, found struct `StructWithCurlyBraces`
  --> <anon>:18:14
   |
18 |     for _ in StructWithCurlyBraces { _foo: 42 } { }
   |              ^^^^^^^^^^^^^^^^^^^^^ did you mean `StructWithCurlyBraces { /* fields */ }`?

error: aborting due to 2 previous errors

It seems that the tokenizer doesn't get this right?

Edit: Include error message

@Mark-Simulacrum Mark-Simulacrum added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Jul 19, 2017
@fintelia
Copy link
Contributor

The same thing happens with an if statement:

struct X {}
if let X {} = X {} {}
error[E0423]: expected value, found struct `X`
  |
4 |     if let X {} = X {} {}
  |                   ^ did you mean `X { /* fields */ }`?

@estebank estebank added the A-parser Area: The parsing of Rust source code to an AST label Dec 12, 2017
@estebank
Copy link
Contributor

The parser cannot differentiate between a struct literal and a "path" (a variable) followed by a block in these places. There's no way to do so at parse time, as you don't yet know wether the found path is a struct so it could be parsed as such, so the parser just flat out doesn't allow that construct.

What could be improved is

  1. not suggesting the struct literal (remove the "did you mean..." if tcx.sess.get_parent_node(id) is an if/while/for statement)

  2. suggesting this instead:

error[E0423]: expected value, found struct `X`
  |
4 |     if let X {} = X {} {}
  |                   ^
help: if you wanted to use a literal struct constructor here, try surrounding it with parenthesis
4 |     if let X {} = (X {}) {}
  |                   ^^^^^^

The second would be harder as at this point the compiler already decided that we meant X as the struct itself, not as the struct constructor, so we do not know where the span for its block ends, if it would parse correctly as such and even if does end. Instead of the suggestion a help could be displayed instead of the current suggestion stating something along the lines of "struct literals are forbidden here due to ambiguous parsing, surround with parenthesis to avoid this".

@estebank estebank added E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. WG-diagnostics Working group: Diagnostics labels Dec 13, 2017
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Jun 8, 2018
…cts, r=nikomatsakis

Suggest parentheses when a struct literal needs them

When writing a struct literal in an expression that expects a block to
be started afterwards (like an `if` statement), do not suggest using the
same struct literal:

```
did you mean `S { /* fields * /}`?
```

Instead, suggest surrounding the expression with parentheses:

```
did you mean `(S { /* fields * /})`?
```

Fix rust-lang#47360, rust-lang#50090. Leaving rust-lang#42982 open to come back to this problem with a better solution.
@estebank
Copy link
Contributor

Fixed by #51360, #59981 and #60118

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 A-parser Area: The parsing of Rust source code to an AST 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. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

No branches or pull requests

4 participants