diff options
| author | Michael Goulet <michael@errs.io> | 2024-09-23 13:52:02 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-09-25 11:13:59 -0400 |
| commit | 3209943604a9b3565a3cef4c43b567f65cfdf192 (patch) | |
| tree | 5872a492b6fc7cd3cb477a6f34d41aea5e79e269 /compiler/rustc_codegen_ssa/src | |
| parent | 8fc8e03150ed69cc37a3e21b319a4d9bf247292f (diff) | |
| download | rust-3209943604a9b3565a3cef4c43b567f65cfdf192.tar.gz rust-3209943604a9b3565a3cef4c43b567f65cfdf192.zip | |
Add a debug assertion in codegen that unsize casts of the same principal trait def id are truly NOPs
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/base.rs | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index fcf48d3e4a3..5c67600e4ee 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -125,8 +125,28 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, '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}" + ); + + // A NOP cast that doesn't actually change anything, let's avoid any + // unnecessary work. This relies on the assumption that if the principal + // traits are equal, then the associated type bounds (`dyn Trait<Assoc=T>`) + // are also equal, which is ensured by the fact that normalization is + // a function and we do not allow overlapping impls. return old_info; } |
