Skip to content

Commit 33b4947

Browse files
authored
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`
2 parents 0d65f12 + bc5f952 commit 33b4947

File tree

8 files changed

+70
-56
lines changed

8 files changed

+70
-56
lines changed

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
245245
span, "silent safe transmute error"
246246
);
247247
}
248+
GetSafeTransmuteErrorAndReason::Default => {
249+
(err_msg, None)
250+
}
248251
GetSafeTransmuteErrorAndReason::Error {
249252
err_msg,
250253
safe_transmute_explanation,
@@ -2226,6 +2229,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
22262229
) -> GetSafeTransmuteErrorAndReason {
22272230
use rustc_transmute::Answer;
22282231

2232+
// We don't assemble a transmutability candidate for types that are generic
2233+
// and we should have ambiguity for types that still have non-region infer.
2234+
if obligation.predicate.has_non_region_param() || obligation.has_non_region_infer() {
2235+
return GetSafeTransmuteErrorAndReason::Default;
2236+
}
2237+
22292238
// Erase regions because layout code doesn't particularly care about regions.
22302239
let trait_ref =
22312240
self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
@@ -2248,6 +2257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
22482257

22492258
let dst = trait_ref.args.type_at(0);
22502259
let src = trait_ref.args.type_at(1);
2260+
22512261
let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
22522262

22532263
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub struct ImplCandidate<'tcx> {
4343

4444
enum GetSafeTransmuteErrorAndReason {
4545
Silent,
46+
Default,
4647
Error { err_msg: String, safe_transmute_explanation: Option<String> },
4748
}
4849

Diff for: compiler/rustc_transmute/src/layout/tree.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,11 @@ pub(crate) mod rustc {
195195
impl<'tcx> From<&LayoutError<'tcx>> for Err {
196196
fn from(err: &LayoutError<'tcx>) -> Self {
197197
match err {
198-
LayoutError::Unknown(..) | LayoutError::ReferencesError(..) => Self::UnknownLayout,
198+
LayoutError::Unknown(..)
199+
| LayoutError::ReferencesError(..)
200+
| LayoutError::NormalizationFailure(..) => Self::UnknownLayout,
199201
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
200202
LayoutError::Cycle(err) => Self::TypeError(*err),
201-
err => unimplemented!("{:?}", err),
202203
}
203204
}
204205
}

Diff for: tests/crashes/125881.rs

-8
This file was deleted.

Diff for: tests/crashes/126377.rs

-29
This file was deleted.

Diff for: tests/crashes/130413.rs

-17
This file was deleted.

Diff for: tests/ui/transmutability/assoc-bound.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![crate_type = "lib"]
2+
#![feature(transmutability)]
3+
4+
trait A {
5+
type AssocA;
6+
}
7+
8+
trait B {
9+
type AssocB: std::mem::TransmuteFrom<()>;
10+
}
11+
12+
impl<T> B for (T, u8)
13+
where
14+
T: A,
15+
{
16+
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]
17+
}
18+
19+
20+
impl<T> B for (T, u16)
21+
where
22+
for<'a> &'a i32: A,
23+
{
24+
type AssocB = <&'static i32 as A>::AssocA; //~ERROR: `()` cannot be safely transmuted into `<&i32 as A>::AssocA`
25+
}

Diff for: tests/ui/transmutability/assoc-bound.stderr

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0277]: the trait bound `<T as A>::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not satisfied
2+
--> $DIR/assoc-bound.rs:16:19
3+
|
4+
LL | type AssocB = T::AssocA;
5+
| ^^^^^^^^^ the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `<T as A>::AssocA`
6+
|
7+
note: required by a bound in `B::AssocB`
8+
--> $DIR/assoc-bound.rs:9:18
9+
|
10+
LL | type AssocB: std::mem::TransmuteFrom<()>;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `B::AssocB`
12+
help: consider further restricting the associated type
13+
|
14+
LL | T: A, <T as A>::AssocA: TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>
15+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
17+
error[E0277]: `()` cannot be safely transmuted into `<&i32 as A>::AssocA`
18+
--> $DIR/assoc-bound.rs:24:19
19+
|
20+
LL | type AssocB = <&'static i32 as A>::AssocA;
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<&i32 as A>::AssocA` has an unknown layout
22+
|
23+
note: required by a bound in `B::AssocB`
24+
--> $DIR/assoc-bound.rs:9:18
25+
|
26+
LL | type AssocB: std::mem::TransmuteFrom<()>;
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `B::AssocB`
28+
29+
error: aborting due to 2 previous errors
30+
31+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)