about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Cann <shum@canndrew.org>2017-01-21 00:08:37 +0800
committerAndrew Cann <shum@canndrew.org>2017-01-21 00:08:37 +0800
commite7e7c360af2535257c419646d150338eadcb8ca3 (patch)
treead3cbe50a6e9629b454fee9f1d4de403c247200f
parentc07aa3383494fa8e6dce17e08ce827b07359f8b9 (diff)
Add unreachable attribute to Err branch
-rw-r--r--src/librustc/hir/lowering.rs33
-rw-r--r--src/test/compile-fail/unreachable-try-pattern.rs20
2 files changed, 37 insertions, 16 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 31eaad8691b..edfd5fbfa62 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1854,28 +1854,29 @@ impl<'a> LoweringContext<'a> {
                         P(self.expr_call(e.span, path, hir_vec![sub_expr]))
                     };
 
+                    // #[allow(unreachable_code)]
+                    let attr = {
+                        // allow(unreachable_code)
+                        let allow = {
+                            let allow_ident = self.str_to_ident("allow");
+                            let uc_ident = self.str_to_ident("unreachable_code");
+                            let uc_meta_item = attr::mk_spanned_word_item(e.span, uc_ident);
+                            let uc_nested = NestedMetaItemKind::MetaItem(uc_meta_item);
+                            let uc_spanned = respan(e.span, uc_nested);
+                            attr::mk_spanned_list_item(e.span, allow_ident, vec![uc_spanned])
+                        };
+                        attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow)
+                    };
+                    let attrs = vec![attr];
+
                     // Ok(val) => { #[allow(unreachable_code)] val }
                     let ok_arm = {
                         let val_ident = self.str_to_ident("val");
                         let val_pat = self.pat_ident(e.span, val_ident);
-                        // #[allow(unreachable_code)]
-                        let val_attr = {
-                            // allow(unreachable_code)
-                            let allow = {
-                                let allow_ident = self.str_to_ident("allow");
-                                let uc_ident = self.str_to_ident("unreachable_code");
-                                let uc_meta_item = attr::mk_spanned_word_item(e.span, uc_ident);
-                                let uc_nested = NestedMetaItemKind::MetaItem(uc_meta_item);
-                                let uc_spanned = respan(e.span, uc_nested);
-                                attr::mk_spanned_list_item(e.span, allow_ident, vec![uc_spanned])
-                            };
-                            attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow)
-                        };
-                        let attrs = From::from(vec![val_attr]);
                         let val_expr = P(self.expr_ident_with_attrs(e.span,
                                                                     val_ident,
                                                                     val_pat.id,
-                                                                    attrs));
+                                                                    From::from(attrs.clone())));
                         let ok_pat = self.pat_ok(e.span, val_pat);
 
                         self.arm(hir_vec![ok_pat], val_expr)
@@ -1901,7 +1902,7 @@ impl<'a> LoweringContext<'a> {
 
                         let ret_expr = P(self.expr(e.span,
                                                    hir::Expr_::ExprRet(Some(from_err_expr)),
-                                                                       ThinVec::new()));
+                                                                       From::from(attrs)));
 
                         let err_pat = self.pat_err(e.span, err_local);
                         self.arm(hir_vec![err_pat], ret_expr)
diff --git a/src/test/compile-fail/unreachable-try-pattern.rs b/src/test/compile-fail/unreachable-try-pattern.rs
index 6b334a0f275..f4817ba33b5 100644
--- a/src/test/compile-fail/unreachable-try-pattern.rs
+++ b/src/test/compile-fail/unreachable-try-pattern.rs
@@ -12,6 +12,14 @@
 #![deny(unreachable_code)]
 #![deny(unreachable_patterns)]
 
+enum Void {}
+
+impl From<Void> for i32 {
+    fn from(v: Void) -> i32 {
+        match v {}
+    }
+}
+
 fn bar(x: Result<!, i32>) -> Result<u32, i32> {
     x?
 }
@@ -23,8 +31,20 @@ fn foo(x: Result<!, i32>) -> Result<u32, i32> {
     Ok(y)
 }
 
+fn qux(x: Result<u32, Void>) -> Result<u32, i32> {
+    Ok(x?)
+}
+
+fn vom(x: Result<u32, Void>) -> Result<u32, i32> {
+    let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
+    //~^ ERROR unreachable pattern
+    Ok(y)
+}
+
 fn main() {
     let _ = bar(Err(123));
     let _ = foo(Err(123));
+    let _ = qux(Ok(123));
+    let _ = vom(Ok(123));
 }