mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Refactor part of codegen_call_terminator
This commit is contained in:
parent
e0dc8d7801
commit
b562f95963
@ -798,58 +798,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let mut op = self.codegen_operand(&mut bx, arg);
|
||||
|
||||
if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
|
||||
if let Pair(..) = op.val {
|
||||
// In the case of Rc<Self>, we need to explicitly pass a
|
||||
// *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
|
||||
// that is understood elsewhere in the compiler as a method on
|
||||
// `dyn Trait`.
|
||||
// To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
|
||||
// we get a value of a built-in pointer type
|
||||
'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);
|
||||
if !field.layout.is_zst() {
|
||||
// we found the one non-zero-sized field that is allowed
|
||||
// now find *its* non-zero-sized field, or stop if it's a
|
||||
// pointer
|
||||
op = field;
|
||||
continue 'descend_newtypes;
|
||||
match op.val {
|
||||
Pair(data_ptr, meta) => {
|
||||
// In the case of Rc<Self>, we need to explicitly pass a
|
||||
// *mut RcBox<Self> with a Scalar (not ScalarPair) ABI. This is a hack
|
||||
// that is understood elsewhere in the compiler as a method on
|
||||
// `dyn Trait`.
|
||||
// To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
|
||||
// we get a value of a built-in pointer type
|
||||
'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);
|
||||
if !field.layout.is_zst() {
|
||||
// we found the one non-zero-sized field that is allowed
|
||||
// now find *its* non-zero-sized field, or stop if it's a
|
||||
// pointer
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
match op.val {
|
||||
Pair(data_ptr, meta) => {
|
||||
llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
|
||||
&mut bx,
|
||||
meta,
|
||||
op.layout.ty,
|
||||
&fn_abi,
|
||||
));
|
||||
llargs.push(data_ptr);
|
||||
continue 'make_args;
|
||||
}
|
||||
other => bug!("expected a Pair, got {:?}", other),
|
||||
Ref(data_ptr, Some(meta), _) => {
|
||||
// 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 if let Ref(data_ptr, Some(meta), _) = op.val {
|
||||
// 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);
|
||||
_ => span_bug!(span, "can't codegen a virtual call on {:?}", op),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user