about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_resolve/lib.rs34
-rw-r--r--src/test/ui/error-codes/E0423.rs19
-rw-r--r--src/test/ui/error-codes/E0423.stderr43
3 files changed, 92 insertions, 4 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 453627f3c36..7bb7f2fffbc 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 f5fea77cf96..7d71499d318 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 ef24295332d..477c698ac9a 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`.