about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-04 08:10:41 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2019-12-20 22:53:40 +0100
commit66470d3217f27b5950c38a3af4a99e0ef12fa2c8 (patch)
tree423921e10f1a61276c526800ce6e88f12edb39a1
parentc9e1f13f6eb9d21224c083eb07d894adffc7ec96 (diff)
downloadrust-66470d3217f27b5950c38a3af4a99e0ef12fa2c8.tar.gz
rust-66470d3217f27b5950c38a3af4a99e0ef12fa2c8.zip
recover `#[attr] if expr {}`
-rw-r--r--src/librustc_parse/lib.rs1
-rw-r--r--src/librustc_parse/parser/expr.rs17
-rw-r--r--src/test/ui/parser/recovery-attr-on-if.rs9
-rw-r--r--src/test/ui/parser/recovery-attr-on-if.stderr35
4 files changed, 54 insertions, 8 deletions
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index 58c36524380..3de7f888724 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -2,6 +2,7 @@
 
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
+#![feature(slice_patterns)]
 
 use syntax::ast;
 use syntax::print::pprust;
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 7afa3d665d6..68af34a36bb 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -668,19 +668,20 @@ impl<'a> Parser<'a> {
             expr.map(|mut expr| {
                 attrs.extend::<Vec<_>>(expr.attrs.into());
                 expr.attrs = attrs;
-                match expr.kind {
-                    ExprKind::If(..) if !expr.attrs.is_empty() => {
-                        // Just point to the first attribute in there...
-                        let span = expr.attrs[0].span;
-                        self.span_err(span, "attributes are not yet allowed on `if` expressions");
-                    }
-                    _ => {}
-                }
+                self.error_attr_on_if_expr(&expr);
                 expr
             })
         )
     }
 
+    fn error_attr_on_if_expr(&self, expr: &Expr) {
+        if let (ExprKind::If(..), [a0, ..]) = (&expr.kind, &*expr.attrs) {
+            // Just point to the first attribute in there...
+            self.struct_span_err(a0.span, "attributes are not yet allowed on `if` expressions")
+                .emit();
+        }
+    }
+
     fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
         let mut e = e0;
         let mut hi;
diff --git a/src/test/ui/parser/recovery-attr-on-if.rs b/src/test/ui/parser/recovery-attr-on-if.rs
new file mode 100644
index 00000000000..0d1f5be7b49
--- /dev/null
+++ b/src/test/ui/parser/recovery-attr-on-if.rs
@@ -0,0 +1,9 @@
+fn main() {
+    #[attr] if true {};
+    //~^ ERROR cannot find attribute
+    //~| ERROR attributes are not yet allowed on `if` expressions
+    #[attr] if true {};
+    //~^ ERROR cannot find attribute
+    //~| ERROR attributes are not yet allowed on `if` expressions
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/recovery-attr-on-if.stderr b/src/test/ui/parser/recovery-attr-on-if.stderr
new file mode 100644
index 00000000000..a02846827c9
--- /dev/null
+++ b/src/test/ui/parser/recovery-attr-on-if.stderr
@@ -0,0 +1,35 @@
+error: attributes are not yet allowed on `if` expressions
+  --> $DIR/recovery-attr-on-if.rs:2:5
+   |
+LL |     #[attr] if true {};
+   |     ^^^^^^^
+
+error: attributes are not yet allowed on `if` expressions
+  --> $DIR/recovery-attr-on-if.rs:5:5
+   |
+LL |     #[attr] if true {};
+   |     ^^^^^^^
+
+error: cannot find attribute `attr` in this scope
+  --> $DIR/recovery-attr-on-if.rs:5:7
+   |
+LL |     #[attr] if true {};
+   |       ^^^^
+
+error: cannot find attribute `attr` in this scope
+  --> $DIR/recovery-attr-on-if.rs:2:7
+   |
+LL |     #[attr] if true {};
+   |       ^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/recovery-attr-on-if.rs:8:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.