From 1c51f60ee2fad1db6ed0615bae8ed99ce08b0fdd Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Tue, 17 Jan 2017 21:32:27 +0800 Subject: [PATCH 1/7] Change unreachable patterns ICEs to warnings Allow code with unreachable `?` and `for` patterns to compile. Add some tests. --- src/librustc/hir/lowering.rs | 64 ++++++++++++++++--- src/librustc_const_eval/check_match.rs | 13 +--- .../recursive-types-are-not-uninhabited.rs | 26 ++++++++ .../compile-fail/unreachable-loop-patterns.rs | 20 ++++++ src/test/run-pass/unreachable-try-pattern.rs | 22 +++++++ 5 files changed, 125 insertions(+), 20 deletions(-) create mode 100644 src/test/compile-fail/recursive-types-are-not-uninhabited.rs create mode 100644 src/test/compile-fail/unreachable-loop-patterns.rs create mode 100644 src/test/run-pass/unreachable-try-pattern.rs diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 3b20a77ad0372..698db3f7169aa 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -51,6 +51,7 @@ use util::nodemap::{NodeMap, FxHashMap}; use std::collections::BTreeMap; use std::iter; +use syntax::attr; use syntax::ast::*; use syntax::errors; use syntax::ptr::P; @@ -1814,7 +1815,8 @@ impl<'a> LoweringContext<'a> { let match_expr = P(self.expr_match(e.span, into_iter_expr, hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar)); + hir::MatchSource::ForLoopDesugar, + ThinVec::new())); // `{ let _result = ...; _result }` // underscore prevents an unused_variables lint if the head diverges @@ -1833,8 +1835,12 @@ impl<'a> LoweringContext<'a> { ExprKind::Try(ref sub_expr) => { // to: // + // #[allow(unreachable_patterns)] // match Carrier::translate() { - // Ok(val) => val, + // Ok(val) => { + // #[allow(unreachable_code)] + // val + // } // Err(err) => return Carrier::from_error(From::from(err)) // } let unstable_span = self.allow_internal_unstable("?", e.span); @@ -1849,14 +1855,31 @@ impl<'a> LoweringContext<'a> { P(self.expr_call(e.span, path, hir_vec![sub_expr])) }; - // Ok(val) => val + // 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); - let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id)); + // #[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_meta_item = NestedMetaItemKind::MetaItem(uc_meta_item); + let uc_spanned = respan(e.span, uc_nested_meta_item); + 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)); + let val_block = P(self.block_expr(val_expr)); + let ok_expr = P(self.expr_block(val_block, ThinVec::new())); + let ok_pat = self.pat_ok(e.span, val_pat); - self.arm(hir_vec![ok_pat], val_expr) + self.arm(hir_vec![ok_pat], ok_expr) }; // Err(err) => return Carrier::from_error(From::from(err)) @@ -1885,8 +1908,23 @@ impl<'a> LoweringContext<'a> { self.arm(hir_vec![err_pat], ret_expr) }; + // #[allow(unreachable_patterns)] + let match_attr = { + // allow(unreachable_patterns) + let allow = { + let allow_ident = self.str_to_ident("allow"); + let up_ident = self.str_to_ident("unreachable_patterns"); + let up_meta_item = attr::mk_spanned_word_item(e.span, up_ident); + let up_nested_meta_item = NestedMetaItemKind::MetaItem(up_meta_item); + let up_spanned = respan(e.span, up_nested_meta_item); + attr::mk_spanned_list_item(e.span, allow_ident, vec![up_spanned]) + }; + attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow) + }; + + let attrs = From::from(vec![match_attr]); return self.expr_match(e.span, discr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar); + hir::MatchSource::TryDesugar, attrs); } ExprKind::Mac(_) => panic!("Shouldn't exist here"), @@ -2031,6 +2069,13 @@ impl<'a> LoweringContext<'a> { } fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> hir::Expr { + self.expr_ident_with_attrs(span, id, binding, ThinVec::new()) + } + + fn expr_ident_with_attrs(&mut self, span: Span, + id: Name, + binding: NodeId, + attrs: ThinVec) -> hir::Expr { let def = { let defs = self.resolver.definitions(); Def::Local(defs.local_def_id(binding)) @@ -2042,7 +2087,7 @@ impl<'a> LoweringContext<'a> { segments: hir_vec![hir::PathSegment::from_name(id)], }))); - self.expr(span, expr_path, ThinVec::new()) + self.expr(span, expr_path, attrs) } fn expr_mut_addr_of(&mut self, span: Span, e: P) -> hir::Expr { @@ -2062,9 +2107,10 @@ impl<'a> LoweringContext<'a> { span: Span, arg: P, arms: hir::HirVec, - source: hir::MatchSource) + source: hir::MatchSource, + attrs: ThinVec) -> hir::Expr { - self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new()) + self.expr(span, hir::ExprMatch(arg, arms, source), attrs) } fn expr_block(&mut self, b: P, attrs: ThinVec) -> hir::Expr { diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 400af3c702346..5046920f5e3c3 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -308,14 +308,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, .emit(); }, - hir::MatchSource::ForLoopDesugar => { - // this is a bug, because on `match iter.next()` we cover - // `Some()` and `None`. It's impossible to have an unreachable - // pattern - // (see libsyntax/ext/expand.rs for the full expansion of a for loop) - span_bug!(pat.span, "unreachable for-loop pattern") - }, - + hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => { let mut diagnostic = Diagnostic::new(Level::Warning, "unreachable pattern"); @@ -329,9 +322,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, hir_pat.id, diagnostic); }, - hir::MatchSource::TryDesugar => { - span_bug!(pat.span, "unreachable try pattern") - }, + hir::MatchSource::TryDesugar => {} } } Useful => (), diff --git a/src/test/compile-fail/recursive-types-are-not-uninhabited.rs b/src/test/compile-fail/recursive-types-are-not-uninhabited.rs new file mode 100644 index 0000000000000..f8d6c3de2ab03 --- /dev/null +++ b/src/test/compile-fail/recursive-types-are-not-uninhabited.rs @@ -0,0 +1,26 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//#![feature(never_type)] + +struct R<'a> { + r: &'a R<'a>, +} + +fn foo(res: Result) -> u32 { + let Ok(x) = res; + //~^ ERROR refutable pattern + x +} + +fn main() { + foo(Ok(23)); +} + diff --git a/src/test/compile-fail/unreachable-loop-patterns.rs b/src/test/compile-fail/unreachable-loop-patterns.rs new file mode 100644 index 0000000000000..6147692658f94 --- /dev/null +++ b/src/test/compile-fail/unreachable-loop-patterns.rs @@ -0,0 +1,20 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(never_type)] +#![deny(unreachable_patterns)] + +fn main() { + let x: &[!] = &[]; + + for _ in x {} + //~^ ERROR unreachable pattern +} + diff --git a/src/test/run-pass/unreachable-try-pattern.rs b/src/test/run-pass/unreachable-try-pattern.rs new file mode 100644 index 0000000000000..f58d5c8de0dcc --- /dev/null +++ b/src/test/run-pass/unreachable-try-pattern.rs @@ -0,0 +1,22 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(never_type)] +#![deny(unreachable_code)] +#![deny(unreachable_patterns)] + +fn bar(x: Result) -> Result { + x? +} + +fn main() { + let _ = bar(Err(123)); +} + From dd13cc3e5d353c54b0c25a83aa5e5bd9fd21a304 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Tue, 17 Jan 2017 21:49:39 +0800 Subject: [PATCH 2/7] Fix make tidy --- src/librustc/hir/lowering.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 698db3f7169aa..348185aae56d9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1866,14 +1866,17 @@ impl<'a> LoweringContext<'a> { 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_meta_item = NestedMetaItemKind::MetaItem(uc_meta_item); - let uc_spanned = respan(e.span, uc_nested_meta_item); + 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)); + let val_expr = P(self.expr_ident_with_attrs(e.span, + val_ident, + val_pat.id, + attrs)); let val_block = P(self.block_expr(val_expr)); let ok_expr = P(self.expr_block(val_block, ThinVec::new())); @@ -1915,8 +1918,8 @@ impl<'a> LoweringContext<'a> { let allow_ident = self.str_to_ident("allow"); let up_ident = self.str_to_ident("unreachable_patterns"); let up_meta_item = attr::mk_spanned_word_item(e.span, up_ident); - let up_nested_meta_item = NestedMetaItemKind::MetaItem(up_meta_item); - let up_spanned = respan(e.span, up_nested_meta_item); + let up_nested = NestedMetaItemKind::MetaItem(up_meta_item); + let up_spanned = respan(e.span, up_nested); attr::mk_spanned_list_item(e.span, allow_ident, vec![up_spanned]) }; attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow) From cc0d63c54642f1a07fd5fdf86cfc3c0d240ece59 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Fri, 20 Jan 2017 22:57:38 +0800 Subject: [PATCH 3/7] Remove attribute on match --- src/librustc/hir/lowering.rs | 25 +++---------------- .../unreachable-try-pattern.rs | 8 ++++++ 2 files changed, 12 insertions(+), 21 deletions(-) rename src/test/{run-pass => compile-fail}/unreachable-try-pattern.rs (73%) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 348185aae56d9..972dc5055d21b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1815,8 +1815,7 @@ impl<'a> LoweringContext<'a> { let match_expr = P(self.expr_match(e.span, into_iter_expr, hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar, - ThinVec::new())); + hir::MatchSource::ForLoopDesugar)); // `{ let _result = ...; _result }` // underscore prevents an unused_variables lint if the head diverges @@ -1911,23 +1910,8 @@ impl<'a> LoweringContext<'a> { self.arm(hir_vec![err_pat], ret_expr) }; - // #[allow(unreachable_patterns)] - let match_attr = { - // allow(unreachable_patterns) - let allow = { - let allow_ident = self.str_to_ident("allow"); - let up_ident = self.str_to_ident("unreachable_patterns"); - let up_meta_item = attr::mk_spanned_word_item(e.span, up_ident); - let up_nested = NestedMetaItemKind::MetaItem(up_meta_item); - let up_spanned = respan(e.span, up_nested); - attr::mk_spanned_list_item(e.span, allow_ident, vec![up_spanned]) - }; - attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow) - }; - - let attrs = From::from(vec![match_attr]); return self.expr_match(e.span, discr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar, attrs); + hir::MatchSource::TryDesugar); } ExprKind::Mac(_) => panic!("Shouldn't exist here"), @@ -2110,10 +2094,9 @@ impl<'a> LoweringContext<'a> { span: Span, arg: P, arms: hir::HirVec, - source: hir::MatchSource, - attrs: ThinVec) + source: hir::MatchSource) -> hir::Expr { - self.expr(span, hir::ExprMatch(arg, arms, source), attrs) + self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new()) } fn expr_block(&mut self, b: P, attrs: ThinVec) -> hir::Expr { diff --git a/src/test/run-pass/unreachable-try-pattern.rs b/src/test/compile-fail/unreachable-try-pattern.rs similarity index 73% rename from src/test/run-pass/unreachable-try-pattern.rs rename to src/test/compile-fail/unreachable-try-pattern.rs index f58d5c8de0dcc..6b334a0f27534 100644 --- a/src/test/run-pass/unreachable-try-pattern.rs +++ b/src/test/compile-fail/unreachable-try-pattern.rs @@ -16,7 +16,15 @@ fn bar(x: Result) -> Result { x? } +fn foo(x: Result) -> Result { + let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; + //~^ ERROR unreachable pattern + //~| ERROR unreachable expression + Ok(y) +} + fn main() { let _ = bar(Err(123)); + let _ = foo(Err(123)); } From c07aa3383494fa8e6dce17e08ce827b07359f8b9 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Fri, 20 Jan 2017 23:28:17 +0800 Subject: [PATCH 4/7] Remove redundant block --- src/librustc/hir/lowering.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 972dc5055d21b..31eaad8691b0d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1876,12 +1876,9 @@ impl<'a> LoweringContext<'a> { val_ident, val_pat.id, attrs)); - let val_block = P(self.block_expr(val_expr)); - let ok_expr = P(self.expr_block(val_block, ThinVec::new())); - let ok_pat = self.pat_ok(e.span, val_pat); - self.arm(hir_vec![ok_pat], ok_expr) + self.arm(hir_vec![ok_pat], val_expr) }; // Err(err) => return Carrier::from_error(From::from(err)) From e7e7c360af2535257c419646d150338eadcb8ca3 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sat, 21 Jan 2017 00:08:37 +0800 Subject: [PATCH 5/7] Add unreachable attribute to Err branch --- src/librustc/hir/lowering.rs | 33 ++++++++++--------- .../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 31eaad8691b0d..edfd5fbfa621c 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 6b334a0f27534..f4817ba33b518 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 for i32 { + fn from(v: Void) -> i32 { + match v {} + } +} + fn bar(x: Result) -> Result { x? } @@ -23,8 +31,20 @@ fn foo(x: Result) -> Result { Ok(y) } +fn qux(x: Result) -> Result { + Ok(x?) +} + +fn vom(x: Result) -> Result { + 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)); } From ef9f0ab43e04a42a88830a072ae30258fc87351b Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sat, 21 Jan 2017 10:53:16 +0800 Subject: [PATCH 6/7] Fix some nits --- src/librustc/hir/lowering.rs | 9 +++++---- src/librustc_const_eval/check_match.rs | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index edfd5fbfa621c..51f587ca46cba 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1869,20 +1869,21 @@ impl<'a> LoweringContext<'a> { }; let attrs = vec![attr]; - // Ok(val) => { #[allow(unreachable_code)] val } + // 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); let val_expr = P(self.expr_ident_with_attrs(e.span, val_ident, val_pat.id, - From::from(attrs.clone()))); + ThinVec::from(attrs.clone()))); let ok_pat = self.pat_ok(e.span, val_pat); self.arm(hir_vec![ok_pat], val_expr) }; - // Err(err) => return Carrier::from_error(From::from(err)) + // Err(err) => #[allow(unreachable_code)] + // return Carrier::from_error(From::from(err)), let err_arm = { let err_ident = self.str_to_ident("err"); let err_local = self.pat_ident(e.span, err_ident); @@ -1902,7 +1903,7 @@ impl<'a> LoweringContext<'a> { let ret_expr = P(self.expr(e.span, hir::Expr_::ExprRet(Some(from_err_expr)), - From::from(attrs))); + ThinVec::from(attrs))); let err_pat = self.pat_err(e.span, err_local); self.arm(hir_vec![err_pat], ret_expr) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 5046920f5e3c3..52f332a30c03b 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -322,6 +322,8 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, hir_pat.id, diagnostic); }, + // Unreachable patterns in try expressions occur when one of the arms + // are an uninhabited type. Which is OK. hir::MatchSource::TryDesugar => {} } } From 0aad529e1ce777c03d1a04db774d0b371b0ff6bf Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sat, 21 Jan 2017 10:55:30 +0800 Subject: [PATCH 7/7] Fix comment --- src/librustc/hir/lowering.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 51f587ca46cba..b801513528f7e 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1834,13 +1834,10 @@ impl<'a> LoweringContext<'a> { ExprKind::Try(ref sub_expr) => { // to: // - // #[allow(unreachable_patterns)] // match Carrier::translate() { - // Ok(val) => { - // #[allow(unreachable_code)] - // val - // } - // Err(err) => return Carrier::from_error(From::from(err)) + // Ok(val) => #[allow(unreachable_code)] val, + // Err(err) => #[allow(unreachable_code)] + // return Carrier::from_error(From::from(err)), // } let unstable_span = self.allow_internal_unstable("?", e.span);