diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 453627f3c36b9..7bb7f2fffbc69 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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); } diff --git a/src/test/ui/error-codes/E0423.rs b/src/test/ui/error-codes/E0423.rs index f5fea77cf9639..7d71499d3186b 100644 --- a/src/test/ui/error-codes/E0423.rs +++ b/src/test/ui/error-codes/E0423.rs @@ -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` +} diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index ef24295332d51..477c698ac9af1 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -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[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 previous error +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0423`.