Suggest braces 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 * /})`? ```
This commit is contained in:
parent
41affd03eb
commit
377cf44b4e
3 changed files with 92 additions and 4 deletions
|
@ -2934,8 +2934,38 @@ impl<'a> Resolver<'a> {
|
|||
here due to private fields"));
|
||||
}
|
||||
} else {
|
||||
err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
|
||||
path_str));
|
||||
// HACK(estebank): find a better way to figure out that this was a
|
||||
// parser issue where a struct literal is being used on an expression
|
||||
// where a brace being opened means a block is being started. Look
|
||||
// ahead for the next text to see if `span` is followed by a `{`.
|
||||
let cm = this.session.codemap();
|
||||
let mut sp = span;
|
||||
loop {
|
||||
sp = cm.next_point(sp);
|
||||
match cm.span_to_snippet(sp) {
|
||||
Ok(ref snippet) => {
|
||||
if snippet.chars().any(|c| { !c.is_whitespace() }) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
let followed_by_brace = match cm.span_to_snippet(sp) {
|
||||
Ok(ref snippet) if snippet == "{" => true,
|
||||
_ => false,
|
||||
};
|
||||
if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
|
||||
err.span_label(
|
||||
span,
|
||||
format!("did you mean `({} {{ /* fields */ }})`?", path_str),
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
span,
|
||||
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
|
||||
);
|
||||
}
|
||||
}
|
||||
return (err, candidates);
|
||||
}
|
||||
|
|
|
@ -13,3 +13,22 @@ fn main () {
|
|||
|
||||
let f = Foo(); //~ ERROR E0423
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
struct S { x: i32, y: i32 }
|
||||
#[derive(PartialEq)]
|
||||
struct T {}
|
||||
|
||||
if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
|
||||
//~^ ERROR E0423
|
||||
//~| expected type, found `1`
|
||||
if T {} == T {} { println!("Ok"); }
|
||||
//~^ ERROR E0423
|
||||
//~| ERROR expected expression, found `==`
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
for _ in std::ops::Range { start: 0, end: 10 } {}
|
||||
//~^ ERROR E0423
|
||||
//~| ERROR expected type, found `0`
|
||||
}
|
||||
|
|
|
@ -1,9 +1,48 @@
|
|||
error: expected type, found `1`
|
||||
--> $DIR/E0423.rs:22:39
|
||||
|
|
||||
LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
|
||||
| ^ expecting a type here because of type ascription
|
||||
|
||||
error: expected expression, found `==`
|
||||
--> $DIR/E0423.rs:25:13
|
||||
|
|
||||
LL | if T {} == T {} { println!("Ok"); }
|
||||
| ^^ expected expression
|
||||
|
||||
error: expected type, found `0`
|
||||
--> $DIR/E0423.rs:31:39
|
||||
|
|
||||
LL | for _ in std::ops::Range { start: 0, end: 10 } {}
|
||||
| ^ expecting a type here because of type ascription
|
||||
|
||||
error[E0423]: expected function, found struct `Foo`
|
||||
--> $DIR/E0423.rs:14:13
|
||||
|
|
||||
LL | let f = Foo(); //~ ERROR E0423
|
||||
| ^^^ did you mean `Foo { /* fields */ }`?
|
||||
| ^^^
|
||||
| |
|
||||
| did you mean `foo`?
|
||||
| did you mean `Foo { /* fields */ }`?
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0423]: expected value, found struct `S`
|
||||
--> $DIR/E0423.rs:22:32
|
||||
|
|
||||
LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
|
||||
| ^ did you mean `(S { /* fields */ })`?
|
||||
|
||||
error[E0423]: expected value, found struct `T`
|
||||
--> $DIR/E0423.rs:25:8
|
||||
|
|
||||
LL | if T {} == T {} { println!("Ok"); }
|
||||
| ^ did you mean `(T { /* fields */ })`?
|
||||
|
||||
error[E0423]: expected value, found struct `std::ops::Range`
|
||||
--> $DIR/E0423.rs:31:14
|
||||
|
|
||||
LL | for _ in std::ops::Range { start: 0, end: 10 } {}
|
||||
| ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`?
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0423`.
|
||||
|
|
Loading…
Add table
Reference in a new issue