From 5b1a2b8712887fff7e0295d4e87aac24ea73797d Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Tue, 1 Oct 2024 20:52:17 +0000 Subject: [PATCH 1/2] TransmuteFrom: Gracefully handle unnormalized types and normalization errors Fixes #130413 --- .../traits/fulfillment_errors.rs | 8 +++++ .../src/error_reporting/traits/mod.rs | 1 + compiler/rustc_transmute/src/layout/tree.rs | 5 +-- tests/ui/transmutability/assoc-bound.rs | 25 +++++++++++++++ tests/ui/transmutability/assoc-bound.stderr | 31 +++++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 tests/ui/transmutability/assoc-bound.rs create mode 100644 tests/ui/transmutability/assoc-bound.stderr 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 34a0f182ab45f..f494d9637f324 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, @@ -2221,6 +2224,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> GetSafeTransmuteErrorAndReason { use rustc_transmute::Answer; + 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)); @@ -2243,6 +2250,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/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`. From bc5f9520c117b372b7ad7326fda1252cd9da3f4e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 3 Oct 2024 15:19:23 -0400 Subject: [PATCH 2/2] Remove crashes, add comment --- .../traits/fulfillment_errors.rs | 2 ++ tests/crashes/125881.rs | 8 ----- tests/crashes/126377.rs | 29 ------------------- tests/crashes/130413.rs | 17 ----------- 4 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 tests/crashes/125881.rs delete mode 100644 tests/crashes/126377.rs delete mode 100644 tests/crashes/130413.rs 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 f494d9637f324..e2d067e012c77 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 @@ -2224,6 +2224,8 @@ 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; } 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; -}