about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-08-05 14:04:40 -0400
committerMichael Goulet <michael@errs.io>2024-08-05 14:28:06 -0400
commitc6f8672dd5e128766298ed0d53bb32a94188f886 (patch)
tree9160cd0a2db7bd26c19bd2d3604ddc3d54bf4447
parent2b78d920964e1d70927bcd208529bda0e11120d0 (diff)
downloadrust-c6f8672dd5e128766298ed0d53bb32a94188f886.tar.gz
rust-c6f8672dd5e128766298ed0d53bb32a94188f886.zip
Normalize when equating dyn tails in MIR borrowck
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs6
-rw-r--r--tests/crashes/128621-2.rs16
-rw-r--r--tests/ui/cast/dyn-tails-need-normalization.rs (renamed from tests/crashes/128621.rs)4
3 files changed, 9 insertions, 17 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index bbb5daccfd6..b13773ffe14 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2330,10 +2330,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         match (cast_ty_from, cast_ty_to) {
                             (Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => {
                                 let mut normalize = |t| self.normalize(t, location);
+
+                                // N.B. `struct_tail_with_normalize` only "structurally resolves"
+                                // the type. It is not fully normalized, so we have to normalize it
+                                // afterwards.
                                 let src_tail =
                                     tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ());
+                                let src_tail = normalize(src_tail);
                                 let dst_tail =
                                     tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ());
+                                let dst_tail = normalize(dst_tail);
 
                                 // This checks (lifetime part of) vtable validity for pointer casts,
                                 // which is irrelevant when there are aren't principal traits on both sides (aka only auto traits).
diff --git a/tests/crashes/128621-2.rs b/tests/crashes/128621-2.rs
deleted file mode 100644
index b1cdaf94984..00000000000
--- a/tests/crashes/128621-2.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: rust-lang/rust#128621
-
-#![feature(ptr_metadata)]
-use std::{ops::FnMut, ptr::Pointee};
-
-pub type EmplacerFn<'a, T> = dyn for<'b> FnMut(<T as Pointee>::Metadata) + 'a;
-
-pub struct Emplacer<'a, T>(EmplacerFn<'a, T>);
-
-impl<'a, T> Emplacer<'a, T> {
-    pub unsafe fn from_fn<'b>(emplacer_fn: &'b mut EmplacerFn<'a, T>) -> &'b mut Self {
-        unsafe { &mut *((emplacer_fn as *mut EmplacerFn<'a, T>) as *mut Self) }
-    }
-}
-
-pub fn main() {}
diff --git a/tests/crashes/128621.rs b/tests/ui/cast/dyn-tails-need-normalization.rs
index 0a02352236d..719e0e89243 100644
--- a/tests/crashes/128621.rs
+++ b/tests/ui/cast/dyn-tails-need-normalization.rs
@@ -1,4 +1,4 @@
-//@ known-bug: rust-lang/rust#128621
+//@ check-pass
 
 trait Trait {
     type Associated;
@@ -17,3 +17,5 @@ struct Wrap(TraitObject);
 fn cast(x: *mut TraitObject) {
     x as *mut Wrap;
 }
+
+fn main() {}