diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 5af117a3f48c4..4bc3fa00d1b84 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -245,6 +245,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span, "silent safe transmute error" ); } + GetSafeTransmuteErrorAndReason::Default => { + (err_msg, None) + } GetSafeTransmuteErrorAndReason::Error { err_msg, safe_transmute_explanation, @@ -2226,6 +2229,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> GetSafeTransmuteErrorAndReason { use rustc_transmute::Answer; + // We don't assemble a transmutability candidate for types that are generic + // and we should have ambiguity for types that still have non-region infer. + if obligation.predicate.has_non_region_param() || obligation.has_non_region_infer() { + return GetSafeTransmuteErrorAndReason::Default; + } + // Erase regions because layout code doesn't particularly care about regions. let trait_ref = self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref)); @@ -2248,6 +2257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let dst = trait_ref.args.type_at(0); let src = trait_ref.args.type_at(1); + let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`"); match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 109bae10b54cc..becc1acfb6641 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -43,6 +43,7 @@ pub struct ImplCandidate<'tcx> { enum GetSafeTransmuteErrorAndReason { Silent, + Default, Error { err_msg: String, safe_transmute_explanation: Option }, } diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 6d5859a5a6563..17eddbfcd7f5e 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -195,10 +195,11 @@ pub(crate) mod rustc { impl<'tcx> From<&LayoutError<'tcx>> for Err { fn from(err: &LayoutError<'tcx>) -> Self { match err { - LayoutError::Unknown(..) | LayoutError::ReferencesError(..) => Self::UnknownLayout, + LayoutError::Unknown(..) + | LayoutError::ReferencesError(..) + | LayoutError::NormalizationFailure(..) => Self::UnknownLayout, LayoutError::SizeOverflow(..) => Self::SizeOverflow, LayoutError::Cycle(err) => Self::TypeError(*err), - err => unimplemented!("{:?}", err), } } } diff --git a/tests/crashes/125881.rs b/tests/crashes/125881.rs deleted file mode 100644 index a38f1891b61d9..0000000000000 --- a/tests/crashes/125881.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: rust-lang/rust#125881 -#![crate_type = "lib"] -#![feature(transmutability)] -#![feature(unboxed_closures,effects)] - -const fn test() -> impl std::mem::TransmuteFrom() { - || {} -} diff --git a/tests/crashes/126377.rs b/tests/crashes/126377.rs deleted file mode 100644 index f6727bcc0a494..0000000000000 --- a/tests/crashes/126377.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ known-bug: rust-lang/rust#126377 - -#![feature(effects)] -#![feature(generic_const_exprs)] - -mod assert { - use std::mem::{Assume, TransmuteFrom}; - - pub fn is_transmutable< - Src, - Dst, - const ASSUME_ALIGNMENT: bool, - const ASSUME_LIFETIMES: bool, - const ASSUME_SAFETY: bool, - const ASSUME_VALIDITY: bool, - >() - where - Dst: TransmuteFrom< - Src, - { } - >, - {} -} - -const fn from_options() -> Assume { - #[repr(C)] struct Src; - #[repr(C)] struct Dst; - assert::is_transmutable::(); -} diff --git a/tests/crashes/130413.rs b/tests/crashes/130413.rs deleted file mode 100644 index 08435ac6450c0..0000000000000 --- a/tests/crashes/130413.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #130413 - -#![feature(transmutability)] -trait Aaa { - type Y; -} - -trait Bbb { - type B: std::mem::TransmuteFrom<()>; -} - -impl Bbb for T -where - T: Aaa, -{ - type B = T::Y; -} diff --git a/tests/ui/transmutability/assoc-bound.rs b/tests/ui/transmutability/assoc-bound.rs new file mode 100644 index 0000000000000..e8a20b45cde34 --- /dev/null +++ b/tests/ui/transmutability/assoc-bound.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] +#![feature(transmutability)] + +trait A { + type AssocA; +} + +trait B { + type AssocB: std::mem::TransmuteFrom<()>; +} + +impl B for (T, u8) +where + T: A, +{ + type AssocB = T::AssocA; //~ERROR: the trait bound `::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not satisfied [E0277] +} + + +impl B for (T, u16) +where + for<'a> &'a i32: A, +{ + type AssocB = <&'static i32 as A>::AssocA; //~ERROR: `()` cannot be safely transmuted into `<&i32 as A>::AssocA` +} diff --git a/tests/ui/transmutability/assoc-bound.stderr b/tests/ui/transmutability/assoc-bound.stderr new file mode 100644 index 0000000000000..08d9089439645 --- /dev/null +++ b/tests/ui/transmutability/assoc-bound.stderr @@ -0,0 +1,31 @@ +error[E0277]: the trait bound `::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not satisfied + --> $DIR/assoc-bound.rs:16:19 + | +LL | type AssocB = T::AssocA; + | ^^^^^^^^^ the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA` + | +note: required by a bound in `B::AssocB` + --> $DIR/assoc-bound.rs:9:18 + | +LL | type AssocB: std::mem::TransmuteFrom<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `B::AssocB` +help: consider further restricting the associated type + | +LL | T: A, ::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }> + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0277]: `()` cannot be safely transmuted into `<&i32 as A>::AssocA` + --> $DIR/assoc-bound.rs:24:19 + | +LL | type AssocB = <&'static i32 as A>::AssocA; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<&i32 as A>::AssocA` has an unknown layout + | +note: required by a bound in `B::AssocB` + --> $DIR/assoc-bound.rs:9:18 + | +LL | type AssocB: std::mem::TransmuteFrom<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `B::AssocB` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.