diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 199d5df29e7..84269ec2942 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::GenericArgsRef; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::symbol::{sym, Symbol}; pub(crate) use self::llvm::codegen_llvm_intrinsic_call; use crate::prelude::*; @@ -1132,7 +1132,7 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, val); } - kw::Try => { + sym::catch_unwind => { intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic); let f = f.load_scalar(fx); let data = data.load_scalar(fx); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index f162ef831b7..d43f5d74757 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::ty::layout::LayoutOf; #[cfg(feature="master")] use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; -use rustc_span::{Span, Symbol, symbol::kw, sym}; +use rustc_span::{Span, Symbol, sym}; use rustc_target::abi::HasDataLayout; use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; use rustc_target::spec::PanicStrategy; @@ -129,7 +129,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let res = self.context.new_call(None, builtin, &[a]); self.icmp(IntPredicate::IntEQ, res, self.const_i32(0)) } - kw::Try => { + sym::catch_unwind => { try_intrinsic( self, args[0].immediate(), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1eac2157cac..e78c4d1e31d 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -17,7 +17,7 @@ use rustc_hir as hir; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; -use rustc_span::{sym, symbol::kw, Span, Symbol}; +use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::{self, Align, HasDataLayout, Primitive}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; @@ -133,8 +133,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::unlikely => self .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]), - kw::Try => { - try_intrinsic( + sym::catch_unwind => { + catch_unwind_intrinsic( self, args[0].immediate(), args[1].immediate(), @@ -457,7 +457,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } -fn try_intrinsic<'ll>( +fn catch_unwind_intrinsic<'ll>( bx: &mut Builder<'_, 'll, '_>, try_func: &'ll Value, data: &'ll Value, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index d7277b22c84..9714a9b5ea3 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi::Abi; @@ -445,7 +445,7 @@ pub fn check_intrinsic_type( ) } - kw::Try => { + sym::catch_unwind => { let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8); let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( [mut_u8], diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 609ab054da2..a66d38e5b53 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -487,6 +487,7 @@ symbols! { call_once, caller_location, capture_disjoint_fields, + catch_unwind, cause, cdylib, ceilf32, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index f9d89795a99..6fd3895bb9c 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -75,6 +75,9 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { unsafe { crate::ptr::drop_in_place(to_drop) } } +#[cfg(bootstrap)] +pub use self::r#try as catch_unwind; + extern "rust-intrinsic" { // N.B., these intrinsics take raw pointers because they mutate aliased // memory, which is not valid for either `&` or `&mut`. @@ -2382,16 +2385,24 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn variant_count() -> usize; - /// Rust's "try catch" construct which invokes the function pointer `try_fn` - /// with the data pointer `data`. - /// - /// The third argument is a function called if a panic occurs. This function - /// takes the data pointer and a pointer to the target-specific exception - /// object that was caught. For more information see the compiler's - /// source as well as std's catch implementation. + /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the + /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs. /// /// `catch_fn` must not unwind. + /// + /// The third argument is a function called if an unwind occurs (both Rust unwinds and foreign + /// unwinds). This function takes the data pointer and a pointer to the target-specific + /// exception object that was caught. For more information, see the compiler's source as well as + /// std's `catch_unwind` implementation. + /// + /// The stable version of this intrinsic is `std::panic::catch_unwind`. #[rustc_nounwind] + #[cfg(not(bootstrap))] + pub fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32; + + /// For bootstrap only, see `catch_unwind`. + #[rustc_nounwind] + #[cfg(bootstrap)] pub fn r#try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32; /// Emits a `!nontemporal` store according to LLVM (see their docs). diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index ef701d3867a..464a46264cb 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -508,12 +508,12 @@ pub unsafe fn r#try R>(f: F) -> Result> // Access to the union's fields: this is `std` and we know that the `r#try` // intrinsic fills in the `r` or `p` union field based on its return value. // - // The call to `intrinsics::r#try` is made safe by: + // The call to `intrinsics::catch_unwind` is made safe by: // - `do_call`, the first argument, can be called with the initial `data_ptr`. // - `do_catch`, the second argument, can be called with the `data_ptr` as well. // See their safety preconditions for more information unsafe { - return if intrinsics::r#try(do_call::, data_ptr, do_catch::) == 0 { + return if intrinsics::catch_unwind(do_call::, data_ptr, do_catch::) == 0 { Ok(ManuallyDrop::into_inner(data.r)) } else { Err(ManuallyDrop::into_inner(data.p)) @@ -540,7 +540,7 @@ pub unsafe fn r#try R>(f: F) -> Result> // Its must contains a valid `f` (type: F) value that can be use to fill // `data.r`. // - // This function cannot be marked as `unsafe` because `intrinsics::r#try` + // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind` // expects normal function pointers. #[inline] fn do_call R, R>(data: *mut u8) { @@ -562,7 +562,7 @@ pub unsafe fn r#try R>(f: F) -> Result> // Since this uses `cleanup` it also hinges on a correct implementation of // `__rustc_panic_cleanup`. // - // This function cannot be marked as `unsafe` because `intrinsics::r#try` + // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind` // expects normal function pointers. #[inline] #[rustc_nounwind] // `intrinsic::r#try` requires catch fn to be nounwind diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index 602e8b31b01..b67d588dbc9 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Some intrinsics are special and need the "ret". match intrinsic_name { - "try" => return this.handle_try(args, dest, ret), + "catch_unwind" => return this.handle_catch_unwind(args, dest, ret), _ => {} } diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 4c054d8dc8a..54f718c46cc 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -69,7 +69,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } /// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`. - fn handle_try( + fn handle_catch_unwind( &mut self, args: &[OpTy<'tcx, Provenance>], dest: &PlaceTy<'tcx, Provenance>, diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs b/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs index 883d5ae8096..fd667fbe454 100644 --- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs +++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs @@ -8,7 +8,7 @@ fn main() { unsafe { // Make sure we check the ABI when Miri itself invokes a function // as part of a shim implementation. - std::intrinsics::r#try( + std::intrinsics::catch_unwind( //~^ ERROR: calling a function with ABI C using caller ABI Rust std::mem::transmute::(try_fn), std::ptr::null_mut(), diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr index f948d08bdbe..501f17c86d6 100644 --- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr +++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr @@ -1,7 +1,7 @@ error: Undefined Behavior: calling a function with ABI C using caller ABI Rust --> $DIR/check_callback_abi.rs:LL:CC | -LL | / std::intrinsics::r#try( +LL | / std::intrinsics::catch_unwind( LL | | LL | | std::mem::transmute::(try_fn), LL | | std::ptr::null_mut(), diff --git a/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs b/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs index e6251b53558..0f41047c603 100644 --- a/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs +++ b/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs @@ -15,7 +15,7 @@ fn main() { unsafe { let _ = malloc(0); std::mem::transmute::(foo)(); - std::intrinsics::r#try( + std::intrinsics::catch_unwind( std::mem::transmute::(try_fn), std::ptr::null_mut(), |_, _| unreachable!(), diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs index 2ca62a78688..45df444dca4 100644 --- a/tests/assembly/wasm_exceptions.rs +++ b/tests/assembly/wasm_exceptions.rs @@ -41,7 +41,7 @@ pub fn test_cleanup() { #[no_mangle] pub fn test_rtry() { unsafe { - core::intrinsics::r#try(|_| { + core::intrinsics::catch_unwind(|_| { may_panic(); }, core::ptr::null_mut(), |data, exception| { log_number(data as usize); diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs index 48a7357bfd8..66d2bbed709 100644 --- a/tests/codegen/wasm_exceptions.rs +++ b/tests/codegen/wasm_exceptions.rs @@ -35,7 +35,7 @@ pub fn test_cleanup() { #[no_mangle] pub fn test_rtry() { unsafe { - core::intrinsics::r#try(|_| { + core::intrinsics::catch_unwind(|_| { may_panic(); }, core::ptr::null_mut(), |data, exception| { log_number(data as usize); diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs index 7049d2fd9e0..9d336510469 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/lib.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs @@ -39,7 +39,7 @@ pub extern "C" fn start() -> usize { let data = 0x1234usize as *mut u8; // Something to recognize unsafe { - core::intrinsics::r#try(|data: *mut u8| { + core::intrinsics::catch_unwind(|data: *mut u8| { let _log_on_drop = LogOnDrop; logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data)); diff --git a/tests/ui/interior-mutability/interior-mutability.stderr b/tests/ui/interior-mutability/interior-mutability.stderr index 7b08a645405..29b250c1b07 100644 --- a/tests/ui/interior-mutability/interior-mutability.stderr +++ b/tests/ui/interior-mutability/interior-mutability.stderr @@ -15,7 +15,7 @@ note: required because it's used within this closure | LL | catch_unwind(|| { x.set(23); }); | ^^ -note: required by a bound in `catch_unwind` +note: required by a bound in `std::panic::catch_unwind` --> $SRC_DIR/std/src/panic.rs:LL:COL error: aborting due to 1 previous error