Skip to content

Commit 3401d79

Browse files
committed
Fix ICE in transmutability error reporting when type aliases are normalized
1 parent 4742769 commit 3401d79

3 files changed

Lines changed: 84 additions & 5 deletions

File tree

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
257257
match self.get_safe_transmute_error_and_reason(
258258
obligation.clone(),
259259
main_trait_predicate,
260+
root_obligation,
260261
span,
261262
) {
262263
GetSafeTransmuteErrorAndReason::Silent => {
@@ -2797,6 +2798,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27972798
&self,
27982799
obligation: PredicateObligation<'tcx>,
27992800
trait_pred: ty::PolyTraitPredicate<'tcx>,
2801+
root_obligation: &PredicateObligation<'tcx>,
28002802
span: Span,
28012803
) -> GetSafeTransmuteErrorAndReason {
28022804
use rustc_transmute::Answer;
@@ -2913,11 +2915,28 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29132915
safe_transmute_explanation: Some(safe_transmute_explanation),
29142916
}
29152917
}
2916-
// Should never get a Yes at this point! We already ran it before, and did not get a Yes.
2917-
Answer::Yes => span_bug!(
2918-
span,
2919-
"Inconsistent rustc_transmute::is_transmutable(...) result, got Yes",
2920-
),
2918+
// The normalized types pass, but the original check failed.
2919+
// This can happen when type aliases were normalized for diagnostics.
2920+
// Retry with root_obligation's types to get the real error.
2921+
Answer::Yes => {
2922+
if obligation.predicate != root_obligation.predicate {
2923+
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(root_pred)) =
2924+
root_obligation.predicate.kind().skip_binder()
2925+
&& root_pred.def_id() == trait_pred.trait_ref.def_id
2926+
{
2927+
return self.get_safe_transmute_error_and_reason(
2928+
root_obligation.clone(),
2929+
root_obligation.predicate.kind().rebind(root_pred),
2930+
root_obligation,
2931+
span,
2932+
);
2933+
}
2934+
}
2935+
span_bug!(
2936+
span,
2937+
"Inconsistent rustc_transmute::is_transmutable(...) result, got Yes",
2938+
)
2939+
}
29212940
// Reached when a different obligation (namely `Freeze`) causes the
29222941
// transmutability analysis to fail. In this case, silence the
29232942
// transmutability error message in favor of that more specific
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! regression test for https://github.com/rust-lang/rust/issues/151462
2+
//@compile-flags: -Znext-solver=globally
3+
#![feature(lazy_type_alias, transmutability)]
4+
#![allow(incomplete_features)]
5+
mod assert {
6+
use std::mem::{Assume, TransmuteFrom};
7+
8+
pub fn is_maybe_transmutable<Src, Dst>()
9+
where
10+
Src: TransmuteFrom<
11+
Src,
12+
{
13+
Assume {
14+
alignment: true,
15+
lifetimes: true,
16+
safety: true,
17+
validity: true,
18+
}
19+
},
20+
>,
21+
{
22+
}
23+
}
24+
25+
fn test() {
26+
type JustUnit = ();
27+
assert::is_maybe_transmutable::<JustUnit, ()>();
28+
//~^ ERROR `JustUnit` cannot be safely transmuted into `JustUnit`
29+
}
30+
31+
fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0277]: `JustUnit` cannot be safely transmuted into `JustUnit`
2+
--> $DIR/type-alias-normalization.rs:27:37
3+
|
4+
LL | assert::is_maybe_transmutable::<JustUnit, ()>();
5+
| ^^^^^^^^ analyzing the transmutability of `JustUnit` is not yet supported
6+
|
7+
note: required by a bound in `is_maybe_transmutable`
8+
--> $DIR/type-alias-normalization.rs:10:14
9+
|
10+
LL | pub fn is_maybe_transmutable<Src, Dst>()
11+
| --------------------- required by a bound in this function
12+
LL | where
13+
LL | Src: TransmuteFrom<
14+
| ______________^
15+
LL | | Src,
16+
LL | | {
17+
LL | | Assume {
18+
... |
19+
LL | | },
20+
LL | | >,
21+
| |_________^ required by this bound in `is_maybe_transmutable`
22+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
23+
|
24+
LL | fn test() where (): TransmuteFrom<(), Assume { alignment: true, lifetimes: true, safety: true, validity: true }> {
25+
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26+
27+
error: aborting due to 1 previous error
28+
29+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)