diff options
| author | Andrew Cann <shum@canndrew.org> | 2017-01-21 00:08:37 +0800 |
|---|---|---|
| committer | Andrew Cann <shum@canndrew.org> | 2017-01-21 00:08:37 +0800 |
| commit | e7e7c360af2535257c419646d150338eadcb8ca3 (patch) | |
| tree | ad3cbe50a6e9629b454fee9f1d4de403c247200f | |
| parent | c07aa3383494fa8e6dce17e08ce827b07359f8b9 (diff) | |
Add unreachable attribute to Err branch
| -rw-r--r-- | src/librustc/hir/lowering.rs | 33 | ||||
| -rw-r--r-- | src/test/compile-fail/unreachable-try-pattern.rs | 20 |
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)); } |
