Skip to content

Commit a1f20f1

Browse files
committed
Properly normalize types in bck when checking pointer casts
1 parent 9ef533e commit a1f20f1

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -2320,8 +2320,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23202320
let cast_ty_to = CastTy::from_ty(*ty);
23212321
match (cast_ty_from, cast_ty_to) {
23222322
(Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
2323-
let src_tail = tcx.struct_tail_without_normalization(src.ty);
2324-
let dst_tail = tcx.struct_tail_without_normalization(dst.ty);
2323+
let mut normalize = |t| self.normalize(t, location);
2324+
let src_tail =
2325+
tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ());
2326+
let dst_tail =
2327+
tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ());
23252328

23262329
// This checks (lifetime part of) vtable validity for pointer casts,
23272330
// which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//@ check-fail
2+
//
3+
// Make sure we can't trick the compiler by using a projection.
4+
5+
trait Cat<'a> {}
6+
impl Cat<'_> for () {}
7+
8+
trait Id {
9+
type Id: ?Sized;
10+
}
11+
impl<T: ?Sized> Id for T {
12+
type Id = T;
13+
}
14+
15+
struct S<T: ?Sized> {
16+
tail: <T as Id>::Id,
17+
}
18+
19+
fn m<'a>() {
20+
let unsend: *const dyn Cat<'a> = &();
21+
let _send = unsend as *const S<dyn Cat<'static>>;
22+
//~^ error: lifetime may not live long enough
23+
}
24+
25+
fn main() {
26+
m();
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:21:17
3+
|
4+
LL | fn m<'a>() {
5+
| -- lifetime `'a` defined here
6+
LL | let unsend: *const dyn Cat<'a> = &();
7+
LL | let _send = unsend as *const S<dyn Cat<'static>>;
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
9+
|
10+
= note: requirement occurs because of the type `S<dyn Cat<'_>>`, which makes the generic argument `dyn Cat<'_>` invariant
11+
= note: the struct `S<T>` is invariant over the parameter `T`
12+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
13+
14+
error: aborting due to 1 previous error
15+

0 commit comments

Comments
 (0)