Skip to content

Commit 3deb5c2

Browse files
authored
Rollup merge of #134744 - compiler-errors:transmute-non-wf, r=lcnr
Don't ice on bad transmute in typeck in new solver Old trait solver ends up getting its infcx tainted because we try to normalize the type, but the new trait solver doesn't. This means we try to compute the stalled transmute obligations, which tries to normalize a type an ICEs. Let's make this a delayed bug. r? lcnr
2 parents 65f35be + 96285bd commit 3deb5c2

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

compiler/rustc_hir_typeck/src/intrinsicck.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,25 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
4040
}
4141

4242
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
43+
/// FIXME: Move this check out of typeck, since it'll easily cycle when revealing opaques,
44+
/// and we shouldn't need to check anything here if the typeck results are tainted.
4345
pub(crate) fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
4446
let tcx = self.tcx;
4547
let dl = &tcx.data_layout;
4648
let span = tcx.hir().span(hir_id);
4749
let normalize = |ty| {
4850
let ty = self.resolve_vars_if_possible(ty);
49-
self.tcx.normalize_erasing_regions(self.typing_env(self.param_env), ty)
51+
if let Ok(ty) =
52+
self.tcx.try_normalize_erasing_regions(self.typing_env(self.param_env), ty)
53+
{
54+
ty
55+
} else {
56+
Ty::new_error_with_message(
57+
tcx,
58+
span,
59+
"tried to normalize non-wf type in check_transmute",
60+
)
61+
}
5062
};
5163
let from = normalize(from);
5264
let to = normalize(to);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: -Znext-solver
2+
3+
trait Trait<'a> {
4+
type Assoc;
5+
}
6+
7+
fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
8+
//~^ ERROR the trait bound `for<'a> (): Trait<'a>` is not satisfied
9+
//~| ERROR the trait bound `for<'a> (): Trait<'a>` is not satisfied
10+
//~| ERROR the trait bound `for<'a> (): Trait<'a>` is not satisfied
11+
unsafe { std::mem::transmute::<_, ()>(x); }
12+
//~^ ERROR the trait bound `for<'a> (): Trait<'a>` is not satisfied
13+
//~| ERROR the trait bound `for<'a> (): Trait<'a>` is not satisfied
14+
//~| ERROR the trait bound `for<'a> (): Trait<'a>` is not satisfied
15+
}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
2+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:11
3+
|
4+
LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
6+
|
7+
help: this trait has no implementations, consider adding one
8+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
9+
|
10+
LL | trait Trait<'a> {
11+
| ^^^^^^^^^^^^^^^
12+
13+
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
14+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:8
15+
|
16+
LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
17+
| ^ the trait `for<'a> Trait<'a>` is not implemented for `()`
18+
|
19+
help: this trait has no implementations, consider adding one
20+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
21+
|
22+
LL | trait Trait<'a> {
23+
| ^^^^^^^^^^^^^^^
24+
25+
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
26+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:11:14
27+
|
28+
LL | unsafe { std::mem::transmute::<_, ()>(x); }
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
30+
|
31+
help: this trait has no implementations, consider adding one
32+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
33+
|
34+
LL | trait Trait<'a> {
35+
| ^^^^^^^^^^^^^^^
36+
37+
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
38+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:11:36
39+
|
40+
LL | unsafe { std::mem::transmute::<_, ()>(x); }
41+
| ^ the trait `for<'a> Trait<'a>` is not implemented for `()`
42+
|
43+
help: this trait has no implementations, consider adding one
44+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
45+
|
46+
LL | trait Trait<'a> {
47+
| ^^^^^^^^^^^^^^^
48+
49+
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
50+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:11:43
51+
|
52+
LL | unsafe { std::mem::transmute::<_, ()>(x); }
53+
| ^ the trait `for<'a> Trait<'a>` is not implemented for `()`
54+
|
55+
help: this trait has no implementations, consider adding one
56+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
57+
|
58+
LL | trait Trait<'a> {
59+
| ^^^^^^^^^^^^^^^
60+
61+
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
62+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:1
63+
|
64+
LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
66+
|
67+
help: this trait has no implementations, consider adding one
68+
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
69+
|
70+
LL | trait Trait<'a> {
71+
| ^^^^^^^^^^^^^^^
72+
73+
error: aborting due to 6 previous errors
74+
75+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)