about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-23 13:52:02 -0400
committerMichael Goulet <michael@errs.io>2024-09-25 11:13:59 -0400
commit6fdc133daad5ea1a2fccd460fd3b65a715f0f272 (patch)
treea96adc0d1d3173d317aee674d3185e169c6e65f0
parent25b66d80911b8c41feef25bac7c8a3c2aa14ebdd (diff)
downloadrust-6fdc133daad5ea1a2fccd460fd3b65a715f0f272.tar.gz
rust-6fdc133daad5ea1a2fccd460fd3b65a715f0f272.zip
Add a debug assertion in codegen that unsize casts of the same principal trait def id are truly NOPs
-rw-r--r--src/unsize.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/unsize.rs b/src/unsize.rs
index 8cfe93b4d9c..339628053a9 100644
--- a/src/unsize.rs
+++ b/src/unsize.rs
@@ -34,7 +34,22 @@ pub(crate) fn unsized_info<'tcx>(
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
             if data_a.principal_def_id() == data_b.principal_def_id() {
-                // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
+                // Codegen takes advantage of the additional assumption, where if the
+                // principal trait def id of what's being casted doesn't change,
+                // then we don't need to adjust the vtable at all. This
+                // corresponds to the fact that `dyn Tr<A>: Unsize<dyn Tr<B>>`
+                // requires that `A = B`; we don't allow *upcasting* objects
+                // between the same trait with different args. If we, for
+                // some reason, were to relax the `Unsize` trait, it could become
+                // unsound, so let's assert here that the trait refs are *equal*.
+                //
+                // We can use `assert_eq` because the binders should have been anonymized,
+                // and because higher-ranked equality now requires the binders are equal.
+                debug_assert_eq!(
+                    data_a.principal(),
+                    data_b.principal(),
+                    "NOP unsize vtable changed principal trait ref: {data_a} -> {data_b}"
+                );
                 return old_info;
             }