diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3babe73030a45..67395cb738f09 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1505,7 +1505,7 @@ impl<'hir> LoweringContext<'_, 'hir> { /// ControlFlow::Break(residual) => /// #[allow(unreachable_code)] /// // If there is an enclosing `try {...}`: - /// break 'catch_target Try::from_residual(residual), + /// break 'catch_target Residual::into_try_type(residual), /// // Otherwise: /// return Try::from_residual(residual), /// } @@ -1571,7 +1571,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident); let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid); let from_residual_expr = self.wrap_in_try_constructor( - hir::LangItem::TryTraitFromResidual, + if self.catch_scope.is_some() { + hir::LangItem::ResidualIntoTryType + } else { + hir::LangItem::TryTraitFromResidual + }, try_span, self.arena.alloc(residual_expr), unstable_span, diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b0bfac8e1f5ec..7ced20670e9da 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -294,6 +294,7 @@ language_item_table! { TryTraitFromOutput, sym::from_output, from_output_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None; + ResidualIntoTryType, sym::into_try_type, into_try_type_fn, Target::Method(MethodKind::Trait { body: true }), GenericRequirement::None; PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None; PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8a6941a451621..7ed208f284fc2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -806,6 +806,7 @@ symbols! { intel, into_future, into_iter, + into_try_type, intra_doc_pointers, intrinsics, irrefutable_let_patterns, diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 02f7f62bfe221..9321d42b1ab5b 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -356,10 +356,18 @@ where /// and in the other direction, /// ` as Residual>::TryType = Result`. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -pub trait Residual { +pub trait Residual: Sized { /// The "return" type of this meta-function. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] type TryType: Try; + + /// Here for convenience in the `?` desugaring. + /// Probably should not be stabilized, as it should never be overridden. + #[unstable(feature = "try_trait_v2_residual", issue = "91285")] + #[cfg_attr(not(bootstrap), lang = "into_try_type")] + fn into_try_type(self) -> Self::TryType { + FromResidual::from_residual(self) + } } #[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")] diff --git a/library/std/src/sys/unix/kernel_copy/tests.rs b/library/std/src/sys/unix/kernel_copy/tests.rs index 3fe849e23e2e6..5c408ab663702 100644 --- a/library/std/src/sys/unix/kernel_copy/tests.rs +++ b/library/std/src/sys/unix/kernel_copy/tests.rs @@ -52,7 +52,7 @@ fn copy_specialization() -> Result<()> { "inner Take allowed reading beyond end of file, some bytes should be left" ); - let mut sink = sink.into_inner()?; + let mut sink = sink.into_inner().map_err(io::Error::from)?; sink.seek(SeekFrom::Start(0))?; let mut copied = Vec::new(); sink.read_to_end(&mut copied)?; diff --git a/src/test/ui/try-block/try-block-bad-type.rs b/src/test/ui/try-block/try-block-bad-type.rs index 30ae96763c0e2..d529a852eb471 100644 --- a/src/test/ui/try-block/try-block-bad-type.rs +++ b/src/test/ui/try-block/try-block-bad-type.rs @@ -4,7 +4,7 @@ pub fn main() { let res: Result = try { - Err("")?; //~ ERROR `?` couldn't convert the error + Err("")?; //~ ERROR mismatched types 5 }; diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr index f9906713f8427..1f244416d3575 100644 --- a/src/test/ui/try-block/try-block-bad-type.stderr +++ b/src/test/ui/try-block/try-block-bad-type.stderr @@ -1,12 +1,11 @@ -error[E0277]: `?` couldn't convert the error to `TryFromSliceError` - --> $DIR/try-block-bad-type.rs:7:16 +error[E0308]: mismatched types + --> $DIR/try-block-bad-type.rs:7:9 | LL | Err("")?; - | ^ the trait `From<&str>` is not implemented for `TryFromSliceError` + | ^^^^^^^^ expected struct `TryFromSliceError`, found `&str` | - = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the trait `From` is implemented for `TryFromSliceError` - = note: required because of the requirements on the impl of `FromResidual>` for `Result` + = note: expected enum `Result` + found enum `Result<_, &str>` error[E0271]: type mismatch resolving ` as Try>::Output == &str` --> $DIR/try-block-bad-type.rs:12:9 @@ -38,5 +37,5 @@ LL | let res: i32 = try { 5 }; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0271, E0277. +Some errors have detailed explanations: E0271, E0277, E0308. For more information about an error, try `rustc --explain E0271`.