diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 59bae7f7e91..7cee9ea3e1d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -907,7 +907,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llargs.push(data_ptr); continue; } - _ => span_bug!(span, "can't codegen a virtual call on {:#?}", op), + Immediate(_) => { + let ty::Ref(_, ty, _) = op.layout.ty.kind() else { + span_bug!(span, "can't codegen a virtual call on {:#?}", op); + }; + if !ty.is_dyn_star() { + span_bug!(span, "can't codegen a virtual call on {:#?}", op); + } + // FIXME(dyn-star): Make sure this is done on a &dyn* receiver + let place = op.deref(bx.cx()); + let data_ptr = place.project_field(&mut bx, 0); + let meta_ptr = place.project_field(&mut bx, 1); + let meta = bx.load_operand(meta_ptr); + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta.immediate(), + op.layout.ty, + &fn_abi, + )); + llargs.push(data_ptr.llval); + continue; + } + _ => { + span_bug!(span, "can't codegen a virtual call on {:#?}", op); + } } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 922891ecc34..b8c4534307c 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -626,7 +626,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } ty::Dynamic(_, _, ty::DynStar) => { - let mut pointer = scalar_unit(Pointer); + let mut pointer = scalar_unit(Int(dl.ptr_sized_integer(), false)); pointer.valid_range_mut().start = 1; let mut vtable = scalar_unit(Pointer); vtable.valid_range_mut().start = 1; @@ -2544,8 +2544,21 @@ where } } - // dyn* (both fields are usize-sized) - ty::Dynamic(_, _, ty::DynStar) => TyMaybeWithLayout::Ty(tcx.types.usize), + ty::Dynamic(_, _, ty::DynStar) => { + if i == 0 { + TyMaybeWithLayout::Ty(tcx.types.usize) + } else if i == 1 { + // FIXME(dyn-star) same FIXME as above applies here too + TyMaybeWithLayout::Ty( + tcx.mk_imm_ref( + tcx.lifetimes.re_static, + tcx.mk_array(tcx.types.usize, 3), + ), + ) + } else { + bug!("no field {i} on dyn*") + } + } ty::Projection(_) | ty::Bound(..)