From 0d4d752e83f664c8e9b135e3e180084bb0b09a39 Mon Sep 17 00:00:00 2001 From: Wang Han <416810799@qq.com> Date: Fri, 21 Feb 2025 00:13:55 +0800 Subject: [PATCH 01/16] Correct doc about `temp_dir()` behavior on Android Since commit https://github.com/aosp-mirror/platform_frameworks_base/commit/d5ccb038f69193fb63b5169d7adc5da19859c9d8, `TMPDIR` will be set to application's cache dir when app starts. --- library/std/src/env.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index adbd68896241c..4a071b4e1faec 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -668,7 +668,9 @@ pub fn home_dir() -> Option { /// On Unix, returns the value of the `TMPDIR` environment variable if it is /// set, otherwise the value is OS-specific: /// - On Android, there is no global temporary folder (it is usually allocated -/// per-app), it returns `/data/local/tmp`. +/// per-app), it will return the application's cache dir if the program runs +/// in application's namespace and system version is Android 13 (or above), or +/// `/data/local/tmp` otherwise. /// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided /// by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's /// security guidelines][appledoc]. From a343dcb97fc37a54083963cc29bfb34f6ace1ddf Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 22 Feb 2025 16:15:14 +0900 Subject: [PATCH 02/16] rustc_target: Add more RISC-V atomic-related features --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 2 ++ compiler/rustc_target/src/target_features.rs | 5 +++++ tests/ui/check-cfg/target_feature.stderr | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index b4b5d6a5b1943..1fcb20e0d7b2b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -281,6 +281,8 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option None, ("riscv32" | "riscv64", "zabha") if get_version().0 < 19 => None, ("riscv32" | "riscv64", "zalrsc") if get_version().0 < 19 => None, + ("riscv32" | "riscv64", "zama16b") if get_version().0 < 19 => None, + ("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None, // Enable the evex512 target feature if an avx512 target feature is enabled. ("x86", s) if s.starts_with("avx512") => { Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512"))) diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 1ba8defedae13..87dd54e7f3d2c 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -497,9 +497,14 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("relax", Unstable(sym::riscv_target_feature), &[]), ("unaligned-scalar-mem", Unstable(sym::riscv_target_feature), &[]), ("v", Unstable(sym::riscv_target_feature), &[]), + ("za128rs", Unstable(sym::riscv_target_feature), &[]), + ("za64rs", Unstable(sym::riscv_target_feature), &[]), ("zaamo", Unstable(sym::riscv_target_feature), &[]), ("zabha", Unstable(sym::riscv_target_feature), &["zaamo"]), + ("zacas", Unstable(sym::riscv_target_feature), &["zaamo"]), ("zalrsc", Unstable(sym::riscv_target_feature), &[]), + ("zama16b", Unstable(sym::riscv_target_feature), &[]), + ("zawrs", Unstable(sym::riscv_target_feature), &[]), ("zba", Stable, &[]), ("zbb", Stable, &[]), ("zbc", Stable, &[]), diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 70852423bdbef..9e9bd391429c9 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -279,9 +279,14 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `xsavec` `xsaveopt` `xsaves` +`za128rs` +`za64rs` `zaamo` `zabha` +`zacas` `zalrsc` +`zama16b` +`zawrs` `zba` `zbb` `zbc` From 5a58a922e21438d70f1be738754dc257cc8c649b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Feb 2025 17:28:13 +0100 Subject: [PATCH 03/16] remove uses of rustc_intrinsic_must_be_overridden from standard library --- library/alloc/src/boxed.rs | 5 +- library/core/src/ffi/va_list.rs | 15 +- library/core/src/intrinsics/mod.rs | 1430 ++++++--------------------- library/core/src/intrinsics/simd.rs | 340 ++----- 4 files changed, 357 insertions(+), 1433 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e2a55d3139532..c3f5806e1aa90 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -238,11 +238,8 @@ pub struct Box< /// /// This is the surface syntax for `box ` expressions. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[unstable(feature = "liballoc_internals", issue = "none")] -pub fn box_new(_x: T) -> Box { - unreachable!() -} +pub fn box_new(_x: T) -> Box; impl Box { /// Allocates memory on the heap and then places `x` into it. diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index cceb186b31e79..cefa0e3950cad 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -305,25 +305,16 @@ impl<'f> Drop for VaListImpl<'f> { /// Destroy the arglist `ap` after initialization with `va_start` or /// `va_copy`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -unsafe fn va_end(_ap: &mut VaListImpl<'_>) { - unreachable!() -} +unsafe fn va_end(_ap: &mut VaListImpl<'_>); /// Copies the current location of arglist `src` to the arglist `dst`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -unsafe fn va_copy<'f>(_dest: *mut VaListImpl<'f>, _src: &VaListImpl<'f>) { - unreachable!() -} +unsafe fn va_copy<'f>(_dest: *mut VaListImpl<'f>, _src: &VaListImpl<'f>); /// Loads an argument of type `T` from the `va_list` `ap` and increment the /// argument `ap` points to. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -unsafe fn va_arg(_ap: &mut VaListImpl<'_>) -> T { - unreachable!() -} +unsafe fn va_arg(_ap: &mut VaListImpl<'_>) -> T; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index ae2b3b92b823f..38a60338e74ed 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -96,11 +96,8 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { /// [`Ordering::Relaxed`] as both the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_relaxed_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -108,11 +105,8 @@ pub unsafe fn atomic_cxchg_relaxed_relaxed(_dst: *mut T, _old: T, _src: /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_relaxed_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -120,11 +114,8 @@ pub unsafe fn atomic_cxchg_relaxed_acquire(_dst: *mut T, _old: T, _src: /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_relaxed_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_relaxed_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -132,11 +123,8 @@ pub unsafe fn atomic_cxchg_relaxed_seqcst(_dst: *mut T, _old: T, _src: /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_acquire_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -144,11 +132,8 @@ pub unsafe fn atomic_cxchg_acquire_relaxed(_dst: *mut T, _old: T, _src: /// [`Ordering::Acquire`] as both the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_acquire_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -156,11 +141,8 @@ pub unsafe fn atomic_cxchg_acquire_acquire(_dst: *mut T, _old: T, _src: /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acquire_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_acquire_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -168,11 +150,8 @@ pub unsafe fn atomic_cxchg_acquire_seqcst(_dst: *mut T, _old: T, _src: /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_release_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -180,11 +159,8 @@ pub unsafe fn atomic_cxchg_release_relaxed(_dst: *mut T, _old: T, _src: /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_release_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -192,11 +168,8 @@ pub unsafe fn atomic_cxchg_release_acquire(_dst: *mut T, _old: T, _src: /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_release_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_release_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -204,11 +177,8 @@ pub unsafe fn atomic_cxchg_release_seqcst(_dst: *mut T, _old: T, _src: /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_acqrel_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -216,11 +186,8 @@ pub unsafe fn atomic_cxchg_acqrel_relaxed(_dst: *mut T, _old: T, _src: /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_acqrel_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -228,11 +195,8 @@ pub unsafe fn atomic_cxchg_acqrel_acquire(_dst: *mut T, _old: T, _src: /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -240,11 +204,8 @@ pub unsafe fn atomic_cxchg_acqrel_seqcst(_dst: *mut T, _old: T, _src: T /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_seqcst_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -252,11 +213,8 @@ pub unsafe fn atomic_cxchg_seqcst_relaxed(_dst: *mut T, _old: T, _src: /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_seqcst_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -264,11 +222,8 @@ pub unsafe fn atomic_cxchg_seqcst_acquire(_dst: *mut T, _old: T, _src: /// [`Ordering::SeqCst`] as both the success and failure parameters. /// For example, [`AtomicBool::compare_exchange`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchg_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchg_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// @@ -277,15 +232,12 @@ pub unsafe fn atomic_cxchg_seqcst_seqcst(_dst: *mut T, _old: T, _src: T /// [`Ordering::Relaxed`] as both the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_relaxed_relaxed( _dst: *mut T, _old: T, _src: T, -) -> (T, bool) { - unreachable!() -} +) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -293,15 +245,12 @@ pub unsafe fn atomic_cxchgweak_relaxed_relaxed( /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_relaxed_acquire( _dst: *mut T, _old: T, _src: T, -) -> (T, bool) { - unreachable!() -} +) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -309,15 +258,9 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire( /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_relaxed_seqcst( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_relaxed_seqcst(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -325,15 +268,12 @@ pub unsafe fn atomic_cxchgweak_relaxed_seqcst( /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_acquire_relaxed( _dst: *mut T, _old: T, _src: T, -) -> (T, bool) { - unreachable!() -} +) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -341,15 +281,12 @@ pub unsafe fn atomic_cxchgweak_acquire_relaxed( /// [`Ordering::Acquire`] as both the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_acquire_acquire( _dst: *mut T, _old: T, _src: T, -) -> (T, bool) { - unreachable!() -} +) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -357,15 +294,9 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire( /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acquire_seqcst( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_acquire_seqcst(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -373,15 +304,12 @@ pub unsafe fn atomic_cxchgweak_acquire_seqcst( /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_release_relaxed( _dst: *mut T, _old: T, _src: T, -) -> (T, bool) { - unreachable!() -} +) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -389,15 +317,12 @@ pub unsafe fn atomic_cxchgweak_release_relaxed( /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn atomic_cxchgweak_release_acquire( _dst: *mut T, _old: T, _src: T, -) -> (T, bool) { - unreachable!() -} +) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -405,15 +330,9 @@ pub unsafe fn atomic_cxchgweak_release_acquire( /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_release_seqcst( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_release_seqcst(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -421,15 +340,9 @@ pub unsafe fn atomic_cxchgweak_release_seqcst( /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_relaxed( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_acqrel_relaxed(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -437,15 +350,9 @@ pub unsafe fn atomic_cxchgweak_acqrel_relaxed( /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_acquire( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_acqrel_acquire(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -453,11 +360,8 @@ pub unsafe fn atomic_cxchgweak_acqrel_acquire( /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -465,15 +369,9 @@ pub unsafe fn atomic_cxchgweak_acqrel_seqcst(_dst: *mut T, _old: T, _sr /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_relaxed( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_seqcst_relaxed(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -481,15 +379,9 @@ pub unsafe fn atomic_cxchgweak_seqcst_relaxed( /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_acquire( - _dst: *mut T, - _old: T, - _src: T, -) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_seqcst_acquire(_dst: *mut T, _old: T, _src: T) +-> (T, bool); /// Stores a value if the current value is the same as the `old` value. /// /// The stabilized version of this intrinsic is available on the @@ -497,11 +389,8 @@ pub unsafe fn atomic_cxchgweak_seqcst_acquire( /// [`Ordering::SeqCst`] as both the success and failure parameters. /// For example, [`AtomicBool::compare_exchange_weak`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_cxchgweak_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { - unreachable!() -} +pub unsafe fn atomic_cxchgweak_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool); /// Loads the current value of the pointer. /// @@ -509,42 +398,30 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst(_dst: *mut T, _old: T, _sr /// [`atomic`] types via the `load` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_load_seqcst(_src: *const T) -> T { - unreachable!() -} +pub unsafe fn atomic_load_seqcst(_src: *const T) -> T; /// Loads the current value of the pointer. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `load` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_load_acquire(_src: *const T) -> T { - unreachable!() -} +pub unsafe fn atomic_load_acquire(_src: *const T) -> T; /// Loads the current value of the pointer. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `load` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_load_relaxed(_src: *const T) -> T { - unreachable!() -} +pub unsafe fn atomic_load_relaxed(_src: *const T) -> T; /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! /// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`, /// i.e., it performs a non-atomic read. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_load_unordered(_src: *const T) -> T { - unreachable!() -} +pub unsafe fn atomic_load_unordered(_src: *const T) -> T; /// Stores the value at the specified memory location. /// @@ -552,42 +429,30 @@ pub unsafe fn atomic_load_unordered(_src: *const T) -> T { /// [`atomic`] types via the `store` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_store_seqcst(_dst: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn atomic_store_seqcst(_dst: *mut T, _val: T); /// Stores the value at the specified memory location. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `store` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_store_release(_dst: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn atomic_store_release(_dst: *mut T, _val: T); /// Stores the value at the specified memory location. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `store` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_store_relaxed(_dst: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn atomic_store_relaxed(_dst: *mut T, _val: T); /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! /// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`, /// i.e., it performs a non-atomic write. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_store_unordered(_dst: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn atomic_store_unordered(_dst: *mut T, _val: T); /// Stores the value at the specified memory location, returning the old value. /// @@ -595,55 +460,40 @@ pub unsafe fn atomic_store_unordered(_dst: *mut T, _val: T) { /// [`atomic`] types via the `swap` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xchg_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xchg_seqcst(_dst: *mut T, _src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xchg_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xchg_acquire(_dst: *mut T, _src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xchg_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xchg_release(_dst: *mut T, _src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xchg_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xchg_acqrel(_dst: *mut T, _src: T) -> T; /// Stores the value at the specified memory location, returning the old value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `swap` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xchg_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xchg_relaxed(_dst: *mut T, _src: T) -> T; /// Adds to the current value, returning the previous value. /// @@ -651,55 +501,40 @@ pub unsafe fn atomic_xchg_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] types via the `fetch_add` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xadd_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xadd_seqcst(_dst: *mut T, _src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xadd_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xadd_acquire(_dst: *mut T, _src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xadd_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xadd_release(_dst: *mut T, _src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xadd_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xadd_acqrel(_dst: *mut T, _src: T) -> T; /// Adds to the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_add` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xadd_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xadd_relaxed(_dst: *mut T, _src: T) -> T; /// Subtract from the current value, returning the previous value. /// @@ -707,55 +542,40 @@ pub unsafe fn atomic_xadd_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] types via the `fetch_sub` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xsub_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xsub_seqcst(_dst: *mut T, _src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xsub_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xsub_acquire(_dst: *mut T, _src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xsub_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xsub_release(_dst: *mut T, _src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xsub_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xsub_acqrel(_dst: *mut T, _src: T) -> T; /// Subtract from the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_sub` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xsub_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xsub_relaxed(_dst: *mut T, _src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// @@ -763,55 +583,40 @@ pub unsafe fn atomic_xsub_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] types via the `fetch_and` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_and_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_and_seqcst(_dst: *mut T, _src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_and_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_and_acquire(_dst: *mut T, _src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_and_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_and_release(_dst: *mut T, _src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_and_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_and_acqrel(_dst: *mut T, _src: T) -> T; /// Bitwise and with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_and` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_and_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_and_relaxed(_dst: *mut T, _src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// @@ -819,55 +624,40 @@ pub unsafe fn atomic_and_relaxed(_dst: *mut T, _src: T) -> T { /// [`AtomicBool`] type via the `fetch_nand` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_nand_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_nand_seqcst(_dst: *mut T, _src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_nand_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_nand_acquire(_dst: *mut T, _src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_nand_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_nand_release(_dst: *mut T, _src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_nand_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_nand_acqrel(_dst: *mut T, _src: T) -> T; /// Bitwise nand with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`AtomicBool`] type via the `fetch_nand` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_nand_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_nand_relaxed(_dst: *mut T, _src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// @@ -875,55 +665,40 @@ pub unsafe fn atomic_nand_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] types via the `fetch_or` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_or_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_or_seqcst(_dst: *mut T, _src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_or_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_or_acquire(_dst: *mut T, _src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_or_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_or_release(_dst: *mut T, _src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_or_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_or_acqrel(_dst: *mut T, _src: T) -> T; /// Bitwise or with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_or` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_or_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_or_relaxed(_dst: *mut T, _src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// @@ -931,55 +706,40 @@ pub unsafe fn atomic_or_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] types via the `fetch_xor` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xor_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xor_seqcst(_dst: *mut T, _src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xor_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xor_acquire(_dst: *mut T, _src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xor_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xor_release(_dst: *mut T, _src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xor_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xor_acqrel(_dst: *mut T, _src: T) -> T; /// Bitwise xor with the current value, returning the previous value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `fetch_xor` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_xor_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_xor_relaxed(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using a signed comparison. /// @@ -987,55 +747,40 @@ pub unsafe fn atomic_xor_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] signed integer types via the `fetch_max` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_max_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_max_seqcst(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_max_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_max_acquire(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_max_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_max_release(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_max_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_max_acqrel(_dst: *mut T, _src: T) -> T; /// Maximum with the current value. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_max` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_max_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_max_relaxed(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using a signed comparison. /// @@ -1043,55 +788,40 @@ pub unsafe fn atomic_max_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] signed integer types via the `fetch_min` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_min_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_min_seqcst(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_min_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_min_acquire(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_min_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_min_release(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_min_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_min_acqrel(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using a signed comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] signed integer types via the `fetch_min` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_min_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_min_relaxed(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// @@ -1099,55 +829,40 @@ pub unsafe fn atomic_min_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] unsigned integer types via the `fetch_min` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umin_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umin_seqcst(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umin_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umin_acquire(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umin_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umin_release(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umin_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umin_acqrel(_dst: *mut T, _src: T) -> T; /// Minimum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_min` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umin_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umin_relaxed(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// @@ -1155,55 +870,40 @@ pub unsafe fn atomic_umin_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic`] unsigned integer types via the `fetch_max` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umax_seqcst(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umax_seqcst(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umax_acquire(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umax_acquire(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umax_release(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umax_release(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umax_acqrel(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umax_acqrel(_dst: *mut T, _src: T) -> T; /// Maximum with the current value using an unsigned comparison. /// /// The stabilized version of this intrinsic is available on the /// [`atomic`] unsigned integer types via the `fetch_max` method by passing /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_umax_relaxed(_dst: *mut T, _src: T) -> T { - unreachable!() -} +pub unsafe fn atomic_umax_relaxed(_dst: *mut T, _src: T) -> T; /// An atomic fence. /// @@ -1211,44 +911,32 @@ pub unsafe fn atomic_umax_relaxed(_dst: *mut T, _src: T) -> T { /// [`atomic::fence`] by passing [`Ordering::SeqCst`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_fence_seqcst() { - unreachable!() -} +pub unsafe fn atomic_fence_seqcst(); /// An atomic fence. /// /// The stabilized version of this intrinsic is available in /// [`atomic::fence`] by passing [`Ordering::Acquire`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_fence_acquire() { - unreachable!() -} +pub unsafe fn atomic_fence_acquire(); /// An atomic fence. /// /// The stabilized version of this intrinsic is available in /// [`atomic::fence`] by passing [`Ordering::Release`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_fence_release() { - unreachable!() -} +pub unsafe fn atomic_fence_release(); /// An atomic fence. /// /// The stabilized version of this intrinsic is available in /// [`atomic::fence`] by passing [`Ordering::AcqRel`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_fence_acqrel() { - unreachable!() -} +pub unsafe fn atomic_fence_acqrel(); /// A compiler-only memory barrier. /// @@ -1261,11 +949,8 @@ pub unsafe fn atomic_fence_acqrel() { /// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_seqcst() { - unreachable!() -} +pub unsafe fn atomic_singlethreadfence_seqcst(); /// A compiler-only memory barrier. /// /// Memory accesses will never be reordered across this barrier by the @@ -1277,11 +962,8 @@ pub unsafe fn atomic_singlethreadfence_seqcst() { /// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_acquire() { - unreachable!() -} +pub unsafe fn atomic_singlethreadfence_acquire(); /// A compiler-only memory barrier. /// /// Memory accesses will never be reordered across this barrier by the @@ -1293,11 +975,8 @@ pub unsafe fn atomic_singlethreadfence_acquire() { /// [`atomic::compiler_fence`] by passing [`Ordering::Release`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_release() { - unreachable!() -} +pub unsafe fn atomic_singlethreadfence_release(); /// A compiler-only memory barrier. /// /// Memory accesses will never be reordered across this barrier by the @@ -1309,11 +988,8 @@ pub unsafe fn atomic_singlethreadfence_release() { /// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`] /// as the `order`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn atomic_singlethreadfence_acqrel() { - unreachable!() -} +pub unsafe fn atomic_singlethreadfence_acqrel(); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. @@ -1325,11 +1001,8 @@ pub unsafe fn atomic_singlethreadfence_acqrel() { /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn prefetch_read_data(_data: *const T, _locality: i32) { - unreachable!() -} +pub unsafe fn prefetch_read_data(_data: *const T, _locality: i32); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. /// Prefetches have no effect on the behavior of the program but can change its performance @@ -1340,11 +1013,8 @@ pub unsafe fn prefetch_read_data(_data: *const T, _locality: i32) { /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn prefetch_write_data(_data: *const T, _locality: i32) { - unreachable!() -} +pub unsafe fn prefetch_write_data(_data: *const T, _locality: i32); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. /// Prefetches have no effect on the behavior of the program but can change its performance @@ -1355,11 +1025,8 @@ pub unsafe fn prefetch_write_data(_data: *const T, _locality: i32) { /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn prefetch_read_instruction(_data: *const T, _locality: i32) { - unreachable!() -} +pub unsafe fn prefetch_read_instruction(_data: *const T, _locality: i32); /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction /// if supported; otherwise, it is a no-op. /// Prefetches have no effect on the behavior of the program but can change its performance @@ -1370,21 +1037,15 @@ pub unsafe fn prefetch_read_instruction(_data: *const T, _locality: i32) { /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn prefetch_write_instruction(_data: *const T, _locality: i32) { - unreachable!() -} +pub unsafe fn prefetch_write_instruction(_data: *const T, _locality: i32); /// Executes a breakpoint trap, for inspection by a debugger. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub fn breakpoint() { - unreachable!() -} +pub fn breakpoint(); /// Magic intrinsic that derives its meaning from attributes /// attached to the function. @@ -1397,10 +1058,7 @@ pub fn breakpoint() { /// This intrinsic should not be used outside of the compiler. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn rustc_peek(_: T) -> T { - unreachable!() -} +pub fn rustc_peek(_: T) -> T; /// Aborts the execution of the process. /// @@ -1419,10 +1077,7 @@ pub fn rustc_peek(_: T) -> T { /// `SIGBUS`. The precise behavior is not guaranteed and not stable. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn abort() -> ! { - unreachable!() -} +pub fn abort() -> !; /// Informs the optimizer that this point in the code is not reachable, /// enabling further optimizations. @@ -1435,10 +1090,7 @@ pub fn abort() -> ! { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unreachable() -> ! { - unreachable!() -} +pub const unsafe fn unreachable() -> !; /// Informs the optimizer that a condition is always true. /// If the condition is false, the behavior is undefined. @@ -1550,10 +1202,7 @@ pub fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn assert_inhabited() { - unreachable!() -} +pub const fn assert_inhabited(); /// A guard for unsafe functions that cannot ever be executed if `T` does not permit /// zero-initialization: This will statically either panic, or do nothing. @@ -1562,10 +1211,7 @@ pub const fn assert_inhabited() { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn assert_zero_valid() { - unreachable!() -} +pub const fn assert_zero_valid(); /// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing. /// @@ -1573,10 +1219,7 @@ pub const fn assert_zero_valid() { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn assert_mem_uninitialized_valid() { - unreachable!() -} +pub const fn assert_mem_uninitialized_valid(); /// Gets a reference to a static `Location` indicating where it was called. /// @@ -1589,10 +1232,7 @@ pub const fn assert_mem_uninitialized_valid() { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn caller_location() -> &'static crate::panic::Location<'static> { - unreachable!() -} +pub const fn caller_location() -> &'static crate::panic::Location<'static>; /// Moves a value out of scope without running drop glue. /// @@ -1606,10 +1246,7 @@ pub const fn caller_location() -> &'static crate::panic::Location<'static> { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn forget(_: T) { - unreachable!() -} +pub const fn forget(_: T); /// Reinterprets the bits of a value of one type as another type. /// @@ -1902,10 +1539,7 @@ pub const fn forget(_: T) { #[rustc_diagnostic_item = "transmute"] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn transmute(_src: Src) -> Dst { - unreachable!() -} +pub const unsafe fn transmute(_src: Src) -> Dst; /// Like [`transmute`], but even less checked at compile-time: rather than /// giving an error for `size_of::() != size_of::()`, it's @@ -1919,10 +1553,7 @@ pub const unsafe fn transmute(_src: Src) -> Dst { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn transmute_unchecked(_src: Src) -> Dst { - unreachable!() -} +pub const unsafe fn transmute_unchecked(_src: Src) -> Dst; /// Returns `true` if the actual type given as `T` requires drop /// glue; returns `false` if the actual type provided for `T` @@ -1940,10 +1571,7 @@ pub const unsafe fn transmute_unchecked(_src: Src) -> Dst { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn needs_drop() -> bool { - unreachable!() -} +pub const fn needs_drop() -> bool; /// Calculates the offset from a pointer. /// @@ -1965,10 +1593,7 @@ pub const fn needs_drop() -> bool { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr { - unreachable!() -} +pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr; /// Calculates the offset from a pointer, potentially wrapping. /// @@ -1987,10 +1612,7 @@ pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T { - unreachable!() -} +pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T; /// Masks out bits of the pointer according to a mask. /// @@ -2002,10 +1624,7 @@ pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T /// Consider using [`pointer::mask`] instead. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T { - unreachable!() -} +pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T; /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of @@ -2016,11 +1635,8 @@ pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T { /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const T, _count: usize) { - unreachable!() -} +pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const T, _count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count * size_of::()` and an alignment of /// `min_align_of::()` @@ -2030,11 +1646,8 @@ pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usize) { - unreachable!() -} +pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count * size_of::()` and an alignment of /// `min_align_of::()`. @@ -2044,504 +1657,357 @@ pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usiz /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn volatile_set_memory(_dst: *mut T, _val: u8, _count: usize) { - unreachable!() -} +pub unsafe fn volatile_set_memory(_dst: *mut T, _val: u8, _count: usize); /// Performs a volatile load from the `src` pointer. /// /// The stabilized version of this intrinsic is [`core::ptr::read_volatile`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn volatile_load(_src: *const T) -> T { - unreachable!() -} +pub unsafe fn volatile_load(_src: *const T) -> T; /// Performs a volatile store to the `dst` pointer. /// /// The stabilized version of this intrinsic is [`core::ptr::write_volatile`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn volatile_store(_dst: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn volatile_store(_dst: *mut T, _val: T); /// Performs a volatile load from the `src` pointer /// The pointer is not required to be aligned. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] -pub unsafe fn unaligned_volatile_load(_src: *const T) -> T { - unreachable!() -} +pub unsafe fn unaligned_volatile_load(_src: *const T) -> T; /// Performs a volatile store to the `dst` pointer. /// The pointer is not required to be aligned. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] -pub unsafe fn unaligned_volatile_store(_dst: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn unaligned_volatile_store(_dst: *mut T, _val: T); /// Returns the square root of an `f16` /// /// The stabilized version of this intrinsic is /// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sqrtf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn sqrtf16(_x: f16) -> f16; /// Returns the square root of an `f32` /// /// The stabilized version of this intrinsic is /// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sqrtf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn sqrtf32(_x: f32) -> f32; /// Returns the square root of an `f64` /// /// The stabilized version of this intrinsic is /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sqrtf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn sqrtf64(_x: f64) -> f64; /// Returns the square root of an `f128` /// /// The stabilized version of this intrinsic is /// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sqrtf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn sqrtf128(_x: f128) -> f128; /// Raises an `f16` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f16::powi`](../../std/primitive.f16.html#method.powi) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powif16(_a: f16, _x: i32) -> f16 { - unreachable!() -} +pub unsafe fn powif16(_a: f16, _x: i32) -> f16; /// Raises an `f32` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f32::powi`](../../std/primitive.f32.html#method.powi) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powif32(_a: f32, _x: i32) -> f32 { - unreachable!() -} +pub unsafe fn powif32(_a: f32, _x: i32) -> f32; /// Raises an `f64` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f64::powi`](../../std/primitive.f64.html#method.powi) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powif64(_a: f64, _x: i32) -> f64 { - unreachable!() -} +pub unsafe fn powif64(_a: f64, _x: i32) -> f64; /// Raises an `f128` to an integer power. /// /// The stabilized version of this intrinsic is /// [`f128::powi`](../../std/primitive.f128.html#method.powi) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powif128(_a: f128, _x: i32) -> f128 { - unreachable!() -} +pub unsafe fn powif128(_a: f128, _x: i32) -> f128; /// Returns the sine of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::sin`](../../std/primitive.f16.html#method.sin) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sinf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn sinf16(_x: f16) -> f16; /// Returns the sine of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::sin`](../../std/primitive.f32.html#method.sin) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sinf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn sinf32(_x: f32) -> f32; /// Returns the sine of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::sin`](../../std/primitive.f64.html#method.sin) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sinf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn sinf64(_x: f64) -> f64; /// Returns the sine of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::sin`](../../std/primitive.f128.html#method.sin) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn sinf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn sinf128(_x: f128) -> f128; /// Returns the cosine of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::cos`](../../std/primitive.f16.html#method.cos) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn cosf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn cosf16(_x: f16) -> f16; /// Returns the cosine of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::cos`](../../std/primitive.f32.html#method.cos) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn cosf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn cosf32(_x: f32) -> f32; /// Returns the cosine of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::cos`](../../std/primitive.f64.html#method.cos) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn cosf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn cosf64(_x: f64) -> f64; /// Returns the cosine of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::cos`](../../std/primitive.f128.html#method.cos) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn cosf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn cosf128(_x: f128) -> f128; /// Raises an `f16` to an `f16` power. /// /// The stabilized version of this intrinsic is /// [`f16::powf`](../../std/primitive.f16.html#method.powf) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powf16(_a: f16, _x: f16) -> f16 { - unreachable!() -} +pub unsafe fn powf16(_a: f16, _x: f16) -> f16; /// Raises an `f32` to an `f32` power. /// /// The stabilized version of this intrinsic is /// [`f32::powf`](../../std/primitive.f32.html#method.powf) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powf32(_a: f32, _x: f32) -> f32 { - unreachable!() -} +pub unsafe fn powf32(_a: f32, _x: f32) -> f32; /// Raises an `f64` to an `f64` power. /// /// The stabilized version of this intrinsic is /// [`f64::powf`](../../std/primitive.f64.html#method.powf) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powf64(_a: f64, _x: f64) -> f64 { - unreachable!() -} +pub unsafe fn powf64(_a: f64, _x: f64) -> f64; /// Raises an `f128` to an `f128` power. /// /// The stabilized version of this intrinsic is /// [`f128::powf`](../../std/primitive.f128.html#method.powf) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn powf128(_a: f128, _x: f128) -> f128 { - unreachable!() -} +pub unsafe fn powf128(_a: f128, _x: f128) -> f128; /// Returns the exponential of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::exp`](../../std/primitive.f16.html#method.exp) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn expf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn expf16(_x: f16) -> f16; /// Returns the exponential of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::exp`](../../std/primitive.f32.html#method.exp) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn expf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn expf32(_x: f32) -> f32; /// Returns the exponential of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::exp`](../../std/primitive.f64.html#method.exp) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn expf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn expf64(_x: f64) -> f64; /// Returns the exponential of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::exp`](../../std/primitive.f128.html#method.exp) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn expf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn expf128(_x: f128) -> f128; /// Returns 2 raised to the power of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn exp2f16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn exp2f16(_x: f16) -> f16; /// Returns 2 raised to the power of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn exp2f32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn exp2f32(_x: f32) -> f32; /// Returns 2 raised to the power of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn exp2f64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn exp2f64(_x: f64) -> f64; /// Returns 2 raised to the power of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn exp2f128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn exp2f128(_x: f128) -> f128; /// Returns the natural logarithm of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::ln`](../../std/primitive.f16.html#method.ln) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn logf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn logf16(_x: f16) -> f16; /// Returns the natural logarithm of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::ln`](../../std/primitive.f32.html#method.ln) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn logf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn logf32(_x: f32) -> f32; /// Returns the natural logarithm of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::ln`](../../std/primitive.f64.html#method.ln) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn logf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn logf64(_x: f64) -> f64; /// Returns the natural logarithm of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::ln`](../../std/primitive.f128.html#method.ln) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn logf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn logf128(_x: f128) -> f128; /// Returns the base 10 logarithm of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::log10`](../../std/primitive.f16.html#method.log10) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log10f16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn log10f16(_x: f16) -> f16; /// Returns the base 10 logarithm of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::log10`](../../std/primitive.f32.html#method.log10) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log10f32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn log10f32(_x: f32) -> f32; /// Returns the base 10 logarithm of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::log10`](../../std/primitive.f64.html#method.log10) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log10f64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn log10f64(_x: f64) -> f64; /// Returns the base 10 logarithm of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::log10`](../../std/primitive.f128.html#method.log10) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log10f128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn log10f128(_x: f128) -> f128; /// Returns the base 2 logarithm of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::log2`](../../std/primitive.f16.html#method.log2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log2f16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn log2f16(_x: f16) -> f16; /// Returns the base 2 logarithm of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::log2`](../../std/primitive.f32.html#method.log2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log2f32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn log2f32(_x: f32) -> f32; /// Returns the base 2 logarithm of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::log2`](../../std/primitive.f64.html#method.log2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log2f64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn log2f64(_x: f64) -> f64; /// Returns the base 2 logarithm of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::log2`](../../std/primitive.f128.html#method.log2) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn log2f128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn log2f128(_x: f128) -> f128; /// Returns `a * b + c` for `f16` values. /// /// The stabilized version of this intrinsic is /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmaf16(_a: f16, _b: f16, _c: f16) -> f16 { - unreachable!() -} +pub unsafe fn fmaf16(_a: f16, _b: f16, _c: f16) -> f16; /// Returns `a * b + c` for `f32` values. /// /// The stabilized version of this intrinsic is /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmaf32(_a: f32, _b: f32, _c: f32) -> f32 { - unreachable!() -} +pub unsafe fn fmaf32(_a: f32, _b: f32, _c: f32) -> f32; /// Returns `a * b + c` for `f64` values. /// /// The stabilized version of this intrinsic is /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmaf64(_a: f64, _b: f64, _c: f64) -> f64 { - unreachable!() -} +pub unsafe fn fmaf64(_a: f64, _b: f64, _c: f64) -> f64; /// Returns `a * b + c` for `f128` values. /// /// The stabilized version of this intrinsic is /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128 { - unreachable!() -} +pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128; /// Returns `a * b + c` for `f16` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -2554,11 +2020,8 @@ pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128 { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16 { - unreachable!() -} +pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16; /// Returns `a * b + c` for `f32` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -2570,11 +2033,8 @@ pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16 { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32 { - unreachable!() -} +pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32; /// Returns `a * b + c` for `f64` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -2586,11 +2046,8 @@ pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32 { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64 { - unreachable!() -} +pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64; /// Returns `a * b + c` for `f128` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the /// intermediate result. @@ -2602,134 +2059,95 @@ pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64 { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmuladdf128(_a: f128, _b: f128, _c: f128) -> f128 { - unreachable!() -} +pub unsafe fn fmuladdf128(_a: f128, _b: f128, _c: f128) -> f128; /// Returns the largest integer less than or equal to an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::floor`](../../std/primitive.f16.html#method.floor) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn floorf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn floorf16(_x: f16) -> f16; /// Returns the largest integer less than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::floor`](../../std/primitive.f32.html#method.floor) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn floorf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn floorf32(_x: f32) -> f32; /// Returns the largest integer less than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::floor`](../../std/primitive.f64.html#method.floor) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn floorf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn floorf64(_x: f64) -> f64; /// Returns the largest integer less than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::floor`](../../std/primitive.f128.html#method.floor) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn floorf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn floorf128(_x: f128) -> f128; /// Returns the smallest integer greater than or equal to an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn ceilf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn ceilf16(_x: f16) -> f16; /// Returns the smallest integer greater than or equal to an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn ceilf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn ceilf32(_x: f32) -> f32; /// Returns the smallest integer greater than or equal to an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn ceilf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn ceilf64(_x: f64) -> f64; /// Returns the smallest integer greater than or equal to an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn ceilf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn ceilf128(_x: f128) -> f128; /// Returns the integer part of an `f16`. /// /// The stabilized version of this intrinsic is /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn truncf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn truncf16(_x: f16) -> f16; /// Returns the integer part of an `f32`. /// /// The stabilized version of this intrinsic is /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn truncf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn truncf32(_x: f32) -> f32; /// Returns the integer part of an `f64`. /// /// The stabilized version of this intrinsic is /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn truncf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn truncf64(_x: f64) -> f64; /// Returns the integer part of an `f128`. /// /// The stabilized version of this intrinsic is /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn truncf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn truncf128(_x: f128) -> f128; /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even /// least significant digit. @@ -2737,22 +2155,16 @@ pub unsafe fn truncf128(_x: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f16(_x: f16) -> f16 { - unreachable!() -} +pub fn round_ties_even_f16(_x: f16) -> f16; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f16(x: f16) -> f16 { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] - unsafe fn rintf16(_x: f16) -> f16 { - unreachable!() - } + unsafe fn rintf16(_x: f16) -> f16; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf16(x) } @@ -2764,22 +2176,16 @@ pub fn round_ties_even_f16(x: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f32(_x: f32) -> f32 { - unreachable!() -} +pub fn round_ties_even_f32(_x: f32) -> f32; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f32(x: f32) -> f32 { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] - unsafe fn rintf32(_x: f32) -> f32 { - unreachable!() - } + unsafe fn rintf32(_x: f32) -> f32; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf32(x) } @@ -2797,22 +2203,16 @@ pub unsafe fn rintf32(x: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f64(_x: f64) -> f64 { - unreachable!() -} +pub fn round_ties_even_f64(_x: f64) -> f64; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f64(x: f64) -> f64 { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] - unsafe fn rintf64(_x: f64) -> f64 { - unreachable!() - } + unsafe fn rintf64(_x: f64) -> f64; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf64(x) } @@ -2830,22 +2230,16 @@ pub unsafe fn rintf64(x: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] #[cfg(not(bootstrap))] -pub fn round_ties_even_f128(_x: f128) -> f128 { - unreachable!() -} +pub fn round_ties_even_f128(_x: f128) -> f128; /// To be removed on next bootstrap bump. #[cfg(bootstrap)] pub fn round_ties_even_f128(x: f128) -> f128 { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] - unsafe fn rintf128(_x: f128) -> f128 { - unreachable!() - } + unsafe fn rintf128(_x: f128) -> f128; // SAFETY: this intrinsic isn't actually unsafe unsafe { rintf128(x) } @@ -2856,157 +2250,112 @@ pub fn round_ties_even_f128(x: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::round`](../../std/primitive.f16.html#method.round) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn roundf16(_x: f16) -> f16 { - unreachable!() -} +pub unsafe fn roundf16(_x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f32::round`](../../std/primitive.f32.html#method.round) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn roundf32(_x: f32) -> f32 { - unreachable!() -} +pub unsafe fn roundf32(_x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f64::round`](../../std/primitive.f64.html#method.round) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn roundf64(_x: f64) -> f64 { - unreachable!() -} +pub unsafe fn roundf64(_x: f64) -> f64; /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is /// [`f128::round`](../../std/primitive.f128.html#method.round) #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn roundf128(_x: f128) -> f128 { - unreachable!() -} +pub unsafe fn roundf128(_x: f128) -> f128; /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fadd_fast(_a: T, _b: T) -> T { - unreachable!() -} +pub unsafe fn fadd_fast(_a: T, _b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fsub_fast(_a: T, _b: T) -> T { - unreachable!() -} +pub unsafe fn fsub_fast(_a: T, _b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fmul_fast(_a: T, _b: T) -> T { - unreachable!() -} +pub unsafe fn fmul_fast(_a: T, _b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn fdiv_fast(_a: T, _b: T) -> T { - unreachable!() -} +pub unsafe fn fdiv_fast(_a: T, _b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn frem_fast(_a: T, _b: T) -> T { - unreachable!() -} +pub unsafe fn frem_fast(_a: T, _b: T) -> T; /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range /// () /// /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn float_to_int_unchecked(_value: Float) -> Int { - unreachable!() -} +pub unsafe fn float_to_int_unchecked(_value: Float) -> Int; /// Float addition that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn fadd_algebraic(_a: T, _b: T) -> T { - unimplemented!() -} +pub fn fadd_algebraic(_a: T, _b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn fsub_algebraic(_a: T, _b: T) -> T { - unimplemented!() -} +pub fn fsub_algebraic(_a: T, _b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn fmul_algebraic(_a: T, _b: T) -> T { - unimplemented!() -} +pub fn fmul_algebraic(_a: T, _b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn fdiv_algebraic(_a: T, _b: T) -> T { - unimplemented!() -} +pub fn fdiv_algebraic(_a: T, _b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn frem_algebraic(_a: T, _b: T) -> T { - unimplemented!() -} +pub fn frem_algebraic(_a: T, _b: T) -> T; /// Returns the number of bits set in an integer type `T` /// @@ -3021,10 +2370,7 @@ pub fn frem_algebraic(_a: T, _b: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn ctpop(_x: T) -> u32 { - unimplemented!() -} +pub const fn ctpop(_x: T) -> u32; /// Returns the number of leading unset bits (zeroes) in an integer type `T`. /// @@ -3065,10 +2411,7 @@ pub const fn ctpop(_x: T) -> u32 { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn ctlz(_x: T) -> u32 { - unimplemented!() -} +pub const fn ctlz(_x: T) -> u32; /// Like `ctlz`, but extra-unsafe as it returns `undef` when /// given an `x` with value `0`. @@ -3090,10 +2433,7 @@ pub const fn ctlz(_x: T) -> u32 { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn ctlz_nonzero(_x: T) -> u32 { - unimplemented!() -} +pub const unsafe fn ctlz_nonzero(_x: T) -> u32; /// Returns the number of trailing unset bits (zeroes) in an integer type `T`. /// @@ -3134,10 +2474,7 @@ pub const unsafe fn ctlz_nonzero(_x: T) -> u32 { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn cttz(_x: T) -> u32 { - unimplemented!() -} +pub const fn cttz(_x: T) -> u32; /// Like `cttz`, but extra-unsafe as it returns `undef` when /// given an `x` with value `0`. @@ -3159,10 +2496,7 @@ pub const fn cttz(_x: T) -> u32 { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn cttz_nonzero(_x: T) -> u32 { - unimplemented!() -} +pub const unsafe fn cttz_nonzero(_x: T) -> u32; /// Reverses the bytes in an integer type `T`. /// @@ -3177,10 +2511,7 @@ pub const unsafe fn cttz_nonzero(_x: T) -> u32 { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn bswap(_x: T) -> T { - unimplemented!() -} +pub const fn bswap(_x: T) -> T; /// Reverses the bits in an integer type `T`. /// @@ -3195,10 +2526,7 @@ pub const fn bswap(_x: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn bitreverse(_x: T) -> T { - unimplemented!() -} +pub const fn bitreverse(_x: T) -> T; /// Does a three-way comparison between the two integer arguments. /// @@ -3208,10 +2536,7 @@ pub const fn bitreverse(_x: T) -> T { /// /// The stabilized version of this intrinsic is [`Ord::cmp`]. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Ordering { - unimplemented!() -} +pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Ordering; /// Combine two values which have no bits in common. /// @@ -3246,10 +2571,7 @@ pub const unsafe fn disjoint_bitor(a: T, b: T #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool) { - unimplemented!() -} +pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool); /// Performs checked integer subtraction /// @@ -3264,10 +2586,7 @@ pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool) { - unimplemented!() -} +pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool); /// Performs checked integer multiplication /// @@ -3282,10 +2601,7 @@ pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool) { - unimplemented!() -} +pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool); /// Performs full-width multiplication and addition with a carry: /// `multiplier * multiplicand + addend + carry`. @@ -3321,10 +2637,7 @@ pub const fn carrying_mul_add, /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn exact_div(_x: T, _y: T) -> T { - unimplemented!() -} +pub const unsafe fn exact_div(_x: T, _y: T) -> T; /// Performs an unchecked division, resulting in undefined behavior /// where `y == 0` or `x == T::MIN && y == -1` @@ -3335,10 +2648,7 @@ pub const unsafe fn exact_div(_x: T, _y: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_div(_x: T, _y: T) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_div(_x: T, _y: T) -> T; /// Returns the remainder of an unchecked division, resulting in /// undefined behavior when `y == 0` or `x == T::MIN && y == -1` /// @@ -3348,10 +2658,7 @@ pub const unsafe fn unchecked_div(_x: T, _y: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T; /// Performs an unchecked left shift, resulting in undefined behavior when /// `y < 0` or `y >= N`, where N is the width of T in bits. @@ -3362,10 +2669,7 @@ pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T; /// Performs an unchecked right shift, resulting in undefined behavior when /// `y < 0` or `y >= N`, where N is the width of T in bits. /// @@ -3375,10 +2679,7 @@ pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T; /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`. @@ -3388,10 +2689,7 @@ pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_add(_x: T, _y: T) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_add(_x: T, _y: T) -> T; /// Returns the result of an unchecked subtraction, resulting in /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`. @@ -3401,10 +2699,7 @@ pub const unsafe fn unchecked_add(_x: T, _y: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`. @@ -3414,10 +2709,7 @@ pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T { - unimplemented!() -} +pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T; /// Performs rotate left. /// @@ -3432,10 +2724,7 @@ pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn rotate_left(_x: T, _shift: u32) -> T { - unimplemented!() -} +pub const fn rotate_left(_x: T, _shift: u32) -> T; /// Performs rotate right. /// @@ -3450,10 +2739,7 @@ pub const fn rotate_left(_x: T, _shift: u32) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn rotate_right(_x: T, _shift: u32) -> T { - unimplemented!() -} +pub const fn rotate_right(_x: T, _shift: u32) -> T; /// Returns (a + b) mod 2N, where N is the width of T in bits. /// @@ -3468,10 +2754,7 @@ pub const fn rotate_right(_x: T, _shift: u32) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn wrapping_add(_a: T, _b: T) -> T { - unimplemented!() -} +pub const fn wrapping_add(_a: T, _b: T) -> T; /// Returns (a - b) mod 2N, where N is the width of T in bits. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -3485,10 +2768,7 @@ pub const fn wrapping_add(_a: T, _b: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn wrapping_sub(_a: T, _b: T) -> T { - unimplemented!() -} +pub const fn wrapping_sub(_a: T, _b: T) -> T; /// Returns (a * b) mod 2N, where N is the width of T in bits. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -3502,10 +2782,7 @@ pub const fn wrapping_sub(_a: T, _b: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn wrapping_mul(_a: T, _b: T) -> T { - unimplemented!() -} +pub const fn wrapping_mul(_a: T, _b: T) -> T; /// Computes `a + b`, saturating at numeric bounds. /// @@ -3520,10 +2797,7 @@ pub const fn wrapping_mul(_a: T, _b: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn saturating_add(_a: T, _b: T) -> T { - unimplemented!() -} +pub const fn saturating_add(_a: T, _b: T) -> T; /// Computes `a - b`, saturating at numeric bounds. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -3537,10 +2811,7 @@ pub const fn saturating_add(_a: T, _b: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn saturating_sub(_a: T, _b: T) -> T { - unimplemented!() -} +pub const fn saturating_sub(_a: T, _b: T) -> T; /// This is an implementation detail of [`crate::ptr::read`] and should /// not be used anywhere else. See its comments for why this exists. @@ -3551,10 +2822,7 @@ pub const fn saturating_sub(_a: T, _b: T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn read_via_copy(_ptr: *const T) -> T { - unimplemented!() -} +pub const unsafe fn read_via_copy(_ptr: *const T) -> T; /// This is an implementation detail of [`crate::ptr::write`] and should /// not be used anywhere else. See its comments for why this exists. @@ -3565,10 +2833,7 @@ pub const unsafe fn read_via_copy(_ptr: *const T) -> T { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn write_via_move(_ptr: *mut T, _value: T) { - unimplemented!() -} +pub const unsafe fn write_via_move(_ptr: *mut T, _value: T); /// Returns the value of the discriminant for the variant in 'v'; /// if `T` has no discriminant, returns `0`. @@ -3582,10 +2847,7 @@ pub const unsafe fn write_via_move(_ptr: *mut T, _value: T) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn discriminant_value(_v: &T) -> ::Discriminant { - unimplemented!() -} +pub const fn discriminant_value(_v: &T) -> ::Discriminant; /// 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. @@ -3604,15 +2866,12 @@ pub const fn discriminant_value(_v: &T) -> ::Discrimin /// For more information, see the compiler's source, as well as the documentation for the stable /// version of this intrinsic, `std::panic::catch_unwind`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] pub unsafe fn catch_unwind( _try_fn: fn(*mut u8), _data: *mut u8, _catch_fn: fn(*mut u8, *mut u8), -) -> i32 { - unreachable!() -} +) -> i32; /// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held /// in cache. Except for performance, this is fully equivalent to `ptr.write(val)`. @@ -3621,29 +2880,20 @@ pub unsafe fn catch_unwind( /// exists, that operation is *not* equivalent to `ptr.write(val)` (`MOVNT` writes can be reordered /// in ways that are not allowed for regular writes). #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn nontemporal_store(_ptr: *mut T, _val: T) { - unreachable!() -} +pub unsafe fn nontemporal_store(_ptr: *mut T, _val: T); /// See documentation of `<*const T>::offset_from` for details. #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn ptr_offset_from(_ptr: *const T, _base: *const T) -> isize { - unimplemented!() -} +pub const unsafe fn ptr_offset_from(_ptr: *const T, _base: *const T) -> isize; /// See documentation of `<*const T>::sub_ptr` for details. #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_intrinsic_const_stable_indirect] -pub const unsafe fn ptr_offset_from_unsigned(_ptr: *const T, _base: *const T) -> usize { - unimplemented!() -} +pub const unsafe fn ptr_offset_from_unsigned(_ptr: *const T, _base: *const T) -> usize; /// See documentation of `<*const T>::guaranteed_eq` for details. /// Returns `2` if the result is unknown. @@ -3683,10 +2933,7 @@ pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { /// which is UB if any of their inputs are `undef`.) #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool { - unimplemented!() -} +pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool; /// Lexicographically compare `[left, left + bytes)` and `[right, right + bytes)` /// as unsigned bytes, returning negative if `left` is less, zero if all the @@ -3704,21 +2951,15 @@ pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool { /// [valid]: crate::ptr#safety #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: usize) -> i32 { - unimplemented!() -} +pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: usize) -> i32; /// See documentation of [`std::hint::black_box`] for details. /// /// [`std::hint::black_box`]: crate::hint::black_box #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_intrinsic_const_stable_indirect] -pub const fn black_box(_dummy: T) -> T { - unimplemented!() -} +pub const fn black_box(_dummy: T) -> T; /// Selects which function to call depending on the context. /// @@ -3774,7 +3015,6 @@ pub const fn black_box(_dummy: T) -> T { /// otherwise, that principle should not be violated. #[rustc_const_unstable(feature = "const_eval_select", issue = "124625")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] pub const fn const_eval_select( _arg: ARG, _called_in_const: F, @@ -3782,10 +3022,7 @@ pub const fn const_eval_select( ) -> RET where G: FnOnce, - F: FnOnce, -{ - unreachable!() -} + F: FnOnce; /// A macro to make it easier to invoke const_eval_select. Use as follows: /// ```rust,ignore (just a macro example) @@ -4081,10 +3318,7 @@ pub fn contract_check_ensures<'a, Ret, C: Fn(&'a Ret) -> bool>(ret: &'a Ret, con #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub unsafe fn vtable_size(_ptr: *const ()) -> usize { - unreachable!() -} +pub unsafe fn vtable_size(_ptr: *const ()) -> usize; /// The intrinsic will return the alignment stored in that vtable. /// @@ -4094,10 +3328,7 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub unsafe fn vtable_align(_ptr: *const ()) -> usize { - unreachable!() -} +pub unsafe fn vtable_align(_ptr: *const ()) -> usize; /// The size of a type in bytes. /// @@ -4114,10 +3345,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn size_of() -> usize { - unreachable!() -} +pub const fn size_of() -> usize; /// The minimum alignment of a type. /// @@ -4131,10 +3359,7 @@ pub const fn size_of() -> usize { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn min_align_of() -> usize { - unreachable!() -} +pub const fn min_align_of() -> usize; /// The preferred alignment of a type. /// @@ -4143,10 +3368,7 @@ pub const fn min_align_of() -> usize { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn pref_align_of() -> usize { - unreachable!() -} +pub const unsafe fn pref_align_of() -> usize; /// Returns the number of variants of the type `T` cast to a `usize`; /// if `T` has no variants, returns `0`. Uninhabited variants will be counted. @@ -4160,10 +3382,7 @@ pub const unsafe fn pref_align_of() -> usize { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn variant_count() -> usize { - unreachable!() -} +pub const fn variant_count() -> usize; /// The size of the referenced value in bytes. /// @@ -4175,11 +3394,8 @@ pub const fn variant_count() -> usize { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_intrinsic_const_stable_indirect] -pub const unsafe fn size_of_val(_ptr: *const T) -> usize { - unreachable!() -} +pub const unsafe fn size_of_val(_ptr: *const T) -> usize; /// The required alignment of the referenced value. /// @@ -4191,11 +3407,8 @@ pub const unsafe fn size_of_val(_ptr: *const T) -> usize { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_intrinsic_const_stable_indirect] -pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize { - unreachable!() -} +pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize; /// Gets a static string slice containing the name of a type. /// @@ -4208,10 +3421,7 @@ pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn type_name() -> &'static str { - unreachable!() -} +pub const fn type_name() -> &'static str; /// Gets an identifier which is globally unique to the specified type. This /// function will return the same value for a type regardless of whichever @@ -4226,10 +3436,7 @@ pub const fn type_name() -> &'static str { #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn type_id() -> u128 { - unreachable!() -} +pub const fn type_id() -> u128; /// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`. /// @@ -4240,12 +3447,7 @@ pub const fn type_id() -> u128 { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P { - // To implement a fallback we'd have to assume the layout of the pointer, - // but the whole point of this intrinsic is that we shouldn't do that. - unreachable!() -} +pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P; #[unstable(feature = "core_intrinsics", issue = "none")] pub trait AggregateRawPtr { @@ -4265,12 +3467,7 @@ impl AggregateRawPtr<*mut T> for *mut P { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M { - // To implement a fallback we'd have to assume the layout of the pointer, - // but the whole point of this intrinsic is that we shouldn't do that. - unreachable!() -} +pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M; // Some functions are defined here because they accidentally got made // available in this module on stable. See . @@ -4372,10 +3569,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - const unsafe fn copy_nonoverlapping(_src: *const T, _dst: *mut T, _count: usize) { - unreachable!() - } + const unsafe fn copy_nonoverlapping(_src: *const T, _dst: *mut T, _count: usize); ub_checks::assert_unsafe_precondition!( check_language_ub, @@ -4476,10 +3670,7 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - const unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize) { - unreachable!() - } + const unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); // SAFETY: the safety contract for `copy` must be upheld by the caller. unsafe { @@ -4559,10 +3750,7 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - const unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize) { - unreachable!() - } + const unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); // SAFETY: the safety contract for `write_bytes` must be upheld by the caller. unsafe { @@ -4590,10 +3778,7 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { /// [`f16::min`] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn minnumf16(_x: f16, _y: f16) -> f16 { - unimplemented!(); -} +pub const fn minnumf16(_x: f16, _y: f16) -> f16; /// Returns the minimum of two `f32` values. /// @@ -4607,10 +3792,7 @@ pub const fn minnumf16(_x: f16, _y: f16) -> f16 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn minnumf32(_x: f32, _y: f32) -> f32 { - unimplemented!(); -} +pub const fn minnumf32(_x: f32, _y: f32) -> f32; /// Returns the minimum of two `f64` values. /// @@ -4624,10 +3806,7 @@ pub const fn minnumf32(_x: f32, _y: f32) -> f32 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn minnumf64(_x: f64, _y: f64) -> f64 { - unimplemented!(); -} +pub const fn minnumf64(_x: f64, _y: f64) -> f64; /// Returns the minimum of two `f128` values. /// @@ -4640,10 +3819,7 @@ pub const fn minnumf64(_x: f64, _y: f64) -> f64 { /// [`f128::min`] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn minnumf128(_x: f128, _y: f128) -> f128 { - unimplemented!(); -} +pub const fn minnumf128(_x: f128, _y: f128) -> f128; /// Returns the maximum of two `f16` values. /// @@ -4656,10 +3832,7 @@ pub const fn minnumf128(_x: f128, _y: f128) -> f128 { /// [`f16::max`] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { - unimplemented!(); -} +pub const fn maxnumf16(_x: f16, _y: f16) -> f16; /// Returns the maximum of two `f32` values. /// @@ -4673,10 +3846,7 @@ pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { - unimplemented!(); -} +pub const fn maxnumf32(_x: f32, _y: f32) -> f32; /// Returns the maximum of two `f64` values. /// @@ -4690,10 +3860,7 @@ pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { - unimplemented!(); -} +pub const fn maxnumf64(_x: f64, _y: f64) -> f64; /// Returns the maximum of two `f128` values. /// @@ -4706,10 +3873,7 @@ pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { /// [`f128::max`] #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { - unimplemented!(); -} +pub const fn maxnumf128(_x: f128, _y: f128) -> f128; /// Returns the absolute value of an `f16`. /// @@ -4717,10 +3881,7 @@ pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { /// [`f16::abs`](../../std/primitive.f16.html#method.abs) #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn fabsf16(_x: f16) -> f16 { - unimplemented!(); -} +pub const unsafe fn fabsf16(_x: f16) -> f16; /// Returns the absolute value of an `f32`. /// @@ -4729,10 +3890,7 @@ pub const unsafe fn fabsf16(_x: f16) -> f16 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn fabsf32(_x: f32) -> f32 { - unimplemented!(); -} +pub const unsafe fn fabsf32(_x: f32) -> f32; /// Returns the absolute value of an `f64`. /// @@ -4741,10 +3899,7 @@ pub const unsafe fn fabsf32(_x: f32) -> f32 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn fabsf64(_x: f64) -> f64 { - unimplemented!(); -} +pub const unsafe fn fabsf64(_x: f64) -> f64; /// Returns the absolute value of an `f128`. /// @@ -4752,10 +3907,7 @@ pub const unsafe fn fabsf64(_x: f64) -> f64 { /// [`f128::abs`](../../std/primitive.f128.html#method.abs) #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn fabsf128(_x: f128) -> f128 { - unimplemented!(); -} +pub const unsafe fn fabsf128(_x: f128) -> f128; /// Copies the sign from `y` to `x` for `f16` values. /// @@ -4763,10 +3915,7 @@ pub const unsafe fn fabsf128(_x: f128) -> f128 { /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { - unimplemented!(); -} +pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16; /// Copies the sign from `y` to `x` for `f32` values. /// @@ -4775,10 +3924,7 @@ pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { - unimplemented!(); -} +pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32; /// Copies the sign from `y` to `x` for `f64` values. /// /// The stabilized version of this intrinsic is @@ -4786,10 +3932,7 @@ pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { - unimplemented!(); -} +pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64; /// Copies the sign from `y` to `x` for `f128` values. /// @@ -4797,10 +3940,7 @@ pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) #[rustc_nounwind] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 { - unimplemented!(); -} +pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128; /// Inform Miri that a given pointer definitely has a certain alignment. #[cfg(miri)] diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index e59d3aff37999..3bde183fefb71 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -10,11 +10,8 @@ /// /// `idx` must be in-bounds of the vector. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T { - unreachable!() -} +pub unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T; /// Extracts an element from a vector. /// @@ -24,41 +21,29 @@ pub unsafe fn simd_insert(_x: T, _idx: u32, _val: U) -> T { /// /// `idx` must be in-bounds of the vector. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_extract(_x: T, _idx: u32) -> U { - unreachable!() -} +pub unsafe fn simd_extract(_x: T, _idx: u32) -> U; /// Adds two simd vectors elementwise. /// /// `T` must be a vector of integer or floating point primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_add(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_add(_x: T, _y: T) -> T; /// Subtracts `rhs` from `lhs` elementwise. /// /// `T` must be a vector of integer or floating point primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_sub(_lhs: T, _rhs: T) -> T { - unreachable!() -} +pub unsafe fn simd_sub(_lhs: T, _rhs: T) -> T; /// Multiplies two simd vectors elementwise. /// /// `T` must be a vector of integer or floating point primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_mul(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_mul(_x: T, _y: T) -> T; /// Divides `lhs` by `rhs` elementwise. /// @@ -68,11 +53,8 @@ pub unsafe fn simd_mul(_x: T, _y: T) -> T { /// For integers, `rhs` must not contain any zero elements. /// Additionally for signed integers, `::MIN / -1` is undefined behavior. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T { - unreachable!() -} +pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T; /// Returns remainder of two vectors elementwise. /// @@ -82,11 +64,8 @@ pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T { /// For integers, `rhs` must not contain any zero elements. /// Additionally for signed integers, `::MIN / -1` is undefined behavior. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T { - unreachable!() -} +pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T; /// Shifts vector left elementwise, with UB on overflow. /// @@ -98,11 +77,8 @@ pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T { /// /// Each element of `rhs` must be less than `::BITS`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T { - unreachable!() -} +pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T; /// Shifts vector right elementwise, with UB on overflow. /// @@ -114,41 +90,29 @@ pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T { /// /// Each element of `rhs` must be less than `::BITS`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_shr(_lhs: T, _rhs: T) -> T { - unreachable!() -} +pub unsafe fn simd_shr(_lhs: T, _rhs: T) -> T; /// "Ands" vectors elementwise. /// /// `T` must be a vector of integer primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_and(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_and(_x: T, _y: T) -> T; /// "Ors" vectors elementwise. /// /// `T` must be a vector of integer primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_or(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_or(_x: T, _y: T) -> T; /// "Exclusive ors" vectors elementwise. /// /// `T` must be a vector of integer primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_xor(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_xor(_x: T, _y: T) -> T; /// Numerically casts a vector, elementwise. /// @@ -169,11 +133,8 @@ pub unsafe fn simd_xor(_x: T, _y: T) -> T { /// * Not be infinite /// * Be representable in the return type, after truncating off its fractional part #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_cast(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_cast(_x: T) -> U; /// Numerically casts a vector, elementwise. /// @@ -187,11 +148,8 @@ pub unsafe fn simd_cast(_x: T) -> U { /// When casting integers to floats, the result is rounded. /// Otherwise, truncates or extends the value, maintaining the sign for signed integers. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_as(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_as(_x: T) -> U; /// Negates a vector elementwise. /// @@ -199,21 +157,15 @@ pub unsafe fn simd_as(_x: T) -> U { /// /// Rust panics for `-::Min` due to overflow, but it is not UB with this intrinsic. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_neg(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_neg(_x: T) -> T; /// Returns absolute value of a vector, elementwise. /// /// `T` must be a vector of floating-point primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fabs(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_fabs(_x: T) -> T; /// Returns the minimum of two vectors, elementwise. /// @@ -221,11 +173,8 @@ pub unsafe fn simd_fabs(_x: T) -> T { /// /// Follows IEEE-754 `minNum` semantics. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fmin(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_fmin(_x: T, _y: T) -> T; /// Returns the maximum of two vectors, elementwise. /// @@ -233,11 +182,8 @@ pub unsafe fn simd_fmin(_x: T, _y: T) -> T { /// /// Follows IEEE-754 `maxNum` semantics. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fmax(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_fmax(_x: T, _y: T) -> T; /// Tests elementwise equality of two vectors. /// @@ -247,11 +193,8 @@ pub unsafe fn simd_fmax(_x: T, _y: T) -> T { /// /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_eq(_x: T, _y: T) -> U { - unreachable!() -} +pub unsafe fn simd_eq(_x: T, _y: T) -> U; /// Tests elementwise inequality equality of two vectors. /// @@ -261,11 +204,8 @@ pub unsafe fn simd_eq(_x: T, _y: T) -> U { /// /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_ne(_x: T, _y: T) -> U { - unreachable!() -} +pub unsafe fn simd_ne(_x: T, _y: T) -> U; /// Tests if `x` is less than `y`, elementwise. /// @@ -275,11 +215,8 @@ pub unsafe fn simd_ne(_x: T, _y: T) -> U { /// /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_lt(_x: T, _y: T) -> U { - unreachable!() -} +pub unsafe fn simd_lt(_x: T, _y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. /// @@ -289,11 +226,8 @@ pub unsafe fn simd_lt(_x: T, _y: T) -> U { /// /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_le(_x: T, _y: T) -> U { - unreachable!() -} +pub unsafe fn simd_le(_x: T, _y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. /// @@ -303,11 +237,8 @@ pub unsafe fn simd_le(_x: T, _y: T) -> U { /// /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_gt(_x: T, _y: T) -> U { - unreachable!() -} +pub unsafe fn simd_gt(_x: T, _y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. /// @@ -317,11 +248,8 @@ pub unsafe fn simd_gt(_x: T, _y: T) -> U { /// /// Returns `0` for false and `!0` for true. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_ge(_x: T, _y: T) -> U { - unreachable!() -} +pub unsafe fn simd_ge(_x: T, _y: T) -> U; /// Shuffles two vectors by const indices. /// @@ -336,11 +264,8 @@ pub unsafe fn simd_ge(_x: T, _y: T) -> U { /// is the concatenation of `x` and `y`. It is a compile-time error if `idx[i]` is out-of-bounds /// of `xy`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V { - unreachable!() -} +pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V; /// Reads a vector of pointers. /// @@ -360,11 +285,8 @@ pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V { /// /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T { - unreachable!() -} +pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T; /// Writes to a vector of pointers. /// @@ -387,11 +309,8 @@ pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T { /// /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V) { - unreachable!() -} +pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V); /// Reads a vector of pointers. /// @@ -413,11 +332,8 @@ pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V) { /// /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T { - unreachable!() -} +pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T; /// Writes to a vector of pointers. /// @@ -438,21 +354,15 @@ pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T { /// /// `mask` must only contain `0` or `!0` values. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_masked_store(_mask: V, _ptr: U, _val: T) { - unreachable!() -} +pub unsafe fn simd_masked_store(_mask: V, _ptr: U, _val: T); /// Adds two simd vectors elementwise, with saturation. /// /// `T` must be a vector of integer primitive types. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_saturating_add(_x: T, _y: T) -> T { - unreachable!() -} +pub unsafe fn simd_saturating_add(_x: T, _y: T) -> T; /// Subtracts two simd vectors elementwise, with saturation. /// @@ -460,11 +370,8 @@ pub unsafe fn simd_saturating_add(_x: T, _y: T) -> T { /// /// Subtract `rhs` from `lhs`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T { - unreachable!() -} +pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T; /// Adds elements within a vector from left to right. /// @@ -474,11 +381,8 @@ pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T { /// /// Starting with the value `y`, add the elements of `x` and accumulate. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U; /// Adds elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. @@ -487,11 +391,8 @@ pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U { /// /// `U` must be the element type of `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_add_unordered(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_add_unordered(_x: T) -> U; /// Multiplies elements within a vector from left to right. /// @@ -501,11 +402,8 @@ pub unsafe fn simd_reduce_add_unordered(_x: T) -> U { /// /// Starting with the value `y`, multiply the elements of `x` and accumulate. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U; /// Multiplies elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. @@ -514,11 +412,8 @@ pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U { /// /// `U` must be the element type of `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_mul_unordered(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_mul_unordered(_x: T) -> U; /// Checks if all mask values are true. /// @@ -527,11 +422,8 @@ pub unsafe fn simd_reduce_mul_unordered(_x: T) -> U { /// # Safety /// `x` must contain only `0` or `!0`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_all(_x: T) -> bool { - unreachable!() -} +pub unsafe fn simd_reduce_all(_x: T) -> bool; /// Checks if any mask value is true. /// @@ -540,11 +432,8 @@ pub unsafe fn simd_reduce_all(_x: T) -> bool { /// # Safety /// `x` must contain only `0` or `!0`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_any(_x: T) -> bool { - unreachable!() -} +pub unsafe fn simd_reduce_any(_x: T) -> bool; /// Returns the maximum element of a vector. /// @@ -554,11 +443,8 @@ pub unsafe fn simd_reduce_any(_x: T) -> bool { /// /// For floating-point values, uses IEEE-754 `maxNum`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_max(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_max(_x: T) -> U; /// Returns the minimum element of a vector. /// @@ -568,11 +454,8 @@ pub unsafe fn simd_reduce_max(_x: T) -> U { /// /// For floating-point values, uses IEEE-754 `minNum`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_min(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_min(_x: T) -> U; /// Logical "ands" all elements together. /// @@ -580,11 +463,8 @@ pub unsafe fn simd_reduce_min(_x: T) -> U { /// /// `U` must be the element type of `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_and(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_and(_x: T) -> U; /// Logical "ors" all elements together. /// @@ -592,11 +472,8 @@ pub unsafe fn simd_reduce_and(_x: T) -> U { /// /// `U` must be the element type of `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_or(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_or(_x: T) -> U; /// Logical "exclusive ors" all elements together. /// @@ -604,11 +481,8 @@ pub unsafe fn simd_reduce_or(_x: T) -> U { /// /// `U` must be the element type of `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_reduce_xor(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_reduce_xor(_x: T) -> U; /// Truncates an integer vector to a bitmask. /// @@ -644,11 +518,8 @@ pub unsafe fn simd_reduce_xor(_x: T) -> U { /// # Safety /// `x` must contain only `0` and `!0`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_bitmask(_x: T) -> U { - unreachable!() -} +pub unsafe fn simd_bitmask(_x: T) -> U; /// Selects elements from a mask. /// @@ -663,11 +534,8 @@ pub unsafe fn simd_bitmask(_x: T) -> U { /// # Safety /// `mask` must only contain `0` and `!0`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_select(_mask: M, _if_true: T, _if_false: T) -> T { - unreachable!() -} +pub unsafe fn simd_select(_mask: M, _if_true: T, _if_false: T) -> T; /// Selects elements from a bitmask. /// @@ -684,11 +552,8 @@ pub unsafe fn simd_select(_mask: M, _if_true: T, _if_false: T) -> T { /// # Safety /// Padding bits must be all zero. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_select_bitmask(_m: M, _yes: T, _no: T) -> T { - unreachable!() -} +pub unsafe fn simd_select_bitmask(_m: M, _yes: T, _no: T) -> T; /// Calculates the offset from a pointer vector elementwise, potentially /// wrapping. @@ -699,21 +564,15 @@ pub unsafe fn simd_select_bitmask(_m: M, _yes: T, _no: T) -> T { /// /// Operates as if by `::wrapping_offset`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_arith_offset(_ptr: T, _offset: U) -> T { - unreachable!() -} +pub unsafe fn simd_arith_offset(_ptr: T, _offset: U) -> T; /// Casts a vector of pointers. /// /// `T` and `U` must be vectors of pointers with the same number of elements. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_cast_ptr(_ptr: T) -> U { - unreachable!() -} +pub unsafe fn simd_cast_ptr(_ptr: T) -> U; /// Exposes a vector of pointers as a vector of addresses. /// @@ -721,11 +580,8 @@ pub unsafe fn simd_cast_ptr(_ptr: T) -> U { /// /// `U` must be a vector of `usize` with the same length as `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_expose_provenance(_ptr: T) -> U { - unreachable!() -} +pub unsafe fn simd_expose_provenance(_ptr: T) -> U; /// Creates a vector of pointers from a vector of addresses. /// @@ -733,123 +589,87 @@ pub unsafe fn simd_expose_provenance(_ptr: T) -> U { /// /// `U` must be a vector of pointers, with the same length as `T`. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_with_exposed_provenance(_addr: T) -> U { - unreachable!() -} +pub unsafe fn simd_with_exposed_provenance(_addr: T) -> U; /// Swaps bytes of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_bswap(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_bswap(_x: T) -> T; /// Reverses bits of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_bitreverse(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_bitreverse(_x: T) -> T; /// Counts the leading zeros of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_ctlz(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_ctlz(_x: T) -> T; /// Counts the number of ones in each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_ctpop(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_ctpop(_x: T) -> T; /// Counts the trailing zeros of each element. /// /// `T` must be a vector of integers. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_cttz(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_cttz(_x: T) -> T; /// Rounds up each element to the next highest integer-valued float. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_ceil(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_ceil(_x: T) -> T; /// Rounds down each element to the next lowest integer-valued float. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_floor(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_floor(_x: T) -> T; /// Rounds each element to the closest integer-valued float. /// Ties are resolved by rounding away from 0. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_round(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_round(_x: T) -> T; /// Returns the integer part of each element as an integer-valued float. /// In other words, non-integer values are truncated towards zero. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_trunc(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_trunc(_x: T) -> T; /// Takes the square root of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fsqrt(_x: T) -> T { - unreachable!() -} +pub unsafe fn simd_fsqrt(_x: T) -> T; /// Computes `(x*y) + z` for each element, but without any intermediate rounding. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fma(_x: T, _y: T, _z: T) -> T { - unreachable!() -} +pub unsafe fn simd_fma(_x: T, _y: T, _z: T) -> T; /// Computes `(x*y) + z` for each element, non-deterministically executing either /// a fused multiply-add or two operations with rounding of the intermediate result. @@ -863,78 +683,54 @@ pub unsafe fn simd_fma(_x: T, _y: T, _z: T) -> T { /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_relaxed_fma(_x: T, _y: T, _z: T) -> T { - unreachable!() -} +pub unsafe fn simd_relaxed_fma(_x: T, _y: T, _z: T) -> T; // Computes the sine of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fsin(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_fsin(_a: T) -> T; // Computes the cosine of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fcos(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_fcos(_a: T) -> T; // Computes the exponential function of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fexp(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_fexp(_a: T) -> T; // Computes 2 raised to the power of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_fexp2(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_fexp2(_a: T) -> T; // Computes the base 10 logarithm of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_flog10(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_flog10(_a: T) -> T; // Computes the base 2 logarithm of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_flog2(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_flog2(_a: T) -> T; // Computes the natural logarithm of each element. /// /// `T` must be a vector of floats. #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn simd_flog(_a: T) -> T { - unreachable!() -} +pub unsafe fn simd_flog(_a: T) -> T; From 6eea027aa9453b685ac636ea40fc826267afab2a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Feb 2025 17:34:50 +0100 Subject: [PATCH 04/16] remove support for rustc_intrinsic_must_be_overridden from the compiler --- .../example/mini_core.rs | 65 ++++--------------- .../rustc_codegen_gcc/example/mini_core.rs | 65 ++++--------------- .../rustc_codegen_gcc/tests/run/abort1.rs | 5 +- .../rustc_codegen_gcc/tests/run/abort2.rs | 5 +- .../rustc_codegen_gcc/tests/run/assign.rs | 5 +- .../rustc_codegen_gcc/tests/run/mut_ref.rs | 5 +- .../rustc_codegen_gcc/tests/run/operations.rs | 5 +- .../rustc_codegen_gcc/tests/run/static.rs | 5 +- .../src/error_codes/E0094.md | 14 +--- compiler/rustc_feature/src/builtin_attrs.rs | 4 -- compiler/rustc_middle/src/ty/util.rs | 13 ++-- compiler/rustc_span/src/symbol.rs | 1 - .../src/language-features/intrinsics.md | 14 ++-- tests/assembly/rust-abi-arg-attr.rs | 5 +- tests/rustdoc/const-intrinsic.rs | 10 +-- tests/rustdoc/safe-intrinsic.rs | 10 +-- .../stable-mir/check_intrinsics.rs | 6 +- tests/ui/error-codes/E0094.rs | 7 +- tests/ui/error-codes/E0094.stderr | 4 +- tests/ui/error-codes/E0308.rs | 7 +- tests/ui/error-codes/E0308.stderr | 4 +- tests/ui/intrinsics/always-gets-overridden.rs | 4 +- tests/ui/repr/16-bit-repr-c-enum.rs | 5 +- tests/ui/target-feature/feature-hierarchy.rs | 5 +- 24 files changed, 70 insertions(+), 203 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 79820232496a5..72c9df59d833f 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -620,70 +620,31 @@ pub union MaybeUninit { pub mod intrinsics { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn size_of() -> usize { - loop {} - } + pub fn size_of() -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn size_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn size_of_val(_val: *const T) -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn min_align_of() -> usize { - loop {} - } + pub fn min_align_of() -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn min_align_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn min_align_of_val(_val: *const T) -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize) { - loop {} - } + pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn transmute(_e: T) -> U { - loop {} - } + pub unsafe fn transmute(_e: T) -> U; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn ctlz_nonzero(_x: T) -> u32 { - loop {} - } + pub unsafe fn ctlz_nonzero(_x: T) -> u32; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn needs_drop() -> bool { - loop {} - } + pub fn needs_drop() -> bool; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bitreverse(_x: T) -> T { - loop {} - } + pub fn bitreverse(_x: T) -> T; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bswap(_x: T) -> T { - loop {} - } + pub fn bswap(_x: T) -> T; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize) { - loop {} - } + pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn unreachable() -> ! { - loop {} - } + pub unsafe fn unreachable() -> !; } pub mod libc { diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 2ff1d757fd4e0..3dad35bc4ce47 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -591,70 +591,31 @@ pub union MaybeUninit { pub mod intrinsics { #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn size_of() -> usize { - loop {} - } + pub fn size_of() -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn size_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn size_of_val(_val: *const T) -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn min_align_of() -> usize { - loop {} - } + pub fn min_align_of() -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn min_align_of_val(_val: *const T) -> usize { - loop {} - } + pub unsafe fn min_align_of_val(_val: *const T) -> usize; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize) { - loop {} - } + pub unsafe fn copy(_src: *const T, _dst: *mut T, _count: usize); #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn transmute(_e: T) -> U { - loop {} - } + pub unsafe fn transmute(_e: T) -> U; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn ctlz_nonzero(_x: T) -> u32 { - loop {} - } + pub unsafe fn ctlz_nonzero(_x: T) -> u32; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn needs_drop() -> bool { - loop {} - } + pub fn needs_drop() -> bool; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bitreverse(_x: T) -> T { - loop {} - } + pub fn bitreverse(_x: T) -> T; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn bswap(_x: T) -> T { - loop {} - } + pub fn bswap(_x: T) -> T; #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize) { - loop {} - } + pub unsafe fn write_bytes(_dst: *mut T, _val: u8, _count: usize); #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub unsafe fn unreachable() -> ! { - loop {} - } + pub unsafe fn unreachable() -> !; } pub mod libc { diff --git a/compiler/rustc_codegen_gcc/tests/run/abort1.rs b/compiler/rustc_codegen_gcc/tests/run/abort1.rs index 385e41a68817f..fe46d9ae41849 100644 --- a/compiler/rustc_codegen_gcc/tests/run/abort1.rs +++ b/compiler/rustc_codegen_gcc/tests/run/abort1.rs @@ -36,10 +36,7 @@ mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } /* diff --git a/compiler/rustc_codegen_gcc/tests/run/abort2.rs b/compiler/rustc_codegen_gcc/tests/run/abort2.rs index 6c66a930e0741..4123f4f4beebc 100644 --- a/compiler/rustc_codegen_gcc/tests/run/abort2.rs +++ b/compiler/rustc_codegen_gcc/tests/run/abort2.rs @@ -36,10 +36,7 @@ mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } /* diff --git a/compiler/rustc_codegen_gcc/tests/run/assign.rs b/compiler/rustc_codegen_gcc/tests/run/assign.rs index 4d414c577a657..286155852d50f 100644 --- a/compiler/rustc_codegen_gcc/tests/run/assign.rs +++ b/compiler/rustc_codegen_gcc/tests/run/assign.rs @@ -59,10 +59,7 @@ mod libc { mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } #[lang = "panic"] diff --git a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs index 9be64f991ee08..b0215860406e5 100644 --- a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs +++ b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs @@ -61,10 +61,7 @@ mod libc { mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } #[lang = "panic"] diff --git a/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs index c92d3cc0b8fbf..8ba7a4c5ed8ce 100644 --- a/compiler/rustc_codegen_gcc/tests/run/operations.rs +++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs @@ -67,10 +67,7 @@ mod libc { mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } #[lang = "panic"] diff --git a/compiler/rustc_codegen_gcc/tests/run/static.rs b/compiler/rustc_codegen_gcc/tests/run/static.rs index 80c8782c4b1a6..c3c8121b1e195 100644 --- a/compiler/rustc_codegen_gcc/tests/run/static.rs +++ b/compiler/rustc_codegen_gcc/tests/run/static.rs @@ -49,10 +49,7 @@ mod intrinsics { #[rustc_nounwind] #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } + pub fn abort() -> !; } mod libc { diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md index efbfa0851a83f..909da368f2b6f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0094.md +++ b/compiler/rustc_error_codes/src/error_codes/E0094.md @@ -7,12 +7,8 @@ Erroneous code example: #![allow(internal_features)] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -fn size_of() -> usize // error: intrinsic has wrong number - // of type parameters -{ - loop {} -} +fn size_of() -> usize; // error: intrinsic has wrong number + // of type parameters ``` Please check that you provided the right number of type parameters @@ -24,9 +20,5 @@ Example: #![allow(internal_features)] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -fn size_of() -> usize // ok! -{ - loop {} -} +fn size_of() -> usize; // ok! ``` diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index b2ada8fe61ef0..6d16dc00ef4e4 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1005,10 +1005,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics, "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items", ), - gated!( - rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics, - "the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies", - ), rustc_attr!( rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, "#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen" diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 88d5749854231..c153f6bb7d77c 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1755,13 +1755,12 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - !has_body - } - _ => true, - }; + let must_be_overridden = match tcx.hir_node_by_def_id(def_id) { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => { + !has_body + } + _ => true, + }; Some(ty::IntrinsicDef { name: tcx.item_name(def_id.into()), must_be_overridden, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 10c79b1be82d9..e5457991e46ee 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1764,7 +1764,6 @@ symbols! { rustc_insignificant_dtor, rustc_intrinsic, rustc_intrinsic_const_stable_indirect, - rustc_intrinsic_must_be_overridden, rustc_layout, rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_start, diff --git a/src/doc/unstable-book/src/language-features/intrinsics.md b/src/doc/unstable-book/src/language-features/intrinsics.md index 13a6814d31be9..975b400447eb8 100644 --- a/src/doc/unstable-book/src/language-features/intrinsics.md +++ b/src/doc/unstable-book/src/language-features/intrinsics.md @@ -62,13 +62,19 @@ These must be implemented by all backends. ### `#[rustc_intrinsic]` declarations -These are written like intrinsics with fallback bodies, but the body is irrelevant. -Use `loop {}` for the body or call the intrinsic recursively and add -`#[rustc_intrinsic_must_be_overridden]` to the function to ensure that backends don't -invoke the body. +These are written without a body: +```rust +#![feature(intrinsics)] +#![allow(internal_features)] + +#[rustc_intrinsic] +pub fn abort() -> !; +``` ### Legacy extern ABI based intrinsics +*This style is deprecated, always prefer the above form.* + These are imported as if they were FFI functions, with the special `rust-intrinsic` ABI. For example, if one was in a freestanding context, but wished to be able to `transmute` between types, and diff --git a/tests/assembly/rust-abi-arg-attr.rs b/tests/assembly/rust-abi-arg-attr.rs index e55a53fbdeb9c..5b5eeb29f0f41 100644 --- a/tests/assembly/rust-abi-arg-attr.rs +++ b/tests/assembly/rust-abi-arg-attr.rs @@ -51,10 +51,7 @@ enum Ordering { } #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -fn three_way_compare(lhs: T, rhs: T) -> Ordering { - loop {} -} +fn three_way_compare(lhs: T, rhs: T) -> Ordering; // ^^^^^ core diff --git a/tests/rustdoc/const-intrinsic.rs b/tests/rustdoc/const-intrinsic.rs index 8444d4a3aa768..7dedb083b7d01 100644 --- a/tests/rustdoc/const-intrinsic.rs +++ b/tests/rustdoc/const-intrinsic.rs @@ -9,19 +9,13 @@ #[stable(since="1.0.0", feature="rust1")] #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub const unsafe fn transmute(_: T) -> U { - loop {} -} +pub const unsafe fn transmute(_: T) -> U; //@ has 'foo/fn.unreachable.html' //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !' #[stable(since="1.0.0", feature="rust1")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub unsafe fn unreachable() -> ! { - loop {} -} +pub unsafe fn unreachable() -> !; extern "C" { //@ has 'foo/fn.needs_drop.html' diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc/safe-intrinsic.rs index 1edc1d9f79b91..0d2ee89415d4a 100644 --- a/tests/rustdoc/safe-intrinsic.rs +++ b/tests/rustdoc/safe-intrinsic.rs @@ -11,14 +11,8 @@ trait Sized {} //@ has 'foo/fn.abort.html' //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !' #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub fn abort() -> ! { - loop {} -} +pub fn abort() -> !; //@ has 'foo/fn.unreachable.html' //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !' #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -pub unsafe fn unreachable() -> ! { - loop {} -} +pub unsafe fn unreachable() -> !; diff --git a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs index 2f772b978865a..07a2a62e06687 100644 --- a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs +++ b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs @@ -51,13 +51,11 @@ fn test_intrinsics() -> ControlFlow<()> { /// This check is unfortunately tight to the implementation of intrinsics. /// -/// We want to ensure that StableMIR can handle intrinsics with and without fallback body. +/// We want to ensure that StableMIR can handle intrinsics with and without fallback body: +/// for intrinsics without a body, obviously we cannot expose anything. /// /// If by any chance this test breaks because you changed how an intrinsic is implemented, please /// update the test to invoke a different intrinsic. -/// -/// In StableMIR, we only expose intrinsic body if they are not marked with -/// `rustc_intrinsic_must_be_overridden`. fn check_instance(instance: &Instance) { assert_eq!(instance.kind, InstanceKind::Intrinsic); let name = instance.intrinsic_name().unwrap(); diff --git a/tests/ui/error-codes/E0094.rs b/tests/ui/error-codes/E0094.rs index da59d3decac7a..2067179b26aa2 100644 --- a/tests/ui/error-codes/E0094.rs +++ b/tests/ui/error-codes/E0094.rs @@ -1,10 +1,7 @@ #![feature(intrinsics)] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -fn size_of() -> usize { - //~^ ERROR E0094 - loop {} -} +fn size_of() -> usize; +//~^ ERROR E0094 fn main() {} diff --git a/tests/ui/error-codes/E0094.stderr b/tests/ui/error-codes/E0094.stderr index e45cc0ea0639b..da29987f8b1bc 100644 --- a/tests/ui/error-codes/E0094.stderr +++ b/tests/ui/error-codes/E0094.stderr @@ -1,7 +1,7 @@ error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1 - --> $DIR/E0094.rs:5:11 + --> $DIR/E0094.rs:4:11 | -LL | fn size_of() -> usize { +LL | fn size_of() -> usize; | ^^^^^^ expected 1 type parameter error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0308.rs b/tests/ui/error-codes/E0308.rs index f8f93d49a8ee1..c27d424547189 100644 --- a/tests/ui/error-codes/E0308.rs +++ b/tests/ui/error-codes/E0308.rs @@ -2,10 +2,7 @@ #![feature(rustc_attrs)] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -fn size_of() { - //~^ ERROR E0308 - loop {} -} +fn size_of(); +//~^ ERROR E0308 fn main() {} diff --git a/tests/ui/error-codes/E0308.stderr b/tests/ui/error-codes/E0308.stderr index 77e5c06e06a73..a1077481a8162 100644 --- a/tests/ui/error-codes/E0308.stderr +++ b/tests/ui/error-codes/E0308.stderr @@ -1,7 +1,7 @@ error[E0308]: intrinsic has wrong type - --> $DIR/E0308.rs:6:16 + --> $DIR/E0308.rs:5:16 | -LL | fn size_of() { +LL | fn size_of(); | ^ expected `usize`, found `()` | = note: expected signature `fn() -> usize` diff --git a/tests/ui/intrinsics/always-gets-overridden.rs b/tests/ui/intrinsics/always-gets-overridden.rs index 2fb64f96d8308..aaac5415c210a 100644 --- a/tests/ui/intrinsics/always-gets-overridden.rs +++ b/tests/ui/intrinsics/always-gets-overridden.rs @@ -1,5 +1,5 @@ -//! Check that `vtable_size` gets overridden by llvm backend even if there is no -//! `rustc_intrinsic_must_be_overridden` attribute on this usage. +//! Check that `vtable_size` gets overridden by llvm backend even if there is a +//! fallback body. #![feature(intrinsics)] //@run-pass diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs index 011076882d24f..8c2d2fafce07e 100644 --- a/tests/ui/repr/16-bit-repr-c-enum.rs +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -24,10 +24,7 @@ enum Foo { #[stable(feature = "intrinsics_for_test", since = "3.3.3")] #[rustc_const_stable(feature = "intrinsics_for_test", since = "3.3.3")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -const fn size_of() -> usize { - loop {} -} +const fn size_of() -> usize; #[lang="sized"] trait Sized {} diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index d62b86693c2ce..315ec983a19a5 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -21,10 +21,7 @@ impl Copy for bool {} #[stable(feature = "test", since = "1.0.0")] #[rustc_const_stable(feature = "test", since = "1.0.0")] #[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -const unsafe fn unreachable() -> ! { - loop {} -} +const unsafe fn unreachable() -> !; #[rustc_builtin_macro] macro_rules! cfg { From 264f2c6699552ea3c45b164e098a0cb45b2c5392 Mon Sep 17 00:00:00 2001 From: Lukas Woodtli Date: Mon, 24 Feb 2025 11:17:49 +0100 Subject: [PATCH 05/16] DWARF mixed versions with LTO on MIPS On MIPS the DWARF version is stored in 2 bytes with the `.2byte` assembler directive. --- tests/assembly/dwarf-mixed-versions-lto.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/assembly/dwarf-mixed-versions-lto.rs b/tests/assembly/dwarf-mixed-versions-lto.rs index 5b8e5ff4f4a4b..f1fc0814c9db6 100644 --- a/tests/assembly/dwarf-mixed-versions-lto.rs +++ b/tests/assembly/dwarf-mixed-versions-lto.rs @@ -1,5 +1,6 @@ // This test ensures that if LTO occurs between crates with different DWARF versions, we // will choose the highest DWARF version for the final binary. This matches Clang's behavior. +// Note: `.2byte` directive is used on MIPS. //@ only-linux //@ aux-build:dwarf-mixed-versions-lto-aux.rs @@ -14,6 +15,6 @@ fn main() { } // CHECK: .section .debug_info -// CHECK-NOT: {{\.(short|hword)}} 2 -// CHECK-NOT: {{\.(short|hword)}} 4 -// CHECK: {{\.(short|hword)}} 5 +// CHECK-NOT: {{\.(short|hword|2byte)}} 2 +// CHECK-NOT: {{\.(short|hword|2byte)}} 4 +// CHECK: {{\.(short|hword|2byte)}} 5 From 9c65672397bab45d2802d994b493353d09cd1535 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 24 Feb 2025 17:10:52 +0300 Subject: [PATCH 06/16] std: Fix another new symlink test on Windows --- library/std/src/fs/tests.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index c7833c7dc7133..38dcd816d267d 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1962,6 +1962,10 @@ fn test_rename_directory_to_non_empty_directory() { #[test] fn test_rename_symlink() { let tmpdir = tmpdir(); + if !got_symlink_permission(&tmpdir) { + return; + }; + let original = tmpdir.join("original"); let dest = tmpdir.join("dest"); let not_exist = Path::new("does not exist"); From 04c00585c36e6e74dbe998d7c3b190955f757469 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 16:12:43 +0000 Subject: [PATCH 07/16] Properly support thin ptrs that are only thin due to their param-env in asm macro --- compiler/rustc_hir_analysis/src/check/intrinsicck.rs | 6 ++---- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 3 ++- tests/ui/asm/conditionally-sized-ptr.rs | 12 ++++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 tests/ui/asm/conditionally-sized-ptr.rs diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index e1727fc48a833..d62fa48bae316 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -33,14 +33,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, def_id: LocalDefId, + typing_env: ty::TypingEnv<'tcx>, get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, ) -> Self { InlineAsmCtxt { tcx, - typing_env: ty::TypingEnv { - typing_mode: ty::TypingMode::non_body_analysis(), - param_env: ty::ParamEnv::empty(), - }, + typing_env, target_features: tcx.asm_target_features(def_id), expr_ty: Box::new(get_operand_ty), } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index edd740d8d8f24..63c1c0608274a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -110,7 +110,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.erase_regions(ty) } }; - InlineAsmCtxt::new(self.tcx, enclosing_id, expr_ty).check_asm(asm); + InlineAsmCtxt::new(self.tcx, enclosing_id, self.typing_env(self.param_env), expr_ty) + .check_asm(asm); } } diff --git a/tests/ui/asm/conditionally-sized-ptr.rs b/tests/ui/asm/conditionally-sized-ptr.rs new file mode 100644 index 0000000000000..8ff18fd1da165 --- /dev/null +++ b/tests/ui/asm/conditionally-sized-ptr.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ needs-asm-support + +use std::arch::asm; + +fn _f(p: *mut T) { + unsafe { + asm!("/* {} */", in(reg) p); + } +} + +fn main() {} From b2dee4226d55f94048be1f5800df73c1430f36b1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 16:20:50 +0000 Subject: [PATCH 08/16] Better error message for unsized pointers --- .../src/check/intrinsicck.rs | 19 ++++++++++++++++++- tests/ui/asm/conditionally-sized-ptr-fail.rs | 19 +++++++++++++++++++ .../asm/conditionally-sized-ptr-fail.stderr | 18 ++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/ui/asm/conditionally-sized-ptr-fail.rs create mode 100644 tests/ui/asm/conditionally-sized-ptr-fail.stderr diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index d62fa48bae316..511947404506c 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -27,6 +27,7 @@ enum NonAsmTypeReason<'tcx> { UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>), Invalid(Ty<'tcx>), InvalidElement(DefId, Ty<'tcx>), + NotSizedPtr(Ty<'tcx>), } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { @@ -81,7 +82,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64), ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128), ty::FnPtr(..) => Ok(asm_ty_isize), - ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Ok(asm_ty_isize), + ty::RawPtr(elem_ty, _) => { + if self.is_thin_ptr_ty(elem_ty) { + Ok(asm_ty_isize) + } else { + Err(NonAsmTypeReason::NotSizedPtr(ty)) + } + } ty::Adt(adt, args) if adt.repr().simd() => { let fields = &adt.non_enum_variant().fields; let field = &fields[FieldIdx::ZERO]; @@ -187,6 +194,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { can be used as arguments for inline assembly", ).emit(); } + NonAsmTypeReason::NotSizedPtr(ty) => { + let msg = format!( + "cannot use value of unsized pointer type `{ty}` for inline assembly" + ); + self.tcx + .dcx() + .struct_span_err(expr.span, msg) + .with_note("only sized pointers can be used in inline assembly") + .emit(); + } NonAsmTypeReason::InvalidElement(did, ty) => { let msg = format!( "cannot use SIMD vector with element type `{ty}` for inline assembly" diff --git a/tests/ui/asm/conditionally-sized-ptr-fail.rs b/tests/ui/asm/conditionally-sized-ptr-fail.rs new file mode 100644 index 0000000000000..b0a93495ffafe --- /dev/null +++ b/tests/ui/asm/conditionally-sized-ptr-fail.rs @@ -0,0 +1,19 @@ +//@ needs-asm-support + +use std::arch::asm; + +fn _f(p: *mut T) { + unsafe { + asm!("/* {} */", in(reg) p); + //~^ ERROR cannot use value of unsized pointer type `*mut T` for inline assembly + } +} + +fn _g(p: *mut [u8]) { + unsafe { + asm!("/* {} */", in(reg) p); + //~^ ERROR cannot use value of unsized pointer type `*mut [u8]` for inline assembly + } +} + +fn main() {} diff --git a/tests/ui/asm/conditionally-sized-ptr-fail.stderr b/tests/ui/asm/conditionally-sized-ptr-fail.stderr new file mode 100644 index 0000000000000..b88f59f569c6c --- /dev/null +++ b/tests/ui/asm/conditionally-sized-ptr-fail.stderr @@ -0,0 +1,18 @@ +error: cannot use value of unsized pointer type `*mut T` for inline assembly + --> $DIR/conditionally-sized-ptr-fail.rs:7:34 + | +LL | asm!("/* {} */", in(reg) p); + | ^ + | + = note: only sized pointers can be used in inline assembly + +error: cannot use value of unsized pointer type `*mut [u8]` for inline assembly + --> $DIR/conditionally-sized-ptr-fail.rs:14:34 + | +LL | asm!("/* {} */", in(reg) p); + | ^ + | + = note: only sized pointers can be used in inline assembly + +error: aborting due to 2 previous errors + From a4a9fb412e1b0420b570a2d6ac2cf81142c5cc11 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 24 Feb 2025 16:38:00 +0000 Subject: [PATCH 09/16] Don't immediately panic if dropck fails without returning errors Type lowering can give non-fatal errors that dropck then uses to suppress its own errors. Assume this is the cases when we can't find the error in borrowck. --- .../src/type_check/liveness/trace.rs | 9 ++++----- .../dropck-after-failed-type-lowering.rs | 14 ++++++++++++++ .../dropck-after-failed-type-lowering.stderr | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 tests/ui/dropck/dropck-after-failed-type-lowering.rs create mode 100644 tests/ui/dropck/dropck-after-failed-type-lowering.stderr diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 12e8be41614bd..dc35d5eb89c95 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -4,7 +4,6 @@ use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::for_liveness; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, HasLocalDecls, Local, Location}; -use rustc_middle::span_bug; use rustc_middle::traits::query::DropckOutlivesResult; use rustc_middle::ty::relate::Relate; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; @@ -12,7 +11,7 @@ use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex}; use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::query::dropck_outlives; @@ -608,7 +607,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { Ok(TypeOpOutput { output, constraints, .. }) => { DropData { dropck_result: output, region_constraint_data: constraints } } - Err(_) => { + Err(ErrorGuaranteed { .. }) => { // We don't run dropck on HIR, and dropck looks inside fields of // types, so there's no guarantee that it succeeds. We also // can't rely on the the `ErrorGuaranteed` from `fully_perform` here @@ -631,10 +630,10 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { } }; + // Could have no errors if a type lowering error, say, caused the query + // to fail. if !errors.is_empty() { typeck.infcx.err_ctxt().report_fulfillment_errors(errors); - } else { - span_bug!(span, "Rerunning drop data query produced no error."); } }); DropData { dropck_result: Default::default(), region_constraint_data: None } diff --git a/tests/ui/dropck/dropck-after-failed-type-lowering.rs b/tests/ui/dropck/dropck-after-failed-type-lowering.rs new file mode 100644 index 0000000000000..2441e26fec96c --- /dev/null +++ b/tests/ui/dropck/dropck-after-failed-type-lowering.rs @@ -0,0 +1,14 @@ +// Regression test for #137329 + +trait B { + type C<'a>; + fn d() -> F { + todo!() + } +} +struct F { + h: Option<::C>, + //~^ ERROR missing generics for associated type `B::C` +} + +fn main() {} diff --git a/tests/ui/dropck/dropck-after-failed-type-lowering.stderr b/tests/ui/dropck/dropck-after-failed-type-lowering.stderr new file mode 100644 index 0000000000000..56ea72de0c5f2 --- /dev/null +++ b/tests/ui/dropck/dropck-after-failed-type-lowering.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for associated type `B::C` + --> $DIR/dropck-after-failed-type-lowering.rs:10:25 + | +LL | h: Option<::C>, + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/dropck-after-failed-type-lowering.rs:4:10 + | +LL | type C<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | h: Option<::C<'a>>, + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. From 0fcb080fb3ecd05c80d6e6d0dea95d724724954f Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:01:17 +0100 Subject: [PATCH 10/16] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/book b/src/doc/book index d4d2c18cbd208..4a01a9182496f 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit d4d2c18cbd20876b2130a546e790446a8444cb32 +Subproject commit 4a01a9182496f807aaa5f72d93a25ce18bcbe105 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 8dbdda7cae4fa..daa4b763cd848 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 8dbdda7cae4fa030f09f8f5b63994d4d1dde74b9 +Subproject commit daa4b763cd848f986813b5cf8069e1649f7147af diff --git a/src/doc/nomicon b/src/doc/nomicon index 336f75835a6c0..8f5c7322b65d0 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 336f75835a6c0514852cc65aba9a698b699b13c8 +Subproject commit 8f5c7322b65d079aa5b242eb10d89a98e12471e1 diff --git a/src/doc/reference b/src/doc/reference index 6195dbd70fc6f..615b4cec60c26 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 6195dbd70fc6f0980c314b4d23875ac570d8253a +Subproject commit 615b4cec60c269cfc105d511c93287620032d5b0 From 0362775fb5badb68fcc2a9a46a16f0154054f3c4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Feb 2025 19:10:55 +0100 Subject: [PATCH 11/16] =?UTF-8?q?rename=20simd=5Fshuffle=5Fgeneric=20?= =?UTF-8?q?=E2=86=92=20simd=5Fshuffle=5Fconst=5Fgeneric?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/intrinsics/simd.rs | 4 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- src/tools/miri/src/intrinsics/simd.rs | 4 +- .../tests/pass/intrinsics/portable-simd.rs | 6 +-- tests/ui/simd/intrinsic/generic-elements.rs | 20 +++---- .../ui/simd/intrinsic/generic-elements.stderr | 54 +++++++++---------- .../monomorphize-shuffle-index.generic.stderr | 10 ++-- tests/ui/simd/monomorphize-shuffle-index.rs | 6 +-- 10 files changed, 55 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index fcccda62355c7..0929218ea2b2d 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -116,8 +116,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } - // simd_shuffle_generic(x: T, y: T) -> U - sym::simd_shuffle_generic => { + // simd_shuffle_const_generic(x: T, y: T) -> U + sym::simd_shuffle_const_generic => { let [x, y] = args else { bug!("wrong number of args for intrinsic {intrinsic}"); }; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index dfbb5bc1731df..56fae135e5527 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1329,7 +1329,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( )); } - if name == sym::simd_shuffle_generic { + if name == sym::simd_shuffle_const_generic { let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch(); let n = idx.len() as u64; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index d468027602cf3..fedc197e7efa4 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -699,7 +699,7 @@ pub fn check_intrinsic_type( | sym::simd_reduce_min | sym::simd_reduce_max => (2, 0, vec![param(0)], param(1)), sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)), - sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)), + sym::simd_shuffle_const_generic => (2, 1, vec![param(0), param(0)], param(1)), other => { tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other }); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 10c79b1be82d9..b7ee4e9be2686 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1916,7 +1916,7 @@ symbols! { simd_shl, simd_shr, simd_shuffle, - simd_shuffle_generic, + simd_shuffle_const_generic, simd_sub, simd_trunc, simd_with_exposed_provenance, diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index 45e316b190a68..3e8b3ef46e437 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -633,7 +633,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_immediate(*val, &dest)?; } } - "shuffle_generic" => { + "shuffle_const_generic" => { let [left, right] = check_arg_count(args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -657,7 +657,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read_immediate(&this.project_index(&right, right_idx)?)? } else { throw_ub_format!( - "`simd_shuffle_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}" + "`simd_shuffle_const_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}" ); }; this.write_immediate(*val, &dest)?; diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index b6c5522b3d207..f043bb7ce9f5d 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -16,7 +16,7 @@ use std::simd::prelude::*; #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn simd_shuffle_generic(_x: T, _y: T) -> U; +pub unsafe fn simd_shuffle_const_generic(_x: T, _y: T) -> U; fn simd_ops_f32() { let a = f32x4::splat(10.0); @@ -619,13 +619,13 @@ fn simd_intrinsics() { simd_select(i8x4::from_array([0, -1, -1, 0]), b, a), i32x4::from_array([10, 2, 10, 10]) ); - assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,); + assert_eq!(simd_shuffle_const_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,); assert_eq!( simd_shuffle::<_, _, i32x4>(a, b, const { u32x4::from_array([3u32, 1, 0, 2]) }), a, ); assert_eq!( - simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b), + simd_shuffle_const_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b), i32x4::from_array([4, 2, 1, 10]), ); assert_eq!( diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs index 4be6645f029c5..54cf35df8c758 100644 --- a/tests/ui/simd/intrinsic/generic-elements.rs +++ b/tests/ui/simd/intrinsic/generic-elements.rs @@ -41,7 +41,7 @@ unsafe fn simd_extract(x: T, idx: u32) -> E; unsafe fn simd_shuffle(x: T, y: T, idx: I) -> U; #[rustc_intrinsic] -unsafe fn simd_shuffle_generic(x: T, y: T) -> U; +unsafe fn simd_shuffle_const_generic(x: T, y: T) -> U; #[repr(simd)] @@ -83,27 +83,27 @@ fn main() { //~^ ERROR expected return type of length 8, found `i32x2` with length 2 const I2: &[u32] = &[0; 2]; - simd_shuffle_generic::(0, 0); + simd_shuffle_const_generic::(0, 0); //~^ ERROR expected SIMD input type, found non-SIMD `i32` const I4: &[u32] = &[0; 4]; - simd_shuffle_generic::(0, 0); + simd_shuffle_const_generic::(0, 0); //~^ ERROR expected SIMD input type, found non-SIMD `i32` const I8: &[u32] = &[0; 8]; - simd_shuffle_generic::(0, 0); + simd_shuffle_const_generic::(0, 0); //~^ ERROR expected SIMD input type, found non-SIMD `i32` - simd_shuffle_generic::<_, f32x2, I2>(x, x); + simd_shuffle_const_generic::<_, f32x2, I2>(x, x); //~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - simd_shuffle_generic::<_, f32x4, I4>(x, x); + simd_shuffle_const_generic::<_, f32x4, I4>(x, x); //~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - simd_shuffle_generic::<_, f32x8, I8>(x, x); + simd_shuffle_const_generic::<_, f32x8, I8>(x, x); //~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - simd_shuffle_generic::<_, i32x8, I2>(x, x); + simd_shuffle_const_generic::<_, i32x8, I2>(x, x); //~^ ERROR expected return type of length 2, found `i32x8` with length 8 - simd_shuffle_generic::<_, i32x8, I4>(x, x); + simd_shuffle_const_generic::<_, i32x8, I4>(x, x); //~^ ERROR expected return type of length 4, found `i32x8` with length 8 - simd_shuffle_generic::<_, i32x2, I8>(x, x); + simd_shuffle_const_generic::<_, i32x2, I8>(x, x); //~^ ERROR expected return type of length 8, found `i32x2` with length 2 } } diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr index 8104c3ba5a2ed..1b3e8d592133c 100644 --- a/tests/ui/simd/intrinsic/generic-elements.stderr +++ b/tests/ui/simd/intrinsic/generic-elements.stderr @@ -70,59 +70,59 @@ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected ret LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` --> $DIR/generic-elements.rs:86:9 | -LL | simd_shuffle_generic::(0, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` --> $DIR/generic-elements.rs:89:9 | -LL | simd_shuffle_generic::(0, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` --> $DIR/generic-elements.rs:92:9 | -LL | simd_shuffle_generic::(0, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` --> $DIR/generic-elements.rs:95:9 | -LL | simd_shuffle_generic::<_, f32x2, I2>(x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::<_, f32x2, I2>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` --> $DIR/generic-elements.rs:97:9 | -LL | simd_shuffle_generic::<_, f32x4, I4>(x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::<_, f32x4, I4>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` --> $DIR/generic-elements.rs:99:9 | -LL | simd_shuffle_generic::<_, f32x8, I8>(x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::<_, f32x8, I8>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8 +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8 --> $DIR/generic-elements.rs:102:9 | -LL | simd_shuffle_generic::<_, i32x8, I2>(x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::<_, i32x8, I2>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8 +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8 --> $DIR/generic-elements.rs:104:9 | -LL | simd_shuffle_generic::<_, i32x8, I4>(x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::<_, i32x8, I4>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2 +error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2 --> $DIR/generic-elements.rs:106:9 | -LL | simd_shuffle_generic::<_, i32x2, I8>(x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_shuffle_const_generic::<_, i32x2, I8>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 21 previous errors diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr index b0a8da59fac1f..8d4bf1e0533ac 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr +++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr @@ -1,10 +1,10 @@ error: overly complex generic constant - --> $DIR/monomorphize-shuffle-index.rs:32:45 + --> $DIR/monomorphize-shuffle-index.rs:32:51 | -LL | return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b); - | ^^----------^^ - | | - | pointer casts are not allowed in generic constants +LL | return simd_shuffle_const_generic::<_, _, { &Self::I.0 }>(a, b); + | ^^----------^^ + | | + | pointer casts are not allowed in generic constants | = help: consider moving this anonymous constant into a `const` function diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index 01926408a2ceb..026193e6af6a7 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -11,7 +11,7 @@ unsafe fn simd_shuffle(a: T, b: T, i: I) -> U; #[rustc_intrinsic] #[cfg(any(generic, generic_with_fn))] -unsafe fn simd_shuffle_generic(a: T, b: T) -> U; +unsafe fn simd_shuffle_const_generic(a: T, b: T) -> U; #[derive(Copy, Clone)] @@ -29,10 +29,10 @@ trait Shuffle { #[cfg(old)] return simd_shuffle(a, b, Self::I); #[cfg(generic)] - return simd_shuffle_generic::<_, _, { &Self::I.0 }>(a, b); + return simd_shuffle_const_generic::<_, _, { &Self::I.0 }>(a, b); //[generic]~^ overly complex generic constant #[cfg(generic_with_fn)] - return simd_shuffle_generic::<_, _, { Self::J }>(a, b); + return simd_shuffle_const_generic::<_, _, { Self::J }>(a, b); } } From f3d31f77e4754d5547606d95db97fd6b2335a8ce Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Feb 2025 02:37:13 +0000 Subject: [PATCH 12/16] Remove dyn_compatible_for_dispatch --- compiler/rustc_feature/src/removed.rs | 9 ++ compiler/rustc_feature/src/unstable.rs | 8 -- .../rustc_hir_analysis/src/coherence/mod.rs | 6 +- .../src/traits/dyn_compatibility.rs | 8 +- .../src/traits/select/candidate_assembly.rs | 8 +- .../rustc_trait_selection/src/traits/wf.rs | 21 ++--- src/tools/tidy/src/issues.txt | 1 - .../coherence-unsafe-trait-object-impl.rs | 18 ---- .../coherence-unsafe-trait-object-impl.stderr | 22 ----- .../issues/cg-in-dyn-issue-128176.rs | 4 +- .../issues/cg-in-dyn-issue-128176.stderr | 19 ++++ ...-consts.dyn_compatible_for_dispatch.stderr | 20 ----- .../ui/dyn-compatibility/associated-consts.rs | 6 +- ...spatch.stderr => associated-consts.stderr} | 27 +++--- tests/ui/dyn-compatibility/generics.rs | 15 ++-- tests/ui/dyn-compatibility/generics.stderr | 85 ++++++++++++++++++ .../mentions-Self.curr.stderr | 16 ++-- tests/ui/dyn-compatibility/mentions-Self.rs | 8 +- .../ui/dyn-compatibility/mentions-Self.stderr | 69 +++++++++++++++ ...-static.dyn_compatible_for_dispatch.stderr | 28 ------ tests/ui/dyn-compatibility/no-static.rs | 8 +- tests/ui/dyn-compatibility/no-static.stderr | 76 ++++++++++++++++ ...sized-2.dyn_compatible_for_dispatch.stderr | 19 ---- tests/ui/dyn-compatibility/sized-2.rs | 6 +- ...ble_for_dispatch.stderr => sized-2.stderr} | 33 ++++--- .../sized.dyn_compatible_for_dispatch.stderr | 19 ---- tests/ui/dyn-compatibility/sized.rs | 6 +- tests/ui/dyn-compatibility/sized.stderr | 34 +++++++ ...st-eval.dyn_compatible_for_dispatch.stderr | 27 ------ .../ui/dyn-compatibility/taint-const-eval.rs | 8 +- .../dyn-compatibility/taint-const-eval.stderr | 74 ++++++++++++++++ ...eature-gate-dyn_compatible_for_dispatch.rs | 41 --------- ...re-gate-dyn_compatible_for_dispatch.stderr | 88 ------------------- .../ui/kindck/kindck-inherited-copy-bound.rs | 12 +-- ...err => kindck-inherited-copy-bound.stderr} | 29 ++++-- .../downcast-unsafe-trait-objects.rs | 23 ----- ...al-self-impl-for-unsafe-obj.current.stderr | 15 ---- ...anual-self-impl-for-unsafe-obj.next.stderr | 15 ---- .../manual-self-impl-for-unsafe-obj.rs | 69 --------------- .../static-dispatch-unsafe-object.rs | 37 -------- .../ice-return-unsized-can-impl-2.rs | 4 +- .../ice-return-unsized-can-impl-2.stderr | 4 +- .../rust-2021/ice-return-unsized-can-impl.rs | 1 - .../ice-return-unsized-can-impl.stderr | 4 +- tests/ui/rust-2021/ice-unsized-fn-params-2.rs | 2 +- tests/ui/rust-2021/ice-unsized-fn-params.rs | 1 - .../ui/rust-2021/ice-unsized-fn-params.stderr | 8 +- ...patible.dyn_compatible_for_dispatch.stderr | 23 ----- .../arbitrary-self-types-dyn-incompatible.rs | 9 +- ...bitrary-self-types-dyn-incompatible.stderr | 42 +++++++++ tests/ui/suggestions/issue-104328.rs | 12 --- tests/ui/suggestions/issue-104328.stderr | 17 ---- .../wf-convert-dyn-incompat-trait-obj-box.rs | 18 ---- ...-convert-dyn-incompat-trait-obj-box.stderr | 54 ------------ .../wf/wf-convert-dyn-incompat-trait-obj.rs | 18 ---- .../wf-convert-dyn-incompat-trait-obj.stderr | 54 ------------ .../ui/wf/wf-dyn-incompat-trait-obj-match.rs | 29 ------ .../wf/wf-dyn-incompat-trait-obj-match.stderr | 60 ------------- 58 files changed, 511 insertions(+), 886 deletions(-) delete mode 100644 tests/ui/coherence/coherence-unsafe-trait-object-impl.rs delete mode 100644 tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr create mode 100644 tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr delete mode 100644 tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr rename tests/ui/dyn-compatibility/{generics.dyn_compatible_for_dispatch.stderr => associated-consts.stderr} (61%) create mode 100644 tests/ui/dyn-compatibility/generics.stderr create mode 100644 tests/ui/dyn-compatibility/mentions-Self.stderr delete mode 100644 tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr create mode 100644 tests/ui/dyn-compatibility/no-static.stderr delete mode 100644 tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr rename tests/ui/dyn-compatibility/{mentions-Self.dyn_compatible_for_dispatch.stderr => sized-2.stderr} (52%) delete mode 100644 tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr create mode 100644 tests/ui/dyn-compatibility/sized.stderr delete mode 100644 tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr create mode 100644 tests/ui/dyn-compatibility/taint-const-eval.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs delete mode 100644 tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr rename tests/ui/kindck/{kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr => kindck-inherited-copy-bound.stderr} (55%) delete mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs delete mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr delete mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr delete mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs delete mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs delete mode 100644 tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr create mode 100644 tests/ui/self/arbitrary-self-types-dyn-incompatible.stderr delete mode 100644 tests/ui/suggestions/issue-104328.rs delete mode 100644 tests/ui/suggestions/issue-104328.stderr delete mode 100644 tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.rs delete mode 100644 tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr delete mode 100644 tests/ui/wf/wf-convert-dyn-incompat-trait-obj.rs delete mode 100644 tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr delete mode 100644 tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs delete mode 100644 tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 60e7788f2c05d..fc58b66ad35ec 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -100,6 +100,15 @@ declare_features! ( Some("renamed to `doc_notable_trait`")), /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). (removed, dropck_parametricity, "1.38.0", Some(28498), None), + /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1]. + /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and + /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. + /// + /// Renamed from `object_safe_for_dispatch`. + /// + /// [^1]: Formerly known as "object safe". + (removed, dyn_compatible_for_dispatch, "1.83.0", Some(43561), + Some("removed, not used heavily and represented additional complexity in dyn compatibility")), /// Uses generic effect parameters for ~const bounds (removed, effects, "1.84.0", Some(102090), Some("removed, redundant with `#![feature(const_trait_impl)]`")), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fe643e9a7d1d8..66c26a541f17f 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -270,14 +270,6 @@ declare_features! ( (unstable, doc_notable_trait, "1.52.0", Some(45040)), /// Allows using the `may_dangle` attribute (RFC 1327). (unstable, dropck_eyepatch, "1.10.0", Some(34761)), - /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1]. - /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and - /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. - /// - /// Renamed from `object_safe_for_dispatch`. - /// - /// [^1]: Formerly known as "object safe". - (unstable, dyn_compatible_for_dispatch, "1.83.0", Some(43561)), /// Allows using the `#[fundamental]` attribute. (unstable, fundamental, "1.0.0", Some(29635)), /// Allows using `#[link_name="llvm.*"]`. diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 1bc60087ab5ee..0245d4c9fe4b6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -199,11 +199,7 @@ fn check_object_overlap<'tcx>( for component_def_id in component_def_ids { if !tcx.is_dyn_compatible(component_def_id) { - // Without the 'dyn_compatible_for_dispatch' feature this is an error - // which will be reported by wfcheck. Ignore it here. - // This is tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`. - // With the feature enabled, the trait is not implemented automatically, - // so this is valid. + // This is a WF error tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`. } else { let mut supertrait_def_ids = elaborate::supertrait_def_ids(tcx, component_def_id); if supertrait_def_ids diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 740f44ebcade2..d4502be6ccfee 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -538,10 +538,10 @@ fn receiver_for_self_ty<'tcx>( /// a pointer. /// /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in -/// a new check that `Trait` is dyn-compatible, creating a cycle (until dyn_compatible_for_dispatch -/// is stabilized, see tracking issue ). -/// Instead, we fudge a little by introducing a new type parameter `U` such that +/// a new check that `Trait` is dyn-compatible, creating a cycle. +/// Instead, we emulate a placeholder by introducing a new type parameter `U` such that /// `Self: Unsize` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. +/// /// Written as a chalk-style query: /// ```ignore (not-rust) /// forall (U: Trait + ?Sized) { @@ -572,8 +572,6 @@ fn receiver_is_dispatchable<'tcx>( // the type `U` in the query // use a bogus type parameter to mimic a forall(U) query using u32::MAX for now. - // FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can - // replace this with `dyn Trait` let unsized_self_ty: Ty<'tcx> = Ty::new_param(tcx, u32::MAX, rustc_span::sym::RustaceansAreAwesome); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 5b362b2356e82..11b6b826efe54 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -859,13 +859,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if let Some(principal) = data.principal() { - if !self.infcx.tcx.features().dyn_compatible_for_dispatch() { - principal.with_self_ty(self.tcx(), self_ty) - } else if self.tcx().is_dyn_compatible(principal.def_id()) { - principal.with_self_ty(self.tcx(), self_ty) - } else { - return; - } + principal.with_self_ty(self.tcx(), self_ty) } else { // Only auto trait bounds exist. return; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 7f3e3ce47816c..18906a6a8ce0f 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -904,19 +904,14 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // FIXME(#27579) RFC also considers adding trait // obligations that don't refer to Self and // checking those - - let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch(); - - if !defer_to_coercion { - if let Some(principal) = data.principal_def_id() { - self.out.push(traits::Obligation::with_depth( - tcx, - self.cause(ObligationCauseCode::WellFormed(None)), - self.recursion_depth, - self.param_env, - ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)), - )); - } + if let Some(principal) = data.principal_def_id() { + self.out.push(traits::Obligation::with_depth( + tcx, + self.cause(ObligationCauseCode::WellFormed(None)), + self.recursion_depth, + self.param_env, + ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)), + )); } } diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 1cb47353469fa..253e13375c73c 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -3827,7 +3827,6 @@ ui/suggestions/issue-103646.rs ui/suggestions/issue-104086-suggest-let.rs ui/suggestions/issue-104287.rs ui/suggestions/issue-104327.rs -ui/suggestions/issue-104328.rs ui/suggestions/issue-104961.rs ui/suggestions/issue-105226.rs ui/suggestions/issue-105494.rs diff --git a/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs b/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs deleted file mode 100644 index 16baf0958a674..0000000000000 --- a/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Check that unsafe trait object do not implement themselves -// automatically - -#![feature(dyn_compatible_for_dispatch)] - -trait Trait: Sized { - fn call(&self); -} - -fn takes_t(s: S) { - s.call(); -} - -fn takes_t_obj(t: &dyn Trait) { - takes_t(t); //~ ERROR E0277 -} - -fn main() {} diff --git a/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr deleted file mode 100644 index 4f898ec127b9f..0000000000000 --- a/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied - --> $DIR/coherence-unsafe-trait-object-impl.rs:15:13 - | -LL | takes_t(t); - | ------- ^ the trait `Trait` is not implemented for `&dyn Trait` - | | - | required by a bound introduced by this call - | -help: this trait has no implementations, consider adding one - --> $DIR/coherence-unsafe-trait-object-impl.rs:6:1 - | -LL | trait Trait: Sized { - | ^^^^^^^^^^^^^^^^^^ -note: required by a bound in `takes_t` - --> $DIR/coherence-unsafe-trait-object-impl.rs:10:15 - | -LL | fn takes_t(s: S) { - | ^^^^^ required by this bound in `takes_t` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs index 5a67d34d6e5a1..dac5429f678ea 100644 --- a/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs +++ b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs @@ -1,10 +1,7 @@ -//@ check-pass - // Regression test for #128176. Previously we would call `type_of` on the `1` anon const // before the anon const had been lowered and had the `type_of` fed with a result. #![feature(generic_const_exprs)] -#![feature(dyn_compatible_for_dispatch)] #![allow(incomplete_features)] trait X { @@ -13,6 +10,7 @@ trait X { const _: () = { fn f2<'a>(arg: Box = &'a ()>>) {} + //~^ ERROR the trait `X` is not dyn compatible }; fn main() {} diff --git a/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr new file mode 100644 index 0000000000000..7d563e3b60542 --- /dev/null +++ b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr @@ -0,0 +1,19 @@ +error[E0038]: the trait `X` is not dyn compatible + --> $DIR/cg-in-dyn-issue-128176.rs:12:24 + | +LL | fn f2<'a>(arg: Box = &'a ()>>) {} + | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/cg-in-dyn-issue-128176.rs:8:10 + | +LL | trait X { + | - this trait is not dyn compatible... +LL | type Y; + | ^ ...because it contains the generic associated type `Y` + = help: consider moving `Y` to another trait + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr deleted file mode 100644 index 704d833f00ba9..0000000000000 --- a/tests/ui/dyn-compatibility/associated-consts.dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/associated-consts.rs:14:5 - | -LL | t - | ^ `Bar` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/associated-consts.rs:9:11 - | -LL | trait Bar { - | --- this trait is not dyn compatible... -LL | const X: usize; - | ^ ...because it contains this associated `const` - = help: consider moving `X` to another trait - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/associated-consts.rs b/tests/ui/dyn-compatibility/associated-consts.rs index fc7b372b782a4..10d151d9a8b59 100644 --- a/tests/ui/dyn-compatibility/associated-consts.rs +++ b/tests/ui/dyn-compatibility/associated-consts.rs @@ -1,16 +1,12 @@ // Check that we correctly prevent users from making trait objects // from traits with associated consts. -// -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar { const X: usize; } fn make_bar(t: &T) -> &dyn Bar { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t //~^ ERROR E0038 } diff --git a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/associated-consts.stderr similarity index 61% rename from tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr rename to tests/ui/dyn-compatibility/associated-consts.stderr index b3565a766fe16..beaf263af07e8 100644 --- a/tests/ui/dyn-compatibility/generics.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/associated-consts.stderr @@ -1,35 +1,34 @@ error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/generics.rs:20:5 + --> $DIR/associated-consts.rs:8:31 | -LL | t - | ^ `Bar` is not dyn compatible +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/generics.rs:10:8 + --> $DIR/associated-consts.rs:5:11 | LL | trait Bar { | --- this trait is not dyn compatible... -LL | fn bar(&self, t: T); - | ^^^ ...because method `bar` has generic type parameters - = help: consider moving `bar` to another trait - = note: required for the cast from `&T` to `&dyn Bar` +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/generics.rs:27:5 + --> $DIR/associated-consts.rs:10:5 | -LL | t as &dyn Bar +LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/generics.rs:10:8 + --> $DIR/associated-consts.rs:5:11 | LL | trait Bar { | --- this trait is not dyn compatible... -LL | fn bar(&self, t: T); - | ^^^ ...because method `bar` has generic type parameters - = help: consider moving `bar` to another trait +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/dyn-compatibility/generics.rs b/tests/ui/dyn-compatibility/generics.rs index b51555aa500c5..dcce17f925bc8 100644 --- a/tests/ui/dyn-compatibility/generics.rs +++ b/tests/ui/dyn-compatibility/generics.rs @@ -1,9 +1,6 @@ // Check that we correctly prevent users from making trait objects // from traits with generic methods, unless `where Self : Sized` is // present. -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar { @@ -16,18 +13,16 @@ trait Quux { } fn make_bar(t: &T) -> &dyn Bar { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t - //[dyn_compatible_for_dispatch]~^ ERROR E0038 - //[curr]~^^ ERROR E0038 + //~^ ERROR E0038 } fn make_bar_explicit(t: &T) -> &dyn Bar { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t as &dyn Bar - //[dyn_compatible_for_dispatch]~^ ERROR E0038 - //[curr]~^^ ERROR E0038 - //[curr]~| ERROR E0038 + //~^ ERROR E0038 + //~| ERROR E0038 } fn make_quux(t: &T) -> &dyn Quux { diff --git a/tests/ui/dyn-compatibility/generics.stderr b/tests/ui/dyn-compatibility/generics.stderr new file mode 100644 index 0000000000000..c019301054193 --- /dev/null +++ b/tests/ui/dyn-compatibility/generics.stderr @@ -0,0 +1,85 @@ +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/generics.rs:15:31 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/generics.rs:7:8 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/generics.rs:21:40 + | +LL | fn make_bar_explicit(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/generics.rs:7:8 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/generics.rs:17:5 + | +LL | t + | ^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/generics.rs:7:8 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/generics.rs:23:10 + | +LL | t as &dyn Bar + | ^^^^^^^^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/generics.rs:7:8 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/generics.rs:23:5 + | +LL | t as &dyn Bar + | ^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/generics.rs:7:8 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr index 2d3fe5ce636cb..6d1ae90152e64 100644 --- a/tests/ui/dyn-compatibility/mentions-Self.curr.stderr +++ b/tests/ui/dyn-compatibility/mentions-Self.curr.stderr @@ -1,12 +1,12 @@ error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/mentions-Self.rs:22:31 + --> $DIR/mentions-Self.rs:18:31 | LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/mentions-Self.rs:11:22 + --> $DIR/mentions-Self.rs:7:22 | LL | trait Bar { | --- this trait is not dyn compatible... @@ -15,14 +15,14 @@ LL | fn bar(&self, x: &Self); = help: consider moving `bar` to another trait error[E0038]: the trait `Baz` is not dyn compatible - --> $DIR/mentions-Self.rs:28:31 + --> $DIR/mentions-Self.rs:24:31 | LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^ `Baz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/mentions-Self.rs:15:22 + --> $DIR/mentions-Self.rs:11:22 | LL | trait Baz { | --- this trait is not dyn compatible... @@ -31,14 +31,14 @@ LL | fn baz(&self) -> Self; = help: consider moving `baz` to another trait error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/mentions-Self.rs:24:5 + --> $DIR/mentions-Self.rs:20:5 | LL | t | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/mentions-Self.rs:11:22 + --> $DIR/mentions-Self.rs:7:22 | LL | trait Bar { | --- this trait is not dyn compatible... @@ -48,14 +48,14 @@ LL | fn bar(&self, x: &Self); = note: required for the cast from `&T` to `&dyn Bar` error[E0038]: the trait `Baz` is not dyn compatible - --> $DIR/mentions-Self.rs:30:5 + --> $DIR/mentions-Self.rs:26:5 | LL | t | ^ `Baz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/mentions-Self.rs:15:22 + --> $DIR/mentions-Self.rs:11:22 | LL | trait Baz { | --- this trait is not dyn compatible... diff --git a/tests/ui/dyn-compatibility/mentions-Self.rs b/tests/ui/dyn-compatibility/mentions-Self.rs index 84c229e252d30..ce210f4776f7b 100644 --- a/tests/ui/dyn-compatibility/mentions-Self.rs +++ b/tests/ui/dyn-compatibility/mentions-Self.rs @@ -1,10 +1,6 @@ // Check that we correctly prevent users from making trait objects // form traits that make use of `Self` in an argument or return // position, unless `where Self : Sized` is present.. -// -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar { @@ -20,13 +16,13 @@ trait Quux { } fn make_bar(t: &T) -> &dyn Bar { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t //~^ ERROR E0038 } fn make_baz(t: &T) -> &dyn Baz { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t //~^ ERROR E0038 } diff --git a/tests/ui/dyn-compatibility/mentions-Self.stderr b/tests/ui/dyn-compatibility/mentions-Self.stderr new file mode 100644 index 0000000000000..6d1ae90152e64 --- /dev/null +++ b/tests/ui/dyn-compatibility/mentions-Self.stderr @@ -0,0 +1,69 @@ +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/mentions-Self.rs:18:31 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mentions-Self.rs:7:22 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Baz` is not dyn compatible + --> $DIR/mentions-Self.rs:24:31 + | +LL | fn make_baz(t: &T) -> &dyn Baz { + | ^^^^^^^ `Baz` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mentions-Self.rs:11:22 + | +LL | trait Baz { + | --- this trait is not dyn compatible... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/mentions-Self.rs:20:5 + | +LL | t + | ^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mentions-Self.rs:7:22 + | +LL | trait Bar { + | --- this trait is not dyn compatible... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Baz` is not dyn compatible + --> $DIR/mentions-Self.rs:26:5 + | +LL | t + | ^ `Baz` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mentions-Self.rs:11:22 + | +LL | trait Baz { + | --- this trait is not dyn compatible... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + = note: required for the cast from `&T` to `&dyn Baz` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr deleted file mode 100644 index d5ad451033461..0000000000000 --- a/tests/ui/dyn-compatibility/no-static.dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/no-static.rs:22:27 - | -LL | let b: Box = Box::new(Bar); - | ^^^^^^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/no-static.rs:9:8 - | -LL | trait Foo { - | --- this trait is not dyn compatible... -LL | fn foo() {} - | ^^^ ...because associated function `foo` has no `self` parameter - = help: only type `Bar` implements `Foo`; consider using it directly instead. - = note: required for the cast from `Box` to `Box` -help: consider turning `foo` into a method by giving it a `&self` argument - | -LL | fn foo(&self) {} - | +++++ -help: alternatively, consider constraining `foo` so it does not apply to trait objects - | -LL | fn foo() where Self: Sized {} - | +++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/no-static.rs b/tests/ui/dyn-compatibility/no-static.rs index 54af16fe18eb6..9bd8716197285 100644 --- a/tests/ui/dyn-compatibility/no-static.rs +++ b/tests/ui/dyn-compatibility/no-static.rs @@ -1,16 +1,12 @@ // Check that we correctly prevent users from making trait objects // from traits with static methods. -// -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Foo { fn foo() {} } fn diverges() -> Box { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 loop { } } @@ -21,5 +17,5 @@ impl Foo for Bar {} fn main() { let b: Box = Box::new(Bar); //~^ ERROR E0038 - //[curr]~| ERROR E0038 + //~| ERROR E0038 } diff --git a/tests/ui/dyn-compatibility/no-static.stderr b/tests/ui/dyn-compatibility/no-static.stderr new file mode 100644 index 0000000000000..814ab0d53c3fc --- /dev/null +++ b/tests/ui/dyn-compatibility/no-static.stderr @@ -0,0 +1,76 @@ +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/no-static.rs:8:22 + | +LL | fn diverges() -> Box { + | ^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/no-static.rs:5:8 + | +LL | trait Foo { + | --- this trait is not dyn compatible... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements `Foo`; consider using it directly instead. +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/no-static.rs:18:12 + | +LL | let b: Box = Box::new(Bar); + | ^^^^^^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/no-static.rs:5:8 + | +LL | trait Foo { + | --- this trait is not dyn compatible... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements `Foo`; consider using it directly instead. +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/no-static.rs:18:27 + | +LL | let b: Box = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/no-static.rs:5:8 + | +LL | trait Foo { + | --- this trait is not dyn compatible... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements `Foo`; consider using it directly instead. + = note: required for the cast from `Box` to `Box` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr deleted file mode 100644 index 1fbc10c0c3f8c..0000000000000 --- a/tests/ui/dyn-compatibility/sized-2.dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/sized-2.rs:16:5 - | -LL | t - | ^ `Bar` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/sized-2.rs:9:18 - | -LL | trait Bar - | --- this trait is not dyn compatible... -LL | where Self : Sized - | ^^^^^ ...because it requires `Self: Sized` - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized-2.rs b/tests/ui/dyn-compatibility/sized-2.rs index f5edd287f24d8..f61d49ee8dff3 100644 --- a/tests/ui/dyn-compatibility/sized-2.rs +++ b/tests/ui/dyn-compatibility/sized-2.rs @@ -1,9 +1,5 @@ // Check that we correctly prevent users from making trait objects // from traits where `Self : Sized`. -// -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar where Self : Sized @@ -12,7 +8,7 @@ trait Bar } fn make_bar(t: &T) -> &dyn Bar { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t //~^ ERROR E0038 } diff --git a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized-2.stderr similarity index 52% rename from tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr rename to tests/ui/dyn-compatibility/sized-2.stderr index 91c26a860259b..1834d906bb89d 100644 --- a/tests/ui/dyn-compatibility/mentions-Self.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/dyn-compatibility/sized-2.stderr @@ -1,36 +1,33 @@ error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/mentions-Self.rs:24:5 + --> $DIR/sized-2.rs:10:31 | -LL | t - | ^ `Bar` is not dyn compatible +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/mentions-Self.rs:11:22 + --> $DIR/sized-2.rs:5:18 | -LL | trait Bar { +LL | trait Bar | --- this trait is not dyn compatible... -LL | fn bar(&self, x: &Self); - | ^^^^^ ...because method `bar` references the `Self` type in this parameter - = help: consider moving `bar` to another trait - = note: required for the cast from `&T` to `&dyn Bar` +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` -error[E0038]: the trait `Baz` is not dyn compatible - --> $DIR/mentions-Self.rs:30:5 +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/sized-2.rs:12:5 | LL | t - | ^ `Baz` is not dyn compatible + | ^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/mentions-Self.rs:15:22 + --> $DIR/sized-2.rs:5:18 | -LL | trait Baz { +LL | trait Bar | --- this trait is not dyn compatible... -LL | fn baz(&self) -> Self; - | ^^^^ ...because method `baz` references the `Self` type in its return type - = help: consider moving `baz` to another trait - = note: required for the cast from `&T` to `&dyn Baz` +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr deleted file mode 100644 index 350c8992c6f96..0000000000000 --- a/tests/ui/dyn-compatibility/sized.dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/sized.rs:14:5 - | -LL | t - | ^ `Bar` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/sized.rs:8:12 - | -LL | trait Bar: Sized { - | --- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/sized.rs b/tests/ui/dyn-compatibility/sized.rs index 4c4fe3f8f2593..eb5279c17e62d 100644 --- a/tests/ui/dyn-compatibility/sized.rs +++ b/tests/ui/dyn-compatibility/sized.rs @@ -1,16 +1,12 @@ // Check that we correctly prevent users from making trait objects // from traits where `Self : Sized`. -// -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar: Sized { fn bar(&self, t: T); } fn make_bar(t: &T) -> &dyn Bar { - //[curr]~^ ERROR E0038 + //~^ ERROR E0038 t //~^ ERROR E0038 } diff --git a/tests/ui/dyn-compatibility/sized.stderr b/tests/ui/dyn-compatibility/sized.stderr new file mode 100644 index 0000000000000..c66e299cf6f5c --- /dev/null +++ b/tests/ui/dyn-compatibility/sized.stderr @@ -0,0 +1,34 @@ +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/sized.rs:8:32 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/sized.rs:4:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Bar` is not dyn compatible + --> $DIR/sized.rs:10:5 + | +LL | t + | ^ `Bar` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/sized.rs:4:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr b/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr deleted file mode 100644 index 0bc7d0b14d3dd..0000000000000 --- a/tests/ui/dyn-compatibility/taint-const-eval.dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0038]: the trait `Qux` is not dyn compatible - --> $DIR/taint-const-eval.rs:11:33 - | -LL | static FOO: &(dyn Qux + Sync) = "desc"; - | ^^^^^^ `Qux` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/taint-const-eval.rs:8:8 - | -LL | trait Qux { - | --- this trait is not dyn compatible... -LL | fn bar(); - | ^^^ ...because associated function `bar` has no `self` parameter - = note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)` -help: consider turning `bar` into a method by giving it a `&self` argument - | -LL | fn bar(&self); - | +++++ -help: alternatively, consider constraining `bar` so it does not apply to trait objects - | -LL | fn bar() where Self: Sized; - | +++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/taint-const-eval.rs b/tests/ui/dyn-compatibility/taint-const-eval.rs index 2feae58080bc8..7ea763e184698 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.rs +++ b/tests/ui/dyn-compatibility/taint-const-eval.rs @@ -1,16 +1,12 @@ // Test that we do not attempt to create dyn-incompatible trait objects in const eval. -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] - trait Qux { fn bar(); } static FOO: &(dyn Qux + Sync) = "desc"; //~^ the trait `Qux` is not dyn compatible -//[curr]~| the trait `Qux` is not dyn compatible -//[curr]~| the trait `Qux` is not dyn compatible +//~| the trait `Qux` is not dyn compatible +//~| the trait `Qux` is not dyn compatible fn main() {} diff --git a/tests/ui/dyn-compatibility/taint-const-eval.stderr b/tests/ui/dyn-compatibility/taint-const-eval.stderr new file mode 100644 index 0000000000000..942c20db6ce0f --- /dev/null +++ b/tests/ui/dyn-compatibility/taint-const-eval.stderr @@ -0,0 +1,74 @@ +error[E0038]: the trait `Qux` is not dyn compatible + --> $DIR/taint-const-eval.rs:7:15 + | +LL | static FOO: &(dyn Qux + Sync) = "desc"; + | ^^^^^^^^^^^^^^ `Qux` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/taint-const-eval.rs:4:8 + | +LL | trait Qux { + | --- this trait is not dyn compatible... +LL | fn bar(); + | ^^^ ...because associated function `bar` has no `self` parameter +help: consider turning `bar` into a method by giving it a `&self` argument + | +LL | fn bar(&self); + | +++++ +help: alternatively, consider constraining `bar` so it does not apply to trait objects + | +LL | fn bar() where Self: Sized; + | +++++++++++++++++ + +error[E0038]: the trait `Qux` is not dyn compatible + --> $DIR/taint-const-eval.rs:7:33 + | +LL | static FOO: &(dyn Qux + Sync) = "desc"; + | ^^^^^^ `Qux` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/taint-const-eval.rs:4:8 + | +LL | trait Qux { + | --- this trait is not dyn compatible... +LL | fn bar(); + | ^^^ ...because associated function `bar` has no `self` parameter + = note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)` +help: consider turning `bar` into a method by giving it a `&self` argument + | +LL | fn bar(&self); + | +++++ +help: alternatively, consider constraining `bar` so it does not apply to trait objects + | +LL | fn bar() where Self: Sized; + | +++++++++++++++++ + +error[E0038]: the trait `Qux` is not dyn compatible + --> $DIR/taint-const-eval.rs:7:15 + | +LL | static FOO: &(dyn Qux + Sync) = "desc"; + | ^^^^^^^^^^^^^^ `Qux` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/taint-const-eval.rs:4:8 + | +LL | trait Qux { + | --- this trait is not dyn compatible... +LL | fn bar(); + | ^^^ ...because associated function `bar` has no `self` parameter + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider turning `bar` into a method by giving it a `&self` argument + | +LL | fn bar(&self); + | +++++ +help: alternatively, consider constraining `bar` so it does not apply to trait objects + | +LL | fn bar() where Self: Sized; + | +++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs deleted file mode 100644 index e38ab66dbe549..0000000000000 --- a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Test that the use of the dyn-incompatible trait objects -// are gated by the `dyn_compatible_for_dispatch` feature gate. - -trait DynIncompatible1: Sized {} - -trait DynIncompatible2 { - fn static_fn() {} -} - -trait DynIncompatible3 { - fn foo(&self); -} - -trait DynIncompatible4 { - fn foo(&self, s: &Self); -} - -fn takes_dyn_incompatible_ref(obj: &dyn DynIncompatible1) { - //~^ ERROR E0038 -} - -fn return_dyn_incompatible_ref() -> &'static dyn DynIncompatible2 { - //~^ ERROR E0038 - loop {} -} - -fn takes_dyn_incompatible_box(obj: Box) { - //~^ ERROR E0038 -} - -fn return_dyn_incompatible_rc() -> std::rc::Rc { - //~^ ERROR E0038 - loop {} -} - -trait Trait {} - -impl Trait for dyn DynIncompatible1 {} -//~^ ERROR E0038 - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr deleted file mode 100644 index 2c3edd6e6a5fc..0000000000000 --- a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,88 +0,0 @@ -error[E0038]: the trait `DynIncompatible1` is not dyn compatible - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:18:40 - | -LL | fn takes_dyn_incompatible_ref(obj: &dyn DynIncompatible1) { - | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25 - | -LL | trait DynIncompatible1: Sized {} - | ---------------- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - -error[E0038]: the trait `DynIncompatible2` is not dyn compatible - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:22:46 - | -LL | fn return_dyn_incompatible_ref() -> &'static dyn DynIncompatible2 { - | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible2` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:7:8 - | -LL | trait DynIncompatible2 { - | ---------------- this trait is not dyn compatible... -LL | fn static_fn() {} - | ^^^^^^^^^ ...because associated function `static_fn` has no `self` parameter -help: consider turning `static_fn` into a method by giving it a `&self` argument - | -LL | fn static_fn(&self) {} - | +++++ -help: alternatively, consider constraining `static_fn` so it does not apply to trait objects - | -LL | fn static_fn() where Self: Sized {} - | +++++++++++++++++ - -error[E0038]: the trait `DynIncompatible3` is not dyn compatible - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:27:40 - | -LL | fn takes_dyn_incompatible_box(obj: Box) { - | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible3` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:11:8 - | -LL | trait DynIncompatible3 { - | ---------------- this trait is not dyn compatible... -LL | fn foo(&self); - | ^^^ ...because method `foo` has generic type parameters - = help: consider moving `foo` to another trait - -error[E0038]: the trait `DynIncompatible4` is not dyn compatible - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:31:48 - | -LL | fn return_dyn_incompatible_rc() -> std::rc::Rc { - | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible4` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:15:22 - | -LL | trait DynIncompatible4 { - | ---------------- this trait is not dyn compatible... -LL | fn foo(&self, s: &Self); - | ^^^^^ ...because method `foo` references the `Self` type in this parameter - = help: consider moving `foo` to another trait - -error[E0038]: the trait `DynIncompatible1` is not dyn compatible - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:38:16 - | -LL | impl Trait for dyn DynIncompatible1 {} - | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25 - | -LL | trait DynIncompatible1: Sized {} - | ---------------- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.rs b/tests/ui/kindck/kindck-inherited-copy-bound.rs index dda95229ddf00..20d54a3fb106d 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.rs +++ b/tests/ui/kindck/kindck-inherited-copy-bound.rs @@ -1,8 +1,4 @@ // Test that Copy bounds inherited by trait are checked. -// -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] use std::any::Any; @@ -18,17 +14,15 @@ fn take_param(foo: &T) { } fn a() { let x: Box<_> = Box::new(3); - take_param(&x); //[curr]~ ERROR E0277 - //[dyn_compatible_for_dispatch]~^ ERROR E0277 + take_param(&x); //~ ERROR E0277 } fn b() { let x: Box<_> = Box::new(3); let y = &x; let z = &x as &dyn Foo; - //[curr]~^ ERROR E0038 - //[curr]~| ERROR E0038 - //[dyn_compatible_for_dispatch]~^^^ ERROR E0038 + //~^ ERROR E0038 + //~| ERROR E0038 } fn main() { } diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.stderr similarity index 55% rename from tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr rename to tests/ui/kindck/kindck-inherited-copy-bound.stderr index 296f011193e9a..edfa7ae7769db 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:21:16 + --> $DIR/kindck-inherited-copy-bound.rs:17:16 | LL | take_param(&x); | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>` @@ -7,35 +7,50 @@ LL | take_param(&x); | required by a bound introduced by this call | note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:14:14 + --> $DIR/kindck-inherited-copy-bound.rs:10:14 | LL | impl Foo for T { | ---- ^^^ ^ | | | unsatisfied trait bound introduced here note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:17:17 + --> $DIR/kindck-inherited-copy-bound.rs:13:17 | LL | fn take_param(foo: &T) { } | ^^^ required by this bound in `take_param` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/kindck-inherited-copy-bound.rs:28:13 + --> $DIR/kindck-inherited-copy-bound.rs:23:19 + | +LL | let z = &x as &dyn Foo; + | ^^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/kindck-inherited-copy-bound.rs:6:13 + | +LL | trait Foo : Copy { + | --- ^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/kindck-inherited-copy-bound.rs:23:13 | LL | let z = &x as &dyn Foo; | ^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/kindck-inherited-copy-bound.rs:10:13 + --> $DIR/kindck-inherited-copy-bound.rs:6:13 | LL | trait Foo : Copy { | --- ^^^^ ...because it requires `Self: Sized` | | | this trait is not dyn compatible... - = note: required for the cast from `&Box` to `&dyn Foo` + = note: required for the cast from `&Box<{integer}>` to `&dyn Foo` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0038, E0277. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs deleted file mode 100644 index b1b2dcf3eb9fd..0000000000000 --- a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Check that we if we get ahold of a dyn-incompatible trait -// object with auto traits and lifetimes, we can downcast it -// -//@ check-pass - -#![feature(dyn_compatible_for_dispatch)] - -trait Trait: Sized {} - -fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait { - t -} - -fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't)) - -> &'b (dyn Trait + 't) -where - 'a: 'b, - 't: 'a + 'b, -{ - t -} - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr deleted file mode 100644 index 1489791b20d69..0000000000000 --- a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: methods `good_virt` and `good_indirect` are never used - --> $DIR/manual-self-impl-for-unsafe-obj.rs:23:8 - | -LL | trait Good { - | ---- methods in this trait -LL | fn good_virt(&self) -> char { - | ^^^^^^^^^ -... -LL | fn good_indirect(&self) -> char { - | ^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr deleted file mode 100644 index 1489791b20d69..0000000000000 --- a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: methods `good_virt` and `good_indirect` are never used - --> $DIR/manual-self-impl-for-unsafe-obj.rs:23:8 - | -LL | trait Good { - | ---- methods in this trait -LL | fn good_virt(&self) -> char { - | ^^^^^^^^^ -... -LL | fn good_indirect(&self) -> char { - | ^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs deleted file mode 100644 index 425dc130d4587..0000000000000 --- a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Check that we can manually implement a dyn-incompatible trait for its trait object. - -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@ run-pass - -#![feature(dyn_compatible_for_dispatch)] - -trait Bad { - fn stat() -> char { - 'A' - } - fn virt(&self) -> char { - 'B' - } - fn indirect(&self) -> char { - Self::stat() - } -} - -trait Good { - fn good_virt(&self) -> char { //~ WARN methods `good_virt` and `good_indirect` are never used - panic!() - } - fn good_indirect(&self) -> char { - panic!() - } -} - -impl<'a> Bad for dyn Bad + 'a { - fn stat() -> char { - 'C' - } - fn virt(&self) -> char { - 'D' - } -} - -struct Struct {} - -impl Bad for Struct {} - -impl Good for Struct {} - -fn main() { - let s = Struct {}; - - let mut res = String::new(); - - // Directly call static. - res.push(Struct::stat()); // "A" - res.push(::stat()); // "AC" - - let good: &dyn Good = &s; - - // These look similar enough... - let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) }; - - // Call virtual. - res.push(s.virt()); // "ACB" - res.push(bad.virt()); // "ACBD" - - // Indirectly call static. - res.push(s.indirect()); // "ACBDA" - res.push(bad.indirect()); // "ACBDAC" - - assert_eq!(&res, "ACBDAC"); -} diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs deleted file mode 100644 index c38928a9f44e9..0000000000000 --- a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Check that we can statically dispatch methods for object -// unsafe trait objects, directly and indirectly -// -//@ check-pass - -#![feature(dyn_compatible_for_dispatch)] - -trait Statics { - fn plain() {} - fn generic() {} -} - -trait Trait: Sized {} - -impl<'a> Statics for dyn Trait + 'a {} - -fn static_poly() { - T::plain(); - T::generic::(); -} - -fn inferred_poly(t: &T) { - static_poly::(); - T::plain(); - T::generic::(); -} - -fn call(t: &dyn Trait) { - static_poly::(); - inferred_poly(t); -} - -fn main() { - static_poly::(); - ::plain(); - ::generic::() -} diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs index e57e9ce4844a4..567d37e1b820d 100644 --- a/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs +++ b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.rs @@ -1,15 +1,17 @@ // Doesn't trigger ICE when returning unsized trait that can be impl // issue https://github.com/rust-lang/rust/issues/125512 //@ edition:2021 -#![feature(dyn_compatible_for_dispatch)] + trait B { fn f(a: A) -> A; //~^ ERROR: expected a type, found a trait //~| ERROR: expected a type, found a trait } + trait A { fn concrete(b: B) -> B; //~^ ERROR: expected a type, found a trait //~| ERROR: expected a type, found a trait } + fn main() {} diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr index ac19f91881dfe..f2942820e2887 100644 --- a/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr +++ b/tests/ui/rust-2021/ice-return-unsized-can-impl-2.stderr @@ -1,5 +1,5 @@ error[E0782]: expected a type, found a trait - --> $DIR/ice-return-unsized-can-impl-2.rs:11:20 + --> $DIR/ice-return-unsized-can-impl-2.rs:12:20 | LL | fn concrete(b: B) -> B; | ^ @@ -16,7 +16,7 @@ LL | fn concrete(b: impl B) -> B; | ++++ error[E0782]: expected a type, found a trait - --> $DIR/ice-return-unsized-can-impl-2.rs:11:26 + --> $DIR/ice-return-unsized-can-impl-2.rs:12:26 | LL | fn concrete(b: B) -> B; | ^ diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl.rs b/tests/ui/rust-2021/ice-return-unsized-can-impl.rs index 055b11b4424a1..8b83b7b537a2f 100644 --- a/tests/ui/rust-2021/ice-return-unsized-can-impl.rs +++ b/tests/ui/rust-2021/ice-return-unsized-can-impl.rs @@ -1,7 +1,6 @@ // Doesn't trigger ICE when returning unsized trait that can be impl // issue https://github.com/rust-lang/rust/issues/120482 //@ edition:2021 -#![feature(dyn_compatible_for_dispatch)] trait B { fn bar(&self, x: &Self); diff --git a/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr b/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr index 463c6892ca26c..cfee506e29b74 100644 --- a/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr +++ b/tests/ui/rust-2021/ice-return-unsized-can-impl.stderr @@ -1,5 +1,5 @@ error[E0782]: expected a type, found a trait - --> $DIR/ice-return-unsized-can-impl.rs:11:15 + --> $DIR/ice-return-unsized-can-impl.rs:10:15 | LL | fn g(new: B) -> B; | ^ @@ -16,7 +16,7 @@ LL | fn g(new: impl B) -> B; | ++++ error[E0782]: expected a type, found a trait - --> $DIR/ice-return-unsized-can-impl.rs:11:21 + --> $DIR/ice-return-unsized-can-impl.rs:10:21 | LL | fn g(new: B) -> B; | ^ diff --git a/tests/ui/rust-2021/ice-unsized-fn-params-2.rs b/tests/ui/rust-2021/ice-unsized-fn-params-2.rs index 2b4f7bd088fbe..8af56ffe80de7 100644 --- a/tests/ui/rust-2021/ice-unsized-fn-params-2.rs +++ b/tests/ui/rust-2021/ice-unsized-fn-params-2.rs @@ -1,7 +1,7 @@ //@ edition:2021 // Test that it doesn't trigger an ICE when using an unsized fn params. // https://github.com/rust-lang/rust/issues/120241 -#![feature(dyn_compatible_for_dispatch)] + #![feature(unsized_fn_params)] fn guard(_s: Copy) -> bool { diff --git a/tests/ui/rust-2021/ice-unsized-fn-params.rs b/tests/ui/rust-2021/ice-unsized-fn-params.rs index 6d8c1c3f152f1..6ed67698e96eb 100644 --- a/tests/ui/rust-2021/ice-unsized-fn-params.rs +++ b/tests/ui/rust-2021/ice-unsized-fn-params.rs @@ -1,7 +1,6 @@ //@ edition:2021 // Test that it doesn't trigger an ICE when using an unsized fn params. // https://github.com/rust-lang/rust/issues/120241 -#![feature(dyn_compatible_for_dispatch)] trait B { fn f(a: A) -> A; diff --git a/tests/ui/rust-2021/ice-unsized-fn-params.stderr b/tests/ui/rust-2021/ice-unsized-fn-params.stderr index c31500ba80046..4d900711ed6ec 100644 --- a/tests/ui/rust-2021/ice-unsized-fn-params.stderr +++ b/tests/ui/rust-2021/ice-unsized-fn-params.stderr @@ -1,5 +1,5 @@ error[E0782]: expected a type, found a trait - --> $DIR/ice-unsized-fn-params.rs:13:13 + --> $DIR/ice-unsized-fn-params.rs:12:13 | LL | fn g(b: B) -> B; | ^ @@ -16,7 +16,7 @@ LL | fn g(b: impl B) -> B; | ++++ error[E0782]: expected a type, found a trait - --> $DIR/ice-unsized-fn-params.rs:13:19 + --> $DIR/ice-unsized-fn-params.rs:12:19 | LL | fn g(b: B) -> B; | ^ @@ -27,7 +27,7 @@ LL | fn g(b: B) -> impl B; | ++++ error[E0782]: expected a type, found a trait - --> $DIR/ice-unsized-fn-params.rs:7:13 + --> $DIR/ice-unsized-fn-params.rs:6:13 | LL | fn f(a: A) -> A; | ^ @@ -44,7 +44,7 @@ LL | fn f(a: impl A) -> A; | ++++ error[E0782]: expected a type, found a trait - --> $DIR/ice-unsized-fn-params.rs:7:19 + --> $DIR/ice-unsized-fn-params.rs:6:19 | LL | fn f(a: A) -> A; | ^ diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr deleted file mode 100644 index d324f4641cf28..0000000000000 --- a/tests/ui/self/arbitrary-self-types-dyn-incompatible.dyn_compatible_for_dispatch.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/arbitrary-self-types-dyn-incompatible.rs:33:13 - | -LL | fn foo(self: &Rc) -> usize; - | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` -... -LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/arbitrary-self-types-dyn-incompatible.rs:8:18 - | -LL | trait Foo { - | --- this trait is not dyn compatible... -LL | fn foo(self: &Rc) -> usize; - | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - = help: only type `usize` implements `Foo`; consider using it directly instead. - = note: required for the cast from `Rc` to `Rc` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.rs b/tests/ui/self/arbitrary-self-types-dyn-incompatible.rs index 940b2f1e8e2fa..0477d9d79c779 100644 --- a/tests/ui/self/arbitrary-self-types-dyn-incompatible.rs +++ b/tests/ui/self/arbitrary-self-types-dyn-incompatible.rs @@ -1,7 +1,3 @@ -//@ revisions: curr dyn_compatible_for_dispatch - -#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] - use std::rc::Rc; trait Foo { @@ -31,9 +27,8 @@ impl Bar for usize { fn make_foo() { let x = Rc::new(5usize) as Rc; - //[curr]~^ ERROR E0038 - //[curr]~| ERROR E0038 - //[dyn_compatible_for_dispatch]~^^^ ERROR E0038 + //~^ ERROR E0038 + //~| ERROR E0038 } fn make_bar() { diff --git a/tests/ui/self/arbitrary-self-types-dyn-incompatible.stderr b/tests/ui/self/arbitrary-self-types-dyn-incompatible.stderr new file mode 100644 index 0000000000000..9fb4c80329d58 --- /dev/null +++ b/tests/ui/self/arbitrary-self-types-dyn-incompatible.stderr @@ -0,0 +1,42 @@ +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/arbitrary-self-types-dyn-incompatible.rs:29:32 + | +LL | fn foo(self: &Rc) -> usize; + | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` +... +LL | let x = Rc::new(5usize) as Rc; + | ^^^^^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/arbitrary-self-types-dyn-incompatible.rs:4:18 + | +LL | trait Foo { + | --- this trait is not dyn compatible... +LL | fn foo(self: &Rc) -> usize; + | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on + = help: only type `usize` implements `Foo`; consider using it directly instead. + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/arbitrary-self-types-dyn-incompatible.rs:29:13 + | +LL | fn foo(self: &Rc) -> usize; + | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` +... +LL | let x = Rc::new(5usize) as Rc; + | ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/arbitrary-self-types-dyn-incompatible.rs:4:18 + | +LL | trait Foo { + | --- this trait is not dyn compatible... +LL | fn foo(self: &Rc) -> usize; + | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on + = help: only type `usize` implements `Foo`; consider using it directly instead. + = note: required for the cast from `Rc` to `Rc` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/suggestions/issue-104328.rs b/tests/ui/suggestions/issue-104328.rs deleted file mode 100644 index 2b0fbdb8d35bb..0000000000000 --- a/tests/ui/suggestions/issue-104328.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(dyn_compatible_for_dispatch)] - -trait Foo { - fn f() {} -} - -impl Foo for dyn Sized {} - -fn main() { - Foo::f(); - //~^ ERROR cannot call associated function on trait without specifying the corresponding `impl` type -} diff --git a/tests/ui/suggestions/issue-104328.stderr b/tests/ui/suggestions/issue-104328.stderr deleted file mode 100644 index 3c5e6f16289e0..0000000000000 --- a/tests/ui/suggestions/issue-104328.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type - --> $DIR/issue-104328.rs:10:5 - | -LL | fn f() {} - | --------- `Foo::f` defined here -... -LL | Foo::f(); - | ^^^^^^^^ cannot call associated function of trait - | -help: use the fully-qualified path to the only available implementation - | -LL | <(dyn Sized + 'static) as Foo>::f(); - | +++++++++++++++++++++++++ + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0790`. diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.rs b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.rs deleted file mode 100644 index 26292a1d218c9..0000000000000 --- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Check that we do not allow casts or coercions -// to dyn-incompatible trait objects inside a Box - -#![feature(dyn_compatible_for_dispatch)] - -trait Trait: Sized {} - -struct S; - -impl Trait for S {} - -fn takes_box(t: Box) {} - -fn main() { - Box::new(S) as Box; //~ ERROR E0038 - let t_box: Box = Box::new(S); //~ ERROR E0038 - takes_box(Box::new(S)); //~ ERROR E0038 -} diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr deleted file mode 100644 index f3e4f2a63e98a..0000000000000 --- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj-box.stderr +++ /dev/null @@ -1,54 +0,0 @@ -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:16:33 - | -LL | let t_box: Box = Box::new(S); - | ^^^^^^^^^^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: only type `S` implements `Trait`; consider using it directly instead. - = note: required for the cast from `Box` to `Box` - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:17:15 - | -LL | takes_box(Box::new(S)); - | ^^^^^^^^^^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: only type `S` implements `Trait`; consider using it directly instead. - = note: required for the cast from `Box` to `Box<(dyn Trait + 'static)>` - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:15:5 - | -LL | Box::new(S) as Box; - | ^^^^^^^^^^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-convert-dyn-incompat-trait-obj-box.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: only type `S` implements `Trait`; consider using it directly instead. - = note: required for the cast from `Box` to `Box` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.rs b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.rs deleted file mode 100644 index ec4bb2897f9dc..0000000000000 --- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Check that we do not allow casts or coercions -// to dyn-incompatible trait objects by ref - -#![feature(dyn_compatible_for_dispatch)] - -trait Trait: Sized {} - -struct S; - -impl Trait for S {} - -fn takes_trait(t: &dyn Trait) {} - -fn main() { - &S as &dyn Trait; //~ ERROR E0038 - let t: &dyn Trait = &S; //~ ERROR E0038 - takes_trait(&S); //~ ERROR E0038 -} diff --git a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr b/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr deleted file mode 100644 index 716d0e78ff11d..0000000000000 --- a/tests/ui/wf/wf-convert-dyn-incompat-trait-obj.stderr +++ /dev/null @@ -1,54 +0,0 @@ -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:16:25 - | -LL | let t: &dyn Trait = &S; - | ^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: only type `S` implements `Trait`; consider using it directly instead. - = note: required for the cast from `&S` to `&dyn Trait` - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:17:17 - | -LL | takes_trait(&S); - | ^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: only type `S` implements `Trait`; consider using it directly instead. - = note: required for the cast from `&S` to `&dyn Trait` - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:15:5 - | -LL | &S as &dyn Trait; - | ^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-convert-dyn-incompat-trait-obj.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: only type `S` implements `Trait`; consider using it directly instead. - = note: required for the cast from `&S` to `&dyn Trait` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs deleted file mode 100644 index 6eba6b7abecd4..0000000000000 --- a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Check that we do not allow coercions to object -// unsafe trait objects in match arms - -#![feature(dyn_compatible_for_dispatch)] - -trait Trait: Sized {} - -struct S; - -impl Trait for S {} - -struct R; - -impl Trait for R {} - -fn opt() -> Option<()> { - Some(()) -} - -fn main() { - match opt() { - Some(()) => &S, - None => &R, //~ ERROR E0308 - } - let t: &dyn Trait = match opt() { - Some(()) => &S, //~ ERROR E0038 - None => &R, //~ ERROR E0038 - }; -} diff --git a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr deleted file mode 100644 index a7405ce4caa9f..0000000000000 --- a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr +++ /dev/null @@ -1,60 +0,0 @@ -error[E0308]: `match` arms have incompatible types - --> $DIR/wf-dyn-incompat-trait-obj-match.rs:23:17 - | -LL | / match opt() { -LL | | Some(()) => &S, - | | -- this is found to be of type `&S` -LL | | None => &R, - | | ^^ expected `&S`, found `&R` -LL | | } - | |_____- `match` arms have incompatible types - | - = note: expected reference `&S` - found reference `&R` - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-dyn-incompat-trait-obj-match.rs:26:21 - | -LL | Some(()) => &S, - | ^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: the following types implement `Trait`: - S - R - consider defining an enum where each variant holds one of these types, - implementing `Trait` for this new enum and using it instead - = note: required for the cast from `&S` to `&dyn Trait` - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/wf-dyn-incompat-trait-obj-match.rs:27:17 - | -LL | None => &R, - | ^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14 - | -LL | trait Trait: Sized {} - | ----- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait is not dyn compatible... - = help: the following types implement `Trait`: - S - R - consider defining an enum where each variant holds one of these types, - implementing `Trait` for this new enum and using it instead - = note: required for the cast from `&R` to `&dyn Trait` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0038, E0308. -For more information about an error, try `rustc --explain E0038`. From b6899ab9216d63762ba7f97c8a457dc9047e0a2b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 18:22:27 +0000 Subject: [PATCH 13/16] More eagerly bail in DispatchFromDyn validation --- .../src/coherence/builtin.rs | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b46b805f0a9d2..5d70d537505f9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -252,16 +252,16 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() })); } - let mut res = Ok(()); if def_a.repr().c() || def_a.repr().packed() { - res = Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span })); + return Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span })); } let fields = &def_a.non_enum_variant().fields; + let mut res = Ok(()); let coerced_fields = fields - .iter() - .filter(|field| { + .iter_enumerated() + .filter_map(|(i, field)| { // Ignore PhantomData fields let unnormalized_ty = tcx.type_of(field.did).instantiate_identity(); if tcx @@ -272,7 +272,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() .unwrap_or(unnormalized_ty) .is_phantom_data() { - return false; + return None; } let ty_a = field.ty(tcx, args_a); @@ -290,7 +290,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() && !ty_a.has_non_region_param() { // ignore 1-ZST fields - return false; + return None; } res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { @@ -299,40 +299,36 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() ty: ty_a, })); - return false; + None + } else { + Some((i, ty_a, ty_b)) } - - true }) .collect::>(); + res?; if coerced_fields.is_empty() { - res = Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle { + return Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle { span, trait_name: "DispatchFromDyn", note: true, })); } else if coerced_fields.len() > 1 { - res = Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti { + return Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti { span, coercions_note: true, number: coerced_fields.len(), coercions: coerced_fields .iter() - .map(|field| { - format!( - "`{}` (`{}` to `{}`)", - field.name, - field.ty(tcx, args_a), - field.ty(tcx, args_b), - ) + .map(|&(i, ty_a, ty_b)| { + format!("`{}` (`{}` to `{}`)", fields[i].name, ty_a, ty_b,) }) .collect::>() .join(", "), })); } else { let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - for field in coerced_fields { + for (_, ty_a, ty_b) in coerced_fields { ocx.register_obligation(Obligation::new( tcx, cause.clone(), @@ -340,19 +336,20 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() ty::TraitRef::new( tcx, dispatch_from_dyn_trait, - [field.ty(tcx, args_a), field.ty(tcx, args_b)], + [ty_a, ty_b], ), )); } let errors = ocx.select_all_or_error(); if !errors.is_empty() { - res = Err(infcx.err_ctxt().report_fulfillment_errors(errors)); + return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } // Finally, resolve all regions. - res = res.and(ocx.resolve_regions_and_report_errors(impl_did, param_env, [])); + ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?; } - res + + Ok(()) } _ => Err(tcx .dcx() @@ -558,11 +555,11 @@ pub(crate) fn coerce_unsized_info<'tcx>( ocx.register_obligation(obligation); let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(errors); + return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } // Finally, resolve all regions. - let _ = ocx.resolve_regions_and_report_errors(impl_did, param_env, []); + ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?; Ok(CoerceUnsizedInfo { custom_kind: kind }) } From 96d966b07aabbf0438489b848b8f039f88bb518e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 19:10:01 +0000 Subject: [PATCH 14/16] Consolidate and rework CoercePointee and DispatchFromDyn errors --- .../src/error_codes/E0374.md | 53 ++++---------- .../src/error_codes/E0375.md | 47 +++---------- .../src/error_codes/E0376.md | 38 ++-------- .../src/error_codes/E0377.md | 23 +++--- compiler/rustc_hir_analysis/messages.ftl | 13 ++-- .../src/coherence/builtin.rs | 67 +++++++----------- compiler/rustc_hir_analysis/src/errors.rs | 70 ++++--------------- tests/ui/coercion/issue-26905.stderr | 13 ++-- tests/ui/error-codes/E0374.stderr | 2 +- tests/ui/error-codes/E0375.stderr | 13 ++-- tests/ui/error-codes/E0376.rs | 10 --- tests/ui/error-codes/E0376.stderr | 9 --- tests/ui/invalid_dispatch_from_dyn_impls.rs | 14 ++-- .../ui/invalid_dispatch_from_dyn_impls.stderr | 28 +++++--- ...patch-from-dyn-zst-transmute-zst-nonzst.rs | 2 +- ...h-from-dyn-zst-transmute-zst-nonzst.stderr | 13 ++-- .../self/dispatch-from-dyn-zst-transmute.rs | 2 +- .../dispatch-from-dyn-zst-transmute.stderr | 13 ++-- tests/ui/traits/issue-78372.stderr | 4 +- 19 files changed, 158 insertions(+), 276 deletions(-) delete mode 100644 tests/ui/error-codes/E0376.rs delete mode 100644 tests/ui/error-codes/E0376.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0374.md b/compiler/rustc_error_codes/src/error_codes/E0374.md index 6d7dc88823c99..63c243b54ff2a 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0374.md +++ b/compiler/rustc_error_codes/src/error_codes/E0374.md @@ -1,5 +1,5 @@ -`CoerceUnsized` was implemented on a struct which does not contain a field with -an unsized type. +`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which does not +contain a field that is being unsized. Example of erroneous code: @@ -11,47 +11,20 @@ struct Foo { a: i32, } -// error: Struct `Foo` has no unsized fields that need `CoerceUnsized`. +// error: Struct `Foo` has no unsized fields that need to be coerced. impl CoerceUnsized> for Foo where T: CoerceUnsized {} ``` -An [unsized type][1] is any type where the compiler does not know the length or -alignment of at compile time. Any struct containing an unsized type is also -unsized. +`CoerceUnsized` is used to coerce structs that have a field that can be unsized, +like a custom `MyBox` being unsized to `MyBox`. `DispatchFromDyn` +is used to dispatch from `MyBox` to `MyBox` in a dyn-compatible +trait. -[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait +If the struct doesn't have any fields of unsized types then there is no +meaningful way to implement `CoerceUnsized` or `DispatchFromDyn`, since +there is no coercion taking place. -`CoerceUnsized` is used to coerce one struct containing an unsized type -into another struct containing a different unsized type. If the struct -doesn't have any fields of unsized types then you don't need explicit -coercion to get the types you want. To fix this you can either -not try to implement `CoerceUnsized` or you can add a field that is -unsized to the struct. - -Example: - -``` -#![feature(coerce_unsized)] -use std::ops::CoerceUnsized; - -// We don't need to impl `CoerceUnsized` here. -struct Foo { - a: i32, -} - -// We add the unsized type field to the struct. -struct Bar { - a: i32, - b: T, -} - -// The struct has an unsized field so we can implement -// `CoerceUnsized` for it. -impl CoerceUnsized> for Bar - where T: CoerceUnsized {} -``` - -Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc` -and `Arc` to be able to mark that they can coerce unsized types that they -are pointing at. +Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers +like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types +that they are pointing at. diff --git a/compiler/rustc_error_codes/src/error_codes/E0375.md b/compiler/rustc_error_codes/src/error_codes/E0375.md index 71e530571650b..7abb3b6afd02f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0375.md +++ b/compiler/rustc_error_codes/src/error_codes/E0375.md @@ -1,5 +1,5 @@ -`CoerceUnsized` was implemented on a struct which contains more than one field -with an unsized type. +`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which contains +more than one field that is being unsized. Erroneous code example: @@ -17,39 +17,14 @@ struct Foo { impl CoerceUnsized> for Foo {} ``` -A struct with more than one field containing an unsized type cannot implement -`CoerceUnsized`. This only occurs when you are trying to coerce one of the -types in your struct to another type in the struct. In this case we try to -impl `CoerceUnsized` from `T` to `U` which are both types that the struct -takes. An [unsized type][1] is any type that the compiler doesn't know the -length or alignment of at compile time. Any struct containing an unsized type -is also unsized. +`CoerceUnsized` is used to coerce structs that have a field that can be unsized, +like a custom `MyBox` being unsized to `MyBox`. `DispatchFromDyn` +is used to dispatch from `MyBox` to `MyBox` in a dyn-compatible +trait. -`CoerceUnsized` only allows for coercion from a structure with a single -unsized type field to another struct with a single unsized type field. -In fact Rust only allows for a struct to have one unsized type in a struct -and that unsized type must be the last field in the struct. So having two -unsized types in a single struct is not allowed by the compiler. To fix this -use only one field containing an unsized type in the struct and then use -multiple structs to manage each unsized type field you need. +If the struct has multiple fields that must be unsized, then the compiler has no +way to generate a valid implementation of `CoerceUnsized` or `DispatchFromDyn`. -Example: - -``` -#![feature(coerce_unsized)] -use std::ops::CoerceUnsized; - -struct Foo { - a: i32, - b: T, -} - -impl CoerceUnsized> for Foo - where T: CoerceUnsized {} - -fn coerce_foo, U>(t: T) -> Foo { - Foo { a: 12i32, b: t } // we use coercion to get the `Foo` type we need -} -``` - -[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait +Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers +like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types +that they are pointing at. diff --git a/compiler/rustc_error_codes/src/error_codes/E0376.md b/compiler/rustc_error_codes/src/error_codes/E0376.md index 50de15bd30f09..5b564ec22fcb8 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0376.md +++ b/compiler/rustc_error_codes/src/error_codes/E0376.md @@ -1,8 +1,11 @@ -`CoerceUnsized` was implemented on something that isn't a struct. +#### Note: this error code is no longer emitted by the compiler. + +`CoerceUnsized` or `DispatchFromDyn` was implemented between two types that +are not structs. Erroneous code example: -```compile_fail,E0376 +```compile_fail,E0377 #![feature(coerce_unsized)] use std::ops::CoerceUnsized; @@ -14,33 +17,4 @@ struct Foo { impl CoerceUnsized for Foo {} ``` -`CoerceUnsized` can only be implemented for a struct. Unsized types are -already able to be coerced without an implementation of `CoerceUnsized` -whereas a struct containing an unsized type needs to know the unsized type -field it's containing is able to be coerced. An [unsized type][1] -is any type that the compiler doesn't know the length or alignment of at -compile time. Any struct containing an unsized type is also unsized. - -[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait - -The `CoerceUnsized` trait takes a struct type. Make sure the type you are -providing to `CoerceUnsized` is a struct with only the last field containing an -unsized type. - -Example: - -``` -#![feature(coerce_unsized)] -use std::ops::CoerceUnsized; - -struct Foo { - a: T, -} - -// The `Foo` is a struct so `CoerceUnsized` can be implemented -impl CoerceUnsized> for Foo where T: CoerceUnsized {} -``` - -Note that in Rust, structs can only contain an unsized type if the field -containing the unsized type is the last and only unsized type field in the -struct. +`CoerceUnsized` or `DispatchFromDyn` can only be implemented between structs. diff --git a/compiler/rustc_error_codes/src/error_codes/E0377.md b/compiler/rustc_error_codes/src/error_codes/E0377.md index b1d36406332bd..cd2b26260a8af 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0377.md +++ b/compiler/rustc_error_codes/src/error_codes/E0377.md @@ -1,5 +1,5 @@ -The trait `CoerceUnsized` may only be implemented for a coercion between -structures with the same definition. +`CoerceUnsized` or `DispatchFromDyn` may only be implemented between structs +of the same type. Example of erroneous code: @@ -20,10 +20,15 @@ pub struct Bar { impl CoerceUnsized> for Foo where T: CoerceUnsized {} ``` -When attempting to implement `CoerceUnsized`, the `impl` signature must look -like: `impl CoerceUnsized> for Type where T: CoerceUnsized`; -the *implementer* and *`CoerceUnsized` type parameter* must be the same -type. In this example, `Bar` and `Foo` (even though structurally identical) -are *not* the same type and are rejected. Learn more about the `CoerceUnsized` -trait and DST coercion in -[the `CoerceUnsized` docs](../std/ops/trait.CoerceUnsized.html). +`CoerceUnsized` is used to coerce structs that have a field that can be unsized, +like a custom `MyBox` being unsized to `MyBox`. `DispatchFromDyn` +is used to dispatch from `MyBox` to `MyBox` in a dyn-compatible +trait. + +The compiler cannot support coercions between structs of different types, so +a valid implementation of `CoerceUnsized` or `DispatchFromDyn` should be +implemented between the same struct with different generic parameters. + +Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers +like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types +that they are pointing at. diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 47d5976be09ef..98eb4f65e22bb 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -85,6 +85,10 @@ hir_analysis_cmse_output_stack_spill = .note1 = functions with the `{$abi}` ABI must pass their result via the available return registers .note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size +hir_analysis_coerce_multi = implementing `{$trait_name}` does not allow multiple fields to be coerced + .note = the trait `{$trait_name}` may only be implemented when a single field is being coerced + .label = these fields must be coerced for `{$trait_name}` to be valid + hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden @@ -97,10 +101,7 @@ hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only ap hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures -hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions - .note = `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced - .coercions_note = currently, {$number} fields need coercions: {$coercions} - .label = requires multiple coercions +hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}` @@ -139,10 +140,6 @@ hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like ` hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate .label = can't implement cross-crate trait for type in another crate -hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions - .note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced - .coercions_note = currently, {$number} fields need coercions: {$coercions} - hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 5d70d537505f9..dc9a5a3db5dfd 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -240,16 +240,17 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() (&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()), (&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - let source_path = tcx.def_path_str(def_a.did()); - let target_path = tcx.def_path_str(def_b.did()); - - return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion { - span, - trait_name: "DispatchFromDyn", - note: true, - source_path, - target_path, - })); + if def_a != def_b { + let source_path = tcx.def_path_str(def_a.did()); + let target_path = tcx.def_path_str(def_b.did()); + return Err(tcx.dcx().emit_err(errors::CoerceSameStruct { + span, + trait_name: "DispatchFromDyn", + note: true, + source_path, + target_path, + })); + } } if def_a.repr().c() || def_a.repr().packed() { @@ -301,43 +302,33 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() None } else { - Some((i, ty_a, ty_b)) + Some((i, ty_a, ty_b, tcx.def_span(field.did))) } }) .collect::>(); res?; if coerced_fields.is_empty() { - return Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle { + return Err(tcx.dcx().emit_err(errors::CoerceNoField { span, trait_name: "DispatchFromDyn", note: true, })); } else if coerced_fields.len() > 1 { - return Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti { + return Err(tcx.dcx().emit_err(errors::CoerceMulti { span, - coercions_note: true, + trait_name: "DispatchFromDyn", number: coerced_fields.len(), - coercions: coerced_fields - .iter() - .map(|&(i, ty_a, ty_b)| { - format!("`{}` (`{}` to `{}`)", fields[i].name, ty_a, ty_b,) - }) - .collect::>() - .join(", "), + fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::>().into(), })); } else { let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - for (_, ty_a, ty_b) in coerced_fields { + for (_, ty_a, ty_b, _) in coerced_fields { ocx.register_obligation(Obligation::new( tcx, cause.clone(), param_env, - ty::TraitRef::new( - tcx, - dispatch_from_dyn_trait, - [ty_a, ty_b], - ), + ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]), )); } let errors = ocx.select_all_or_error(); @@ -353,7 +344,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() } _ => Err(tcx .dcx() - .emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })), + .emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "DispatchFromDyn" })), } } @@ -419,7 +410,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( if def_a != def_b { let source_path = tcx.def_path_str(def_a.did()); let target_path = tcx.def_path_str(def_b.did()); - return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame { + return Err(tcx.dcx().emit_err(errors::CoerceSameStruct { span, trait_name: "CoerceUnsized", note: true, @@ -501,12 +492,12 @@ pub(crate) fn coerce_unsized_info<'tcx>( // Collect up all fields that were significantly changed // i.e., those that contain T in coerce_unsized T -> U - Some((i, a, b)) + Some((i, a, b, tcx.def_span(f.did))) }) .collect::>(); if diff_fields.is_empty() { - return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField { + return Err(tcx.dcx().emit_err(errors::CoerceNoField { span, trait_name: "CoerceUnsized", note: true, @@ -519,19 +510,15 @@ pub(crate) fn coerce_unsized_info<'tcx>( tcx.def_span(impl_did) }; - return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti { + return Err(tcx.dcx().emit_err(errors::CoerceMulti { span, - coercions_note: true, + trait_name: "CoerceUnsized", number: diff_fields.len(), - coercions: diff_fields - .iter() - .map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b)) - .collect::>() - .join(", "), + fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::>().into(), })); } - let (i, a, b) = diff_fields[0]; + let (i, a, b, _) = diff_fields[0]; let kind = ty::adjustment::CustomCoerceUnsized::Struct(i); (a, b, coerce_unsized_trait, Some(kind)) } @@ -539,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( _ => { return Err(tcx .dcx() - .emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" })); + .emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "CoerceUnsized" })); } }; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1a0b0edb25703..a74d9b95e0e60 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1164,18 +1164,6 @@ pub(crate) struct InherentTyOutside { pub span: Span, } -#[derive(Diagnostic)] -#[diag(hir_analysis_coerce_unsized_may, code = E0378)] -pub(crate) struct DispatchFromDynCoercion<'a> { - #[primary_span] - pub span: Span, - pub trait_name: &'a str, - #[note(hir_analysis_coercion_between_struct_same_note)] - pub note: bool, - pub source_path: String, - pub target_path: String, -} - #[derive(Diagnostic)] #[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)] pub(crate) struct DispatchFromDynRepr { @@ -1293,78 +1281,46 @@ pub(crate) struct DispatchFromDynZST<'a> { } #[derive(Diagnostic)] -#[diag(hir_analysis_coerce_unsized_may, code = E0378)] -pub(crate) struct DispatchFromDynSingle<'a> { +#[diag(hir_analysis_coerce_zero, code = E0374)] +pub(crate) struct CoerceNoField { #[primary_span] pub span: Span, - pub trait_name: &'a str, + pub trait_name: &'static str, #[note(hir_analysis_coercion_between_struct_single_note)] pub note: bool, } #[derive(Diagnostic)] -#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)] -#[note] -pub(crate) struct DispatchFromDynMulti { +#[diag(hir_analysis_coerce_multi, code = E0375)] +pub(crate) struct CoerceMulti { + pub trait_name: &'static str, #[primary_span] pub span: Span, - #[note(hir_analysis_coercions_note)] - pub coercions_note: bool, pub number: usize, - pub coercions: String, + #[note] + pub fields: MultiSpan, } #[derive(Diagnostic)] -#[diag(hir_analysis_coerce_unsized_may, code = E0376)] -pub(crate) struct DispatchFromDynStruct<'a> { +#[diag(hir_analysis_coerce_unsized_may, code = E0377)] +pub(crate) struct CoerceUnsizedNonStruct { #[primary_span] pub span: Span, - pub trait_name: &'a str, + pub trait_name: &'static str, } #[derive(Diagnostic)] #[diag(hir_analysis_coerce_unsized_may, code = E0377)] -pub(crate) struct DispatchFromDynSame<'a> { +pub(crate) struct CoerceSameStruct { #[primary_span] pub span: Span, - pub trait_name: &'a str, + pub trait_name: &'static str, #[note(hir_analysis_coercion_between_struct_same_note)] pub note: bool, pub source_path: String, pub target_path: String, } -#[derive(Diagnostic)] -#[diag(hir_analysis_coerce_unsized_may, code = E0374)] -pub(crate) struct CoerceUnsizedOneField<'a> { - #[primary_span] - pub span: Span, - pub trait_name: &'a str, - #[note(hir_analysis_coercion_between_struct_single_note)] - pub note: bool, -} - -#[derive(Diagnostic)] -#[diag(hir_analysis_coerce_unsized_multi, code = E0375)] -#[note] -pub(crate) struct CoerceUnsizedMulti { - #[primary_span] - #[label] - pub span: Span, - #[note(hir_analysis_coercions_note)] - pub coercions_note: bool, - pub number: usize, - pub coercions: String, -} - -#[derive(Diagnostic)] -#[diag(hir_analysis_coerce_unsized_may, code = E0378)] -pub(crate) struct CoerceUnsizedMay<'a> { - #[primary_span] - pub span: Span, - pub trait_name: &'a str, -} - #[derive(Diagnostic)] #[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)] pub(crate) struct TraitCannotImplForTy { diff --git a/tests/ui/coercion/issue-26905.stderr b/tests/ui/coercion/issue-26905.stderr index 86f6a14cd1053..17387ae992b42 100644 --- a/tests/ui/coercion/issue-26905.stderr +++ b/tests/ui/coercion/issue-26905.stderr @@ -1,11 +1,16 @@ -error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions +error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced --> $DIR/issue-26905.rs:16:40 | LL | impl, U: ?Sized> CoerceUnsized> for MyRc{ } - | ^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions + | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced - = note: currently, 2 fields need coercions: `_ptr` (`*const T` to `*const U`), `_boo` (`NotPhantomData` to `NotPhantomData`) +note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced + --> $DIR/issue-26905.rs:12:5 + | +LL | _ptr: *const T, + | ^^^^^^^^^^^^^^ +LL | _boo: NotPhantomData, + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0374.stderr b/tests/ui/error-codes/E0374.stderr index 71eec4c16fd34..95e6b95e0d56b 100644 --- a/tests/ui/error-codes/E0374.stderr +++ b/tests/ui/error-codes/E0374.stderr @@ -6,7 +6,7 @@ LL | struct Foo { | = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` -error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures +error[E0374]: implementing `CoerceUnsized` requires a field to be coerced --> $DIR/E0374.rs:8:1 | LL | / impl CoerceUnsized> for Foo diff --git a/tests/ui/error-codes/E0375.stderr b/tests/ui/error-codes/E0375.stderr index af720bd40e7e3..a797ba9d4612f 100644 --- a/tests/ui/error-codes/E0375.stderr +++ b/tests/ui/error-codes/E0375.stderr @@ -23,14 +23,19 @@ help: the `Box` type always has a statically known size and allocates its conten LL | b: Box, | ++++ + -error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions +error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced --> $DIR/E0375.rs:10:12 | LL | impl CoerceUnsized> for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions + | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced - = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`) +note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced + --> $DIR/E0375.rs:6:5 + | +LL | b: T, + | ^^^^ +LL | c: U, + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0376.rs b/tests/ui/error-codes/E0376.rs deleted file mode 100644 index f092eb02c2bcc..0000000000000 --- a/tests/ui/error-codes/E0376.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(coerce_unsized)] -use std::ops::CoerceUnsized; - -struct Foo { - a: T, -} - -impl CoerceUnsized for Foo {} //~ ERROR E0376 - -fn main() {} diff --git a/tests/ui/error-codes/E0376.stderr b/tests/ui/error-codes/E0376.stderr deleted file mode 100644 index 46668e05a42f4..0000000000000 --- a/tests/ui/error-codes/E0376.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0376]: the trait `CoerceUnsized` may only be implemented for a coercion between structures - --> $DIR/E0376.rs:8:1 - | -LL | impl CoerceUnsized for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0376`. diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.rs b/tests/ui/invalid_dispatch_from_dyn_impls.rs index b7bc766fbe020..972465d71978c 100644 --- a/tests/ui/invalid_dispatch_from_dyn_impls.rs +++ b/tests/ui/invalid_dispatch_from_dyn_impls.rs @@ -8,9 +8,10 @@ use std::{ struct WrapperWithExtraField(T, i32); impl DispatchFromDyn> for WrapperWithExtraField +//~^ ERROR [E0378] where T: DispatchFromDyn, -{} //~^^^ ERROR [E0378] +{} struct MultiplePointers{ @@ -19,9 +20,10 @@ struct MultiplePointers{ } impl DispatchFromDyn> for MultiplePointers +//~^ implementing `DispatchFromDyn` does not allow multiple fields to be coerced where T: Unsize, -{} //~^^^ ERROR [E0378] +{} struct NothingToCoerce { @@ -29,23 +31,25 @@ struct NothingToCoerce { } impl DispatchFromDyn> for NothingToCoerce {} -//~^ ERROR [E0378] +//~^ ERROR implementing `DispatchFromDyn` requires a field to be coerced #[repr(C)] struct HasReprC(Box); impl DispatchFromDyn> for HasReprC +//~^ ERROR [E0378] where T: Unsize, -{} //~^^^ ERROR [E0378] +{} #[repr(align(64))] struct OverAlignedZst; struct OverAligned(Box, OverAlignedZst); impl DispatchFromDyn> for OverAligned +//~^ ERROR [E0378] where T: Unsize, -{} //~^^^ ERROR [E0378] +{} fn main() {} diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/invalid_dispatch_from_dyn_impls.stderr index 02718334c733e..93ec6bbe0896f 100644 --- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr +++ b/tests/ui/invalid_dispatch_from_dyn_impls.stderr @@ -2,25 +2,32 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs co --> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1 | LL | / impl DispatchFromDyn> for WrapperWithExtraField +LL | | LL | | where LL | | T: DispatchFromDyn, | |__________________________^ | = note: extra field `1` of type `i32` is not allowed -error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions - --> $DIR/invalid_dispatch_from_dyn_impls.rs:21:1 +error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced + --> $DIR/invalid_dispatch_from_dyn_impls.rs:22:1 | LL | / impl DispatchFromDyn> for MultiplePointers +LL | | LL | | where LL | | T: Unsize, | |_________________^ | - = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced - = note: currently, 2 fields need coercions: `ptr1` (`*const T` to `*const U`), `ptr2` (`*const T` to `*const U`) +note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced + --> $DIR/invalid_dispatch_from_dyn_impls.rs:18:5 + | +LL | ptr1: *const T, + | ^^^^^^^^^^^^^^ +LL | ptr2: *const T, + | ^^^^^^^^^^^^^^ -error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures - --> $DIR/invalid_dispatch_from_dyn_impls.rs:31:1 +error[E0374]: implementing `DispatchFromDyn` requires a field to be coerced + --> $DIR/invalid_dispatch_from_dyn_impls.rs:33:1 | LL | impl DispatchFromDyn> for NothingToCoerce {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,17 +35,19 @@ LL | impl DispatchFromDyn> for NothingT = note: expected a single field to be coerced, none found error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` - --> $DIR/invalid_dispatch_from_dyn_impls.rs:37:1 + --> $DIR/invalid_dispatch_from_dyn_impls.rs:39:1 | LL | / impl DispatchFromDyn> for HasReprC +LL | | LL | | where LL | | T: Unsize, | |_________________^ error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else - --> $DIR/invalid_dispatch_from_dyn_impls.rs:46:1 + --> $DIR/invalid_dispatch_from_dyn_impls.rs:49:1 | LL | / impl DispatchFromDyn> for OverAligned +LL | | LL | | where LL | | T: Unsize, | |_____________________^ @@ -47,4 +56,5 @@ LL | | T: Unsize, error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0378`. +Some errors have detailed explanations: E0374, E0375, E0378. +For more information about an error, try `rustc --explain E0374`. diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs index 71f198f7dc70e..94b76fe96854e 100644 --- a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs +++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs @@ -15,7 +15,7 @@ struct Dispatchable { } impl DispatchFromDyn> for Dispatchable -//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions +//~^ ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced where T: Unsize + ?Sized, U: ?Sized, diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr index 1f13c51f67996..91760b9e2eab5 100644 --- a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr +++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr @@ -1,4 +1,4 @@ -error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions +error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced --> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:17:1 | LL | / impl DispatchFromDyn> for Dispatchable @@ -8,9 +8,14 @@ LL | | T: Unsize + ?Sized, LL | | U: ?Sized, | |______________^ | - = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced - = note: currently, 2 fields need coercions: `_ptr` (`Box` to `Box`), `z` (`()` to `i32`) +note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced + --> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:13:5 + | +LL | _ptr: Box, + | ^^^^^^^^^^^^ +LL | z: Z, + | ^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0378`. +For more information about this error, try `rustc --explain E0375`. diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs index 57c255b4d7bca..967958ab48695 100644 --- a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs +++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs @@ -15,7 +15,7 @@ struct Foo<'a, U: ?Sized> { } impl<'a, T, U> DispatchFromDyn> for Foo<'a, T> -//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions +//~^ ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced where T: Unsize + ?Sized, U: ?Sized {} diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr index 5a8ae88b5f1b8..cc8be45e99d8a 100644 --- a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr +++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr @@ -1,4 +1,4 @@ -error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions +error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced --> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1 | LL | / impl<'a, T, U> DispatchFromDyn> for Foo<'a, T> @@ -8,9 +8,14 @@ LL | | T: Unsize + ?Sized, LL | | U: ?Sized {} | |_____________^ | - = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced - = note: currently, 2 fields need coercions: `token` (`IsSendToken` to `IsSendToken`), `ptr` (`&'a T` to `&'a U`) +note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced + --> $DIR/dispatch-from-dyn-zst-transmute.rs:13:5 + | +LL | token: IsSendToken, + | ^^^^^^^^^^^^^^^^^^^^^ +LL | ptr: &'a U, + | ^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0378`. +For more information about this error, try `rustc --explain E0375`. diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index d4dfba4f039f6..fbc60ce5d83e6 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -65,7 +65,7 @@ LL | fn foo(self: Smaht); = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures +error[E0377]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures --> $DIR/issue-78372.rs:3:1 | LL | impl DispatchFromDyn> for T {} @@ -73,5 +73,5 @@ LL | impl DispatchFromDyn> for T {} error: aborting due to 7 previous errors -Some errors have detailed explanations: E0307, E0378, E0412, E0658. +Some errors have detailed explanations: E0307, E0377, E0412, E0658. For more information about an error, try `rustc --explain E0307`. From 5c5ed92c37a70603e9d45c698898841afacfb25f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 19:51:06 +0000 Subject: [PATCH 15/16] Simplify trait error message for CoercePointee validation --- compiler/rustc_hir_analysis/messages.ftl | 3 + .../src/coherence/builtin.rs | 116 +++++++++++------- compiler/rustc_hir_analysis/src/errors.rs | 12 ++ library/core/src/marker.rs | 1 + .../deriving/deriving-coerce-pointee-neg.rs | 26 ++++ .../deriving-coerce-pointee-neg.stderr | 91 +++++++++++++- 6 files changed, 199 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 98eb4f65e22bb..6badd29091750 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -99,6 +99,9 @@ hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applica hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout +hir_analysis_coerce_unsized_field_validity = for `{$ty}` to have a valid implementation of `{$trait_name}`, it must be possible to coerce the field of type `{$field_ty}` + .label = `{$field_ty}` must be a pointer, reference, or smart pointer that is allowed to be unsized + hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index dc9a5a3db5dfd..9d6bb1cf6bffd 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeVisitableExt, TypingMode, suggest_constraining_type_params, }; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::{DUMMY_SP, Span, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::misc::{ ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason, @@ -199,6 +199,13 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E tcx.at(span).ensure_ok().coerce_unsized_info(impl_did) } +fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool { + span.ctxt() + .outer_expn_data() + .macro_def_id + .is_some_and(|def_id| tcx.is_diagnostic_item(sym::CoercePointee, def_id)) +} + fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; let impl_did = checker.impl_def_id; @@ -206,6 +213,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); let span = tcx.def_span(impl_did); + let trait_name = "DispatchFromDyn"; let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); @@ -240,17 +248,15 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() (&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()), (&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { - if def_a != def_b { - let source_path = tcx.def_path_str(def_a.did()); - let target_path = tcx.def_path_str(def_b.did()); - return Err(tcx.dcx().emit_err(errors::CoerceSameStruct { - span, - trait_name: "DispatchFromDyn", - note: true, - source_path, - target_path, - })); - } + let source_path = tcx.def_path_str(def_a.did()); + let target_path = tcx.def_path_str(def_b.did()); + return Err(tcx.dcx().emit_err(errors::CoerceSameStruct { + span, + trait_name, + note: true, + source_path, + target_path, + })); } if def_a.repr().c() || def_a.repr().packed() { @@ -311,40 +317,46 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() if coerced_fields.is_empty() { return Err(tcx.dcx().emit_err(errors::CoerceNoField { span, - trait_name: "DispatchFromDyn", + trait_name, note: true, })); - } else if coerced_fields.len() > 1 { - return Err(tcx.dcx().emit_err(errors::CoerceMulti { - span, - trait_name: "DispatchFromDyn", - number: coerced_fields.len(), - fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::>().into(), - })); - } else { + } else if let &[(_, ty_a, ty_b, field_span)] = &coerced_fields[..] { let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - for (_, ty_a, ty_b, _) in coerced_fields { - ocx.register_obligation(Obligation::new( - tcx, - cause.clone(), - param_env, - ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]), - )); - } + ocx.register_obligation(Obligation::new( + tcx, + cause.clone(), + param_env, + ty::TraitRef::new(tcx, dispatch_from_dyn_trait, [ty_a, ty_b]), + )); let errors = ocx.select_all_or_error(); if !errors.is_empty() { - return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); + if is_from_coerce_pointee_derive(tcx, span) { + return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity { + span, + trait_name, + ty: trait_ref.self_ty(), + field_span, + field_ty: ty_a, + })); + } else { + return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); + } } // Finally, resolve all regions. ocx.resolve_regions_and_report_errors(impl_did, param_env, [])?; - } - Ok(()) + Ok(()) + } else { + return Err(tcx.dcx().emit_err(errors::CoerceMulti { + span, + trait_name, + number: coerced_fields.len(), + fields: coerced_fields.iter().map(|(_, _, _, s)| *s).collect::>().into(), + })); + } } - _ => Err(tcx - .dcx() - .emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "DispatchFromDyn" })), + _ => Err(tcx.dcx().emit_err(errors::CoerceUnsizedNonStruct { span, trait_name })), } } @@ -354,13 +366,14 @@ pub(crate) fn coerce_unsized_info<'tcx>( ) -> Result { debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did); let span = tcx.def_span(impl_did); + let trait_name = "CoerceUnsized"; let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); - let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span)); let source = tcx.type_of(impl_did).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().instantiate_identity(); + assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.args.type_at(1); debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); @@ -387,9 +400,9 @@ pub(crate) fn coerce_unsized_info<'tcx>( ) .emit(); } - (mt_a.ty, mt_b.ty, unsize_trait, None) + (mt_a.ty, mt_b.ty, unsize_trait, None, span) }; - let (source, target, trait_def_id, kind) = match (source.kind(), target.kind()) { + let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) { (&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => { infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a); let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a }; @@ -412,7 +425,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( let target_path = tcx.def_path_str(def_b.did()); return Err(tcx.dcx().emit_err(errors::CoerceSameStruct { span, - trait_name: "CoerceUnsized", + trait_name, note: true, source_path, target_path, @@ -499,7 +512,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( if diff_fields.is_empty() { return Err(tcx.dcx().emit_err(errors::CoerceNoField { span, - trait_name: "CoerceUnsized", + trait_name, note: true, })); } else if diff_fields.len() > 1 { @@ -512,21 +525,19 @@ pub(crate) fn coerce_unsized_info<'tcx>( return Err(tcx.dcx().emit_err(errors::CoerceMulti { span, - trait_name: "CoerceUnsized", + trait_name, number: diff_fields.len(), fields: diff_fields.iter().map(|(_, _, _, s)| *s).collect::>().into(), })); } - let (i, a, b, _) = diff_fields[0]; + let (i, a, b, field_span) = diff_fields[0]; let kind = ty::adjustment::CustomCoerceUnsized::Struct(i); - (a, b, coerce_unsized_trait, Some(kind)) + (a, b, coerce_unsized_trait, Some(kind), field_span) } _ => { - return Err(tcx - .dcx() - .emit_err(errors::CoerceUnsizedNonStruct { span, trait_name: "CoerceUnsized" })); + return Err(tcx.dcx().emit_err(errors::CoerceUnsizedNonStruct { span, trait_name })); } }; @@ -541,8 +552,19 @@ pub(crate) fn coerce_unsized_info<'tcx>( ); ocx.register_obligation(obligation); let errors = ocx.select_all_or_error(); + if !errors.is_empty() { - return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); + if is_from_coerce_pointee_derive(tcx, span) { + return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity { + span, + trait_name, + ty: trait_ref.self_ty(), + field_span, + field_ty: source, + })); + } else { + return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); + } } // Finally, resolve all regions. diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index a74d9b95e0e60..99262f9871e07 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1321,6 +1321,18 @@ pub(crate) struct CoerceSameStruct { pub target_path: String, } +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_field_validity)] +pub(crate) struct CoerceFieldValidity<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, + pub trait_name: &'static str, + #[label] + pub field_span: Span, + pub field_ty: Ty<'tcx>, +} + #[derive(Diagnostic)] #[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)] pub(crate) struct TraitCannotImplForTy { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 842a48e1606de..b0571bf7247af 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1302,6 +1302,7 @@ pub trait FnPtr: Copy + Clone { /// ``` #[rustc_builtin_macro(CoercePointee, attributes(pointee))] #[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)] +#[cfg_attr(not(test), rustc_diagnostic_item = "CoercePointee")] #[unstable(feature = "derive_coerce_pointee", issue = "123430")] pub macro CoercePointee($item:item) { /* compiler built-in */ diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.rs b/tests/ui/deriving/deriving-coerce-pointee-neg.rs index 6577500d8eb0f..e660e7baacb50 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.rs +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.rs @@ -142,4 +142,30 @@ struct TryToWipeRepr<'a, #[pointee] T: ?Sized> { ptr: &'a T, } +#[repr(transparent)] +#[derive(CoercePointee)] +//~^ ERROR for `RcWithId` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box)>` +//~| ERROR for `RcWithId` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box)>` +struct RcWithId { + inner: std::rc::Rc<(i32, Box)>, +} + +#[repr(transparent)] +#[derive(CoercePointee)] +//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced +//~| ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced +struct MoreThanOneField { + //~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2 + inner1: Box, + inner2: Box, +} + +struct NotCoercePointeeData(T); + +#[repr(transparent)] +#[derive(CoercePointee)] +//~^ ERROR for `UsingNonCoercePointeeData` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData` +//~| ERROR for `UsingNonCoercePointeeData` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData` +struct UsingNonCoercePointeeData(NotCoercePointeeData); + fn main() {} diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr index 999214bfa9fe3..e346d13ff5c08 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr @@ -118,7 +118,92 @@ error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr( LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors +error: for `RcWithId` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box)>` + --> $DIR/deriving-coerce-pointee-neg.rs:146:10 + | +LL | #[derive(CoercePointee)] + | ^^^^^^^^^^^^^ +... +LL | inner: std::rc::Rc<(i32, Box)>, + | --------------------------------- `Rc<(i32, Box)>` must be a pointer, reference, or smart pointer that is allowed to be unsized + | + = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced + --> $DIR/deriving-coerce-pointee-neg.rs:154:10 + | +LL | #[derive(CoercePointee)] + | ^^^^^^^^^^^^^ + | +note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced + --> $DIR/deriving-coerce-pointee-neg.rs:159:5 + | +LL | inner1: Box, + | ^^^^^^^^^^^^^^ +LL | inner2: Box, + | ^^^^^^^^^^^^^^ + = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: for `UsingNonCoercePointeeData` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData` + --> $DIR/deriving-coerce-pointee-neg.rs:166:10 + | +LL | #[derive(CoercePointee)] + | ^^^^^^^^^^^^^ +... +LL | struct UsingNonCoercePointeeData(NotCoercePointeeData); + | ----------------------- `NotCoercePointeeData` must be a pointer, reference, or smart pointer that is allowed to be unsized + | + = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: for `RcWithId` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box)>` + --> $DIR/deriving-coerce-pointee-neg.rs:146:10 + | +LL | #[derive(CoercePointee)] + | ^^^^^^^^^^^^^ +... +LL | inner: std::rc::Rc<(i32, Box)>, + | --------------------------------- `Rc<(i32, Box)>` must be a pointer, reference, or smart pointer that is allowed to be unsized + | + = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced + --> $DIR/deriving-coerce-pointee-neg.rs:154:10 + | +LL | #[derive(CoercePointee)] + | ^^^^^^^^^^^^^ + | +note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced + --> $DIR/deriving-coerce-pointee-neg.rs:159:5 + | +LL | inner1: Box, + | ^^^^^^^^^^^^^^ +LL | inner2: Box, + | ^^^^^^^^^^^^^^ + = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: for `UsingNonCoercePointeeData` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData` + --> $DIR/deriving-coerce-pointee-neg.rs:166:10 + | +LL | #[derive(CoercePointee)] + | ^^^^^^^^^^^^^ +... +LL | struct UsingNonCoercePointeeData(NotCoercePointeeData); + | ----------------------- `NotCoercePointeeData` must be a pointer, reference, or smart pointer that is allowed to be unsized + | + = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/deriving-coerce-pointee-neg.rs:157:1 + | +LL | struct MoreThanOneField { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 +LL | +LL | inner1: Box, + | -------------- this field has non-zero size or requires alignment +LL | inner2: Box, + | -------------- this field has non-zero size or requires alignment + +error: aborting due to 24 previous errors -Some errors have detailed explanations: E0392, E0802. -For more information about an error, try `rustc --explain E0392`. +Some errors have detailed explanations: E0375, E0392, E0690, E0802. +For more information about an error, try `rustc --explain E0375`. From b46acc01916ba3e8b8f8ab9d89608861d1d4cb87 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 19:55:12 +0000 Subject: [PATCH 16/16] Deduplicate CoerceUnsized and DispatchFromDyn impl errors --- .../src/coherence/builtin.rs | 16 ++++-- .../deriving/deriving-coerce-pointee-neg.rs | 3 -- .../deriving-coerce-pointee-neg.stderr | 49 +++---------------- 3 files changed, 19 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 9d6bb1cf6bffd..cee2f487639db 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -195,8 +195,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E // Just compute this for the side-effects, in particular reporting // errors; other parts of the code may demand it for the info of // course. - let span = tcx.def_span(impl_did); - tcx.at(span).ensure_ok().coerce_unsized_info(impl_did) + tcx.ensure_ok().coerce_unsized_info(impl_did) } fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool { @@ -218,13 +217,24 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); let source = trait_ref.self_ty(); - assert!(!source.has_escaping_bound_vars()); let target = { assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait); trait_ref.args.type_at(1) }; + // Check `CoercePointee` impl is WF -- if not, then there's no reason to report + // redundant errors for `DispatchFromDyn`. This is best effort, though. + let mut res = Ok(()); + tcx.for_each_relevant_impl( + tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)), + source, + |impl_def_id| { + res = res.and(tcx.ensure_ok().coerce_unsized_info(impl_def_id)); + }, + ); + res?; + debug!("visit_implementation_of_dispatch_from_dyn: {:?} -> {:?}", source, target); let param_env = tcx.param_env(impl_did); diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.rs b/tests/ui/deriving/deriving-coerce-pointee-neg.rs index e660e7baacb50..2713366945e9a 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.rs +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.rs @@ -145,7 +145,6 @@ struct TryToWipeRepr<'a, #[pointee] T: ?Sized> { #[repr(transparent)] #[derive(CoercePointee)] //~^ ERROR for `RcWithId` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box)>` -//~| ERROR for `RcWithId` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box)>` struct RcWithId { inner: std::rc::Rc<(i32, Box)>, } @@ -153,7 +152,6 @@ struct RcWithId { #[repr(transparent)] #[derive(CoercePointee)] //~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced -//~| ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced struct MoreThanOneField { //~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2 inner1: Box, @@ -165,7 +163,6 @@ struct NotCoercePointeeData(T); #[repr(transparent)] #[derive(CoercePointee)] //~^ ERROR for `UsingNonCoercePointeeData` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData` -//~| ERROR for `UsingNonCoercePointeeData` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData` struct UsingNonCoercePointeeData(NotCoercePointeeData); fn main() {} diff --git a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr index e346d13ff5c08..d3d731320781b 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-neg.stderr +++ b/tests/ui/deriving/deriving-coerce-pointee-neg.stderr @@ -118,43 +118,6 @@ error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr( LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: for `RcWithId` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `Rc<(i32, Box)>` - --> $DIR/deriving-coerce-pointee-neg.rs:146:10 - | -LL | #[derive(CoercePointee)] - | ^^^^^^^^^^^^^ -... -LL | inner: std::rc::Rc<(i32, Box)>, - | --------------------------------- `Rc<(i32, Box)>` must be a pointer, reference, or smart pointer that is allowed to be unsized - | - = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced - --> $DIR/deriving-coerce-pointee-neg.rs:154:10 - | -LL | #[derive(CoercePointee)] - | ^^^^^^^^^^^^^ - | -note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced - --> $DIR/deriving-coerce-pointee-neg.rs:159:5 - | -LL | inner1: Box, - | ^^^^^^^^^^^^^^ -LL | inner2: Box, - | ^^^^^^^^^^^^^^ - = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: for `UsingNonCoercePointeeData` to have a valid implementation of `DispatchFromDyn`, it must be possible to coerce the field of type `NotCoercePointeeData` - --> $DIR/deriving-coerce-pointee-neg.rs:166:10 - | -LL | #[derive(CoercePointee)] - | ^^^^^^^^^^^^^ -... -LL | struct UsingNonCoercePointeeData(NotCoercePointeeData); - | ----------------------- `NotCoercePointeeData` must be a pointer, reference, or smart pointer that is allowed to be unsized - | - = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) - error: for `RcWithId` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box)>` --> $DIR/deriving-coerce-pointee-neg.rs:146:10 | @@ -167,13 +130,13 @@ LL | inner: std::rc::Rc<(i32, Box)>, = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced - --> $DIR/deriving-coerce-pointee-neg.rs:154:10 + --> $DIR/deriving-coerce-pointee-neg.rs:153:10 | LL | #[derive(CoercePointee)] | ^^^^^^^^^^^^^ | note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced - --> $DIR/deriving-coerce-pointee-neg.rs:159:5 + --> $DIR/deriving-coerce-pointee-neg.rs:157:5 | LL | inner1: Box, | ^^^^^^^^^^^^^^ @@ -182,18 +145,18 @@ LL | inner2: Box, = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) error: for `UsingNonCoercePointeeData` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData` - --> $DIR/deriving-coerce-pointee-neg.rs:166:10 + --> $DIR/deriving-coerce-pointee-neg.rs:164:10 | LL | #[derive(CoercePointee)] | ^^^^^^^^^^^^^ -... +LL | LL | struct UsingNonCoercePointeeData(NotCoercePointeeData); | ----------------------- `NotCoercePointeeData` must be a pointer, reference, or smart pointer that is allowed to be unsized | = note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 - --> $DIR/deriving-coerce-pointee-neg.rs:157:1 + --> $DIR/deriving-coerce-pointee-neg.rs:155:1 | LL | struct MoreThanOneField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 @@ -203,7 +166,7 @@ LL | inner1: Box, LL | inner2: Box, | -------------- this field has non-zero size or requires alignment -error: aborting due to 24 previous errors +error: aborting due to 21 previous errors Some errors have detailed explanations: E0375, E0392, E0690, E0802. For more information about an error, try `rustc --explain E0375`.