1
Fork 0

Refactor part of codegen_call_terminator

This commit is contained in:
Eric Holk 2022-08-22 11:25:56 -07:00
parent e0dc8d7801
commit b562f95963

View file

@ -798,58 +798,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let mut op = self.codegen_operand(&mut bx, arg); let mut op = self.codegen_operand(&mut bx, arg);
if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) { if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
if let Pair(..) = op.val { match op.val {
// In the case of Rc<Self>, we need to explicitly pass a Pair(data_ptr, meta) => {
// *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack // In the case of Rc<Self>, we need to explicitly pass a
// that is understood elsewhere in the compiler as a method on // *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
// `dyn Trait`. // that is understood elsewhere in the compiler as a method on
// To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until // `dyn Trait`.
// we get a value of a built-in pointer type // To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() // we get a value of a built-in pointer type
&& !op.layout.ty.is_region_ptr() 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr()
{ && !op.layout.ty.is_region_ptr()
for i in 0..op.layout.fields.count() { {
let field = op.extract_field(&mut bx, i); for i in 0..op.layout.fields.count() {
if !field.layout.is_zst() { let field = op.extract_field(&mut bx, i);
// we found the one non-zero-sized field that is allowed if !field.layout.is_zst() {
// now find *its* non-zero-sized field, or stop if it's a // we found the one non-zero-sized field that is allowed
// pointer // now find *its* non-zero-sized field, or stop if it's a
op = field; // pointer
continue 'descend_newtypes; op = field;
continue 'descend_newtypes;
}
} }
span_bug!(span, "receiver has no non-zero-sized fields {:?}", op);
} }
span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
// data pointer and vtable. Look up the method in the vtable, and pass
// the data pointer as the first argument
llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
&mut bx,
meta,
op.layout.ty,
&fn_abi,
));
llargs.push(data_ptr);
continue 'make_args;
} }
Ref(data_ptr, Some(meta), _) => {
// now that we have `*dyn Trait` or `&dyn Trait`, split it up into its // by-value dynamic dispatch
// data pointer and vtable. Look up the method in the vtable, and pass llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
// the data pointer as the first argument &mut bx,
match op.val { meta,
Pair(data_ptr, meta) => { op.layout.ty,
llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( &fn_abi,
&mut bx, ));
meta, llargs.push(data_ptr);
op.layout.ty, continue;
&fn_abi,
));
llargs.push(data_ptr);
continue 'make_args;
}
other => bug!("expected a Pair, got {:?}", other),
} }
} else if let Ref(data_ptr, Some(meta), _) = op.val { _ => span_bug!(span, "can't codegen a virtual call on {:?}", op),
// by-value dynamic dispatch
llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
&mut bx,
meta,
op.layout.ty,
&fn_abi,
));
llargs.push(data_ptr);
continue;
} else {
span_bug!(span, "can't codegen a virtual call on {:?}", op);
} }
} }