Skip to content

Commit ecb5622

Browse files
danielsnMark R. Tuttle
authored andcommitted
Refactor codegen_vtable and vtable_name (rust-lang#24)
Co-authored-by: Mark R. Tuttle <[email protected]>
1 parent 6a4606f commit ecb5622

File tree

2 files changed

+34
-26
lines changed

2 files changed

+34
-26
lines changed

compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -787,34 +787,45 @@ impl<'tcx> GotocCtx<'tcx> {
787787
(vt_size, vt_align)
788788
}
789789

790-
fn codegen_vtable(&mut self, o: &Operand<'tcx>, t: Ty<'tcx>) -> &Symbol {
791-
let (binder_t, underlying_dynamic_type) = match t.kind() {
792-
ty::Ref(_region_t, ty::TyS { kind: ty::Dynamic(binder_t, _), .. }, _) => (binder_t, t),
793-
// For `Box<dyn trait>` generate the vtable for `dyn trait` and not `t`
794-
ty::Adt(adt_def, substs_ref) if adt_def.is_box() => {
795-
let dyn_trait = substs_ref.first().unwrap().expect_ty();
796-
match dyn_trait.kind() {
797-
ty::Dynamic(binder_t, _) => (binder_t, dyn_trait),
798-
_ => {
799-
unreachable!("Cannot codegen_vtable for type: Box<{:?}>", dyn_trait.kind())
800-
}
801-
}
802-
}
803-
_ => unimplemented!("Cannot codegen_vtable for type {:?}", t.kind()),
790+
fn codegen_vtable(&mut self, operand: &Operand<'tcx>, dst_mir_type: Ty<'tcx>) -> &Symbol {
791+
let src_mir_type = self.monomorphize(self.operand_ty(operand));
792+
return self.codegen_vtable_from_types(src_mir_type, dst_mir_type);
793+
}
794+
795+
fn codegen_vtable_from_types(
796+
&mut self,
797+
src_mir_type: Ty<'tcx>,
798+
dst_mir_type: Ty<'tcx>,
799+
) -> &Symbol {
800+
let trait_type = match dst_mir_type.kind() {
801+
// dst is pointer type
802+
ty::Ref(_, pointee_type, ..) => pointee_type,
803+
// dst is box type
804+
ty::Adt(adt_def, adt_subst) if adt_def.is_box() => {
805+
adt_subst.first().unwrap().expect_ty()
806+
}
807+
// dst is dynamic type
808+
ty::Dynamic(..) => dst_mir_type,
809+
_ => unimplemented!("Cannot codegen_vtable for type {:?}", dst_mir_type.kind()),
804810
};
805-
let operand_type = self.monomorphize(self.operand_ty(o));
806-
let operand_name = self.ty_mangled_name(operand_type);
811+
assert!(trait_type.is_trait(), "VTable trait type {} must be a trait type", trait_type);
812+
let binders = match trait_type.kind() {
813+
ty::Dynamic(binders, ..) => binders,
814+
_ => unimplemented!("Cannot codegen_vtable for type {:?}", dst_mir_type.kind()),
815+
};
816+
817+
let src_name = self.ty_mangled_name(src_mir_type);
807818
// name needs to be the same as inserted in typ.rs
808-
let vtable_name = self.vtable_name(underlying_dynamic_type);
809-
let vtable_impl_name = format!("{}_impl_for_{}", vtable_name, operand_name);
819+
let vtable_name = self.vtable_name(trait_type);
820+
let vtable_impl_name = format!("{}_impl_for_{}", vtable_name, src_name);
810821

811822
self.ensure(&vtable_impl_name, |ctx, _| {
812823
// Build the vtable
813824
let drop_irep = ctx.codegen_vtable_drop_in_place();
814-
let (vt_size, vt_align) = ctx.codegen_vtable_size_and_align(&operand_type);
825+
let (vt_size, vt_align) = ctx.codegen_vtable_size_and_align(&src_mir_type);
815826
let mut vtable_fields = vec![drop_irep, vt_size, vt_align];
816-
let trait_ref_t = binder_t.principal().unwrap().with_self_ty(ctx.tcx, operand_type);
817-
let mut methods = ctx.codegen_vtable_methods(trait_ref_t, underlying_dynamic_type);
827+
let concrete_type = binders.principal().unwrap().with_self_ty(ctx.tcx, src_mir_type);
828+
let mut methods = ctx.codegen_vtable_methods(concrete_type, trait_type);
818829
vtable_fields.append(&mut methods);
819830
let vtable = Expr::struct_expr_from_values(
820831
Type::struct_tag(&vtable_name),

compiler/rustc_codegen_llvm/src/gotoc/typ.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,8 @@ impl<'tcx> GotocCtx<'tcx> {
208208
/// Gives the name for a trait.
209209
/// In some cases, we have &T, in other cases T, so normalize.
210210
pub fn normalized_trait_name(&self, t: Ty<'tcx>) -> String {
211-
if let ty::Ref(_region, ty, _mutability) = t.kind() {
212-
self.ty_mangled_name(ty).to_string()
213-
} else {
214-
self.ty_mangled_name(t).to_string()
215-
}
211+
assert!(t.is_trait(), "Type {} must be a trait type (a dynamic type)", t);
212+
self.ty_mangled_name(t).to_string()
216213
}
217214

218215
/// Gives the vtable name for a type.

0 commit comments

Comments
 (0)