about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits/vtable.rs
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-07-17 11:48:22 +0200
committerRalf Jung <post@ralfj.de>2024-07-18 11:41:10 +0200
commita7b80819e9c7c9fcc822d2e0cb2dfb4426a9a911 (patch)
tree829e6e6002a1d887a646f45db4145ea9b71faa15 /compiler/rustc_trait_selection/src/traits/vtable.rs
parent4cd8dc63353a9859e3e3c2d5296024c810fc0923 (diff)
downloadrust-a7b80819e9c7c9fcc822d2e0cb2dfb4426a9a911.tar.gz
rust-a7b80819e9c7c9fcc822d2e0cb2dfb4426a9a911.zip
interpret: add sanity check in dyn upcast to double-check what codegen does
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/vtable.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs20
1 files changed, 12 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index 8f56f9c0f3e..4645d828461 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -364,7 +364,9 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
 }
 
 /// Given a `dyn Subtrait` and `dyn Supertrait` trait object, find the slot of
-/// // the trait vptr in the subtrait's vtable.
+/// the trait vptr in the subtrait's vtable.
+///
+/// A return value of `None` means that the original vtable can be reused.
 pub(crate) fn supertrait_vtable_slot<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: (
@@ -373,20 +375,22 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
     ),
 ) -> Option<usize> {
     debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param());
-
     let (source, target) = key;
-    let ty::Dynamic(source, _, _) = *source.kind() else {
+
+    // If the target principal is `None`, we can just return `None`.
+    let ty::Dynamic(target, _, _) = *target.kind() else {
         bug!();
     };
-    let source_principal = tcx
-        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
+    let target_principal = tcx
+        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal()?)
         .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
 
-    let ty::Dynamic(target, _, _) = *target.kind() else {
+    // Given that we have a target principal, it is a bug for there not to be a source principal.
+    let ty::Dynamic(source, _, _) = *source.kind() else {
         bug!();
     };
-    let target_principal = tcx
-        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal().unwrap())
+    let source_principal = tcx
+        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
         .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
 
     let vtable_segment_callback = {