diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index c7ed6e6110fab..d77c3a277bfe8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -363,6 +363,11 @@ fn resolve_associated_item<'tcx>( tcx.item_name(trait_item_id) ), } + } else if tcx.is_lang_item(trait_ref.def_id, LangItem::TransmuteTrait) { + let name = tcx.item_name(trait_item_id); + assert_eq!(name, sym::transmute); + let args = tcx.erase_regions(rcvr_args); + Some(ty::Instance::new(trait_item_id, args)) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) } diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index ea73c5b80ba44..62d454a5289b1 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -1,10 +1,88 @@ use crate::marker::{ConstParamTy_, UnsizedConstParamTy}; -/// Are values of a type transmutable into values of another type? +/// Marks that `Src` is transmutable into `Self`. /// -/// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of -/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`, -/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied. +/// # Implementation +/// +/// This trait cannot be implemented explicitly. It is implemented on-the-fly by +/// the compiler for all types `Src` and `Self` such that, given a set of safety +/// obligations on the programmer (see [`Assume`]), the compiler has proved that +/// the bits of a value of type `Src` can be soundly reinterpreted as a `Self`. +/// +/// # Safety +/// +/// If `Dst: BikeshedIntrinsicFrom`, the compiler guarantees +/// that `Src` is soundly *union-transmutable* into a value of type `Dst`, +/// provided that the programmer has guaranteed that the given +/// [`ASSUMPTIONS`](Assume) are satisfied. +/// +/// A union-transmute is any bit-reinterpretation conversion in the form of: +/// +/// ```rust +/// pub unsafe fn transmute_via_union(src: Src) -> Dst { +/// use core::mem::ManuallyDrop; +/// +/// #[repr(C)] +/// union Transmute { +/// src: ManuallyDrop, +/// dst: ManuallyDrop, +/// } +/// +/// let transmute = Transmute { +/// src: ManuallyDrop::new(src), +/// }; +/// +/// let dst = transmute.dst; +/// +/// ManuallyDrop::into_inner(dst) +/// } +/// ``` +/// +/// Note that this construction is more permissive than +/// [`mem::transmute_copy`](super::transmute_copy); union-transmutes permit +/// conversions that extend the bits of `Src` with trailing padding to fill +/// trailing uninitialized bytes of `Self`; e.g.: +/// +#[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] +#[cfg_attr(not(bootstrap), doc = "```rust")] +/// #![feature(transmutability)] +/// +/// use core::mem::{Assume, BikeshedIntrinsicFrom}; +/// +/// let src = 42u8; // size = 1 +/// +/// #[repr(C, align(2))] +/// struct Dst(u8); // size = 2 +// +/// let _ = unsafe { +/// >::transmute(src) +/// }; +/// ``` +/// +/// # Caveats +/// +/// ## Portability +/// +/// Implementations of this trait do not provide any guarantee of portability +/// across toolchains, targets or compilations. This trait may be implemented +/// for certain combinations of `Src`, `Self` and `ASSUME` on some toolchains, +/// targets or compilations, but not others. For example, if the layouts of +/// `Src` or `Self` are non-deterministic, the presence or absence of an +/// implementation of this trait may also be non-deterministic. Even if `Src` +/// and `Self` have deterministic layouts (e.g., they are `repr(C)` structs), +/// Rust does not specify the alignments of its primitive integer types, and +/// layouts that involve these types may vary across toolchains, targets or +/// compilations. +/// +/// ## Stability +/// +/// Implementations of this trait do not provide any guarantee of SemVer +/// stability across the crate versions that define the `Src` and `Self` types. +/// If SemVer stability is crucial to your application, you must consult the +/// documentation of `Src` and `Self`s' defining crates. Note that the presence +/// of `repr(C)`, alone, does not carry a safety invariant of SemVer stability. +/// Furthermore, stability does not imply portability. For example, the size of +/// `usize` is stable, but not portable. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_trait"] #[rustc_deny_explicit_impl(implement_via_object = false)] @@ -13,28 +91,207 @@ pub unsafe trait BikeshedIntrinsicFrom Self + where + Src: Sized, + Self: Sized, + { + use super::ManuallyDrop; + + #[repr(C)] + union Transmute { + src: ManuallyDrop, + dst: ManuallyDrop, + } + + let transmute = Transmute { src: ManuallyDrop::new(src) }; + + // SAFETY: It is safe to reinterpret the bits of `src` as a value of + // type `Self`, because, by combination of invariant on this trait and + // contract on the caller, `src` has been proven to satisfy both the + // language and library invariants of `Self`. For all invariants not + // `ASSUME`'d by the caller, the safety obligation is supplied by the + // compiler. Conversely, for all invariants `ASSUME`'d by the caller, + // the safety obligation is supplied by contract on the caller. + let dst = unsafe { transmute.dst }; + + ManuallyDrop::into_inner(dst) + } } -/// What transmutation safety conditions shall the compiler assume that *you* are checking? +/// Configurable proof assumptions of [`BikeshedIntrinsicFrom`]. +/// +/// When `false`, the respective proof obligation belongs to the compiler. When +/// `true`, the onus of the safety proof belongs to the programmer. +/// [`BikeshedIntrinsicFrom`]. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_opts"] #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct Assume { - /// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that - /// destination referents do not have stricter alignment requirements than source referents. + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that might violate the the alignment requirements of + /// references; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")] + /// #![feature(transmutability)] + /// use core::mem::{align_of, BikeshedIntrinsicFrom}; + /// + /// assert_eq!(align_of::<[u8; 2]>(), 1); + /// assert_eq!(align_of::(), 2); + /// + /// let src: &[u8; 2] = &[0xFF, 0xFF]; + /// + /// // SAFETY: No safety obligations. + /// let dst: &u16 = unsafe { + /// <_ as BikeshedIntrinsicFrom<_>>::transmute(src) + /// }; + /// ``` + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that references in the transmuted value satisfy the alignment + /// requirements of their referent types; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(pointer_is_aligned_to, transmutability)] + /// use core::mem::{align_of, Assume, BikeshedIntrinsicFrom}; + /// + /// let src: &[u8; 2] = &[0xFF, 0xFF]; + /// + /// let maybe_dst: Option<&u16> = if <*const _>::is_aligned_to(src, align_of::()) { + /// // SAFETY: We have checked above that the address of `src` satisfies the + /// // alignment requirements of `u16`. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { Assume::ALIGNMENT }>>::transmute(src) + /// }) + /// } else { + /// None + /// }; + /// + /// assert!(matches!(maybe_dst, Some(&u16::MAX) | None)); + /// ``` pub alignment: bool, - /// When `true`, the compiler assume that *you* are ensuring that lifetimes are not extended in a manner - /// that violates Rust's memory model. + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that extend the lifetimes of references. + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that references in the transmuted value do not outlive their referents. pub lifetimes: bool, - /// When `true`, the compiler assumes that *you* have ensured that no - /// unsoundness will arise from violating the safety invariants of the - /// destination type (and sometimes of the source type, too). + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that might violate the library safety invariants of the + /// destination type; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")] + /// #![feature(transmutability)] + /// use core::mem::BikeshedIntrinsicFrom; + /// + /// let src: u8 = 3; + /// + /// struct EvenU8 { + /// // SAFETY: `val` must be an even number. + /// val: u8, + /// } + /// + /// // SAFETY: No safety obligations. + /// let dst: EvenU8 = unsafe { + /// <_ as BikeshedIntrinsicFrom<_>>::transmute(src) + /// }; + /// ``` + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that undefined behavior does not arise from using the transmuted value; + /// e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(transmutability)] + /// use core::mem::{Assume, BikeshedIntrinsicFrom}; + /// + /// let src: u8 = 42; + /// + /// struct EvenU8 { + /// // SAFETY: `val` must be an even number. + /// val: u8, + /// } + /// + /// let maybe_dst: Option = if src % 2 == 0 { + /// // SAFETY: We have checked above that the value of `src` is even. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { Assume::SAFETY }>>::transmute(src) + /// }) + /// } else { + /// None + /// }; + /// + /// assert!(matches!(maybe_dst, Some(EvenU8 { val: 42 }))); + /// ``` pub safety: bool, - /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid - /// instance of the destination type. + /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for + /// transmutations that might violate the language-level bit-validity + /// invariant of the destination type; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```compile_fail,E0277")] + /// #![feature(transmutability)] + /// use core::mem::BikeshedIntrinsicFrom; + /// + /// let src: u8 = 3; + /// + /// // SAFETY: No safety obligations. + /// let dst: bool = unsafe { + /// <_ as BikeshedIntrinsicFrom<_>>::transmute(src) + /// }; + /// ``` + /// + /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured + /// that the value being transmuted is a bit-valid instance of the + /// transmuted value; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(transmutability)] + /// use core::mem::{Assume, BikeshedIntrinsicFrom}; + /// + /// let src: u8 = 1; + /// + /// let maybe_dst: Option = if src == 0 || src == 1 { + /// // SAFETY: We have checked above that the value of `src` is a bit-valid + /// // instance of `bool`. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { Assume::VALIDITY }>>::transmute(src) + /// }) + /// } else { + /// None + /// }; + /// + /// assert_eq!(maybe_dst, Some(true)); + /// ``` pub validity: bool, } @@ -44,29 +301,87 @@ impl ConstParamTy_ for Assume {} impl UnsizedConstParamTy for Assume {} impl Assume { - /// Do not assume that *you* have ensured any safety properties are met. + /// With this, [`BikeshedIntrinsicFrom`] does not assume you have ensured + /// any safety obligations are met, and relies only upon its own analysis to + /// (dis)prove transmutability. #[unstable(feature = "transmutability", issue = "99571")] pub const NOTHING: Self = Self { alignment: false, lifetimes: false, safety: false, validity: false }; - /// Assume only that alignment conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that references in the transmuted value satisfy the alignment + /// requirements of their referent types. See [`Assume::alignment`] for + /// examples. #[unstable(feature = "transmutability", issue = "99571")] pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING }; - /// Assume only that lifetime conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that references in the transmuted value do not outlive their referents. + /// See [`Assume::lifetimes`] for examples. #[unstable(feature = "transmutability", issue = "99571")] pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING }; - /// Assume only that safety conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that undefined behavior does not arise from using the transmuted value. + /// See [`Assume::safety`] for examples. #[unstable(feature = "transmutability", issue = "99571")] pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING }; - /// Assume only that dynamically-satisfiable validity conditions are met. + /// With this, [`BikeshedIntrinsicFrom`] assumes only that you have ensured + /// that the value being transmuted is a bit-valid instance of the + /// transmuted value. See [`Assume::validity`] for examples. #[unstable(feature = "transmutability", issue = "99571")] pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING }; - /// Assume both `self` and `other_assumptions`. + /// Combine the assumptions of `self` and `other_assumptions`. + /// + /// This is especially useful for extending [`Assume`] in generic contexts; + /// e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] #[unstable(feature = "transmutability", issue = "99571")] + /// #![feature( + /// adt_const_params, + /// generic_const_exprs, + /// pointer_is_aligned_to, + /// transmutability, + /// )] + /// #![allow(incomplete_features)] + /// use core::mem::{align_of, Assume, BikeshedIntrinsicFrom}; + /// + /// /// Attempts to transmute `src` to `&Dst`. + /// /// + /// /// Returns `None` if `src` violates the alignment requirements of `&Dst`. + /// /// + /// /// # Safety + /// /// + /// /// The caller guarantees that the obligations required by `ASSUME`, except + /// /// alignment, are satisfied. + /// unsafe fn try_transmute_ref<'a, Src, Dst, const ASSUME: Assume>(src: &'a Src) -> Option<&'a Dst> + /// where + /// &'a Dst: BikeshedIntrinsicFrom<&'a Src, { ASSUME.and(Assume::ALIGNMENT) }>, + /// { + /// if <*const _>::is_aligned_to(src, align_of::()) { + /// // SAFETY: By the above dynamic check, we have ensured that the address + /// // of `src` satisfies the alignment requirements of `&Dst`. By contract + /// // on the caller, the safety obligations required by `ASSUME` have also + /// // been satisfied. + /// Some(unsafe { + /// <_ as BikeshedIntrinsicFrom<_, { ASSUME.and(Assume::ALIGNMENT) }>>::transmute(src) + /// }) + /// } else { + /// None + /// } + /// } + /// + /// let src: &[u8; 2] = &[0xFF, 0xFF]; + /// + /// // SAFETY: No safety obligations. + /// let maybe_dst: Option<&u16> = unsafe { + /// try_transmute_ref::<_, _, { Assume::NOTHING }>(src) + /// }; + ///``` pub const fn and(self, other_assumptions: Self) -> Self { Self { alignment: self.alignment || other_assumptions.alignment, @@ -76,7 +391,21 @@ impl Assume { } } - /// Assume `self`, excepting `other_assumptions`. + /// Remove `other_assumptions` the obligations of `self`; e.g.: + /// + #[cfg_attr(bootstrap, doc = "```rust,ignore not runnable on bootstrap")] + #[cfg_attr(not(bootstrap), doc = "```rust")] + /// #![feature(transmutability)] + /// use core::mem::Assume; + /// + /// let assumptions = Assume::ALIGNMENT.and(Assume::SAFETY); + /// let to_be_removed = Assume::SAFETY.and(Assume::VALIDITY); + /// + /// assert_eq!( + /// assumptions.but_not(to_be_removed), + /// Assume::ALIGNMENT, + /// ); + /// ``` #[unstable(feature = "transmutability", issue = "99571")] pub const fn but_not(self, other_assumptions: Self) -> Self { Self { diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir index e8ad5cd8d16a8..293aa37944dd2 100644 --- a/tests/mir-opt/issue_72181_1.main.built.after.mir +++ b/tests/mir-opt/issue_72181_1.main.built.after.mir @@ -19,7 +19,7 @@ fn main() -> () { StorageLive(_2); StorageLive(_3); _3 = (); - _2 = transmute::<(), Void>(move _3) -> bb4; + _2 = std::intrinsics::transmute::<(), Void>(move _3) -> bb4; } bb1: { diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff index 71e84fdd8816e..b1104c70e4696 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as i8 (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff index 71e84fdd8816e..b1104c70e4696 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as i8 (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff index 37232b826c129..169e48a31ddb9 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as *const T (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff index 37232b826c129..169e48a31ddb9 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; +- _0 = std::intrinsics::transmute::<&T, *const T>(move _2) -> [return: bb1, unwind unreachable]; + _0 = move _2 as *const T (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff index 8ac70f99ad2f0..7098b4d316882 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff @@ -11,7 +11,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as std::boxed::Box (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff index 8ac70f99ad2f0..7098b4d316882 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -11,7 +11,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::>(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as std::boxed::Box (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff index c2c4ec0003c26..06225fffd7c2d 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &mut Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff index c2c4ec0003c26..06225fffd7c2d 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &mut Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff index 1b516a1f53b39..dd6ab3a9c97e5 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff index 1b516a1f53b39..dd6ab3a9c97e5 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -10,7 +10,7 @@ bb0: { StorageLive(_1); -- _1 = transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; +- _1 = std::intrinsics::transmute::(const 1_usize) -> [return: bb1, unwind unreachable]; + _1 = const 1_usize as &Never (Transmute); + goto -> bb1; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff index eab969e9fe5bb..6571f3d9db81a 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<(), Never>(move _2) -> unwind unreachable; +- _0 = std::intrinsics::transmute::<(), Never>(move _2) -> unwind unreachable; + _0 = move _2 as Never (Transmute); + unreachable; } diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff index eab969e9fe5bb..6571f3d9db81a 100644 --- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff +++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff @@ -9,7 +9,7 @@ bb0: { StorageLive(_2); _2 = copy _1; -- _0 = transmute::<(), Never>(move _2) -> unwind unreachable; +- _0 = std::intrinsics::transmute::<(), Never>(move _2) -> unwind unreachable; + _0 = move _2 as Never (Transmute); + unreachable; } diff --git a/tests/ui/closures/coerce-unsafe-to-closure.stderr b/tests/ui/closures/coerce-unsafe-to-closure.stderr index cb718ca160f8b..2538fc0361c37 100644 --- a/tests/ui/closures/coerce-unsafe-to-closure.stderr +++ b/tests/ui/closures/coerce-unsafe-to-closure.stderr @@ -1,4 +1,4 @@ -error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` +error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` --> $DIR/coerce-unsafe-to-closure.rs:2:44 | LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); @@ -6,7 +6,7 @@ LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); | | | required by a bound introduced by this call | - = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` + = help: the trait `FnOnce(&str)` is not implemented for fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` = note: unsafe function cannot be called generically without an unsafe block note: required by a bound in `Option::::map` --> $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr index 0119a1a6650d0..21b7bf4e1cb83 100644 --- a/tests/ui/intrinsics/reify-intrinsic.stderr +++ b/tests/ui/intrinsics/reify-intrinsic.stderr @@ -7,9 +7,9 @@ LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::tr | expected due to this | = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(isize) -> usize` - found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` + found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` -error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid +error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid --> $DIR/reify-intrinsic.rs:11:13 | LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;