Rollup merge of #131112 - jswrenn:fix-130413, r=compiler-errors
TransmuteFrom: Gracefully handle unnormalized types and normalization errors ~~Refactor to share code between `TransmuteFrom`'s trait selection and error reporting code paths. Additionally normalizes the source and destination types, and gracefully handles normalization errors.~~ Fixes #130413 r? `@compiler-errors`
This commit is contained in:
commit
33b4947554
@ -245,6 +245,9 @@ pub fn report_selection_error(
|
||||
span, "silent safe transmute error"
|
||||
);
|
||||
}
|
||||
GetSafeTransmuteErrorAndReason::Default => {
|
||||
(err_msg, None)
|
||||
}
|
||||
GetSafeTransmuteErrorAndReason::Error {
|
||||
err_msg,
|
||||
safe_transmute_explanation,
|
||||
@ -2226,6 +2229,12 @@ fn get_safe_transmute_error_and_reason(
|
||||
) -> 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 @@ fn get_safe_transmute_error_and_reason(
|
||||
|
||||
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(
|
||||
|
@ -43,6 +43,7 @@ pub struct ImplCandidate<'tcx> {
|
||||
|
||||
enum GetSafeTransmuteErrorAndReason {
|
||||
Silent,
|
||||
Default,
|
||||
Error { err_msg: String, safe_transmute_explanation: Option<String> },
|
||||
}
|
||||
|
||||
|
@ -195,10 +195,11 @@ pub(crate) enum Err {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|| {}
|
||||
}
|
@ -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::<Src, Dst, {0u8}, false, false, false>();
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//@ known-bug: #130413
|
||||
|
||||
#![feature(transmutability)]
|
||||
trait Aaa {
|
||||
type Y;
|
||||
}
|
||||
|
||||
trait Bbb {
|
||||
type B: std::mem::TransmuteFrom<()>;
|
||||
}
|
||||
|
||||
impl<T> Bbb for T
|
||||
where
|
||||
T: Aaa,
|
||||
{
|
||||
type B = T::Y;
|
||||
}
|
25
tests/ui/transmutability/assoc-bound.rs
Normal file
25
tests/ui/transmutability/assoc-bound.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#![crate_type = "lib"]
|
||||
#![feature(transmutability)]
|
||||
|
||||
trait A {
|
||||
type AssocA;
|
||||
}
|
||||
|
||||
trait B {
|
||||
type AssocB: std::mem::TransmuteFrom<()>;
|
||||
}
|
||||
|
||||
impl<T> B for (T, u8)
|
||||
where
|
||||
T: A,
|
||||
{
|
||||
type AssocB = T::AssocA; //~ERROR: the trait bound `<T as A>::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
|
||||
impl<T> 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`
|
||||
}
|
31
tests/ui/transmutability/assoc-bound.stderr
Normal file
31
tests/ui/transmutability/assoc-bound.stderr
Normal file
@ -0,0 +1,31 @@
|
||||
error[E0277]: the trait bound `<T as A>::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 `<T as A>::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, <T as 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`.
|
Loading…
Reference in New Issue
Block a user