mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Implement by-value trait object method call.
This commit is contained in:
parent
f2ef005d1d
commit
5eceab02ec
@ -305,17 +305,17 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||
// Don't pass the vtable, it's not an argument of the virtual fn.
|
||||
// Instead, pass just the (thin pointer) first field of `*dyn Trait`.
|
||||
if arg_idx == Some(0) {
|
||||
if layout.is_unsized() {
|
||||
unimplemented!("by-value trait object is not \
|
||||
yet implemented in #![feature(unsized_locals)]");
|
||||
}
|
||||
// FIXME(eddyb) `layout.field(cx, 0)` is not enough because e.g.
|
||||
// `Box<dyn Trait>` has a few newtype wrappers around the raw
|
||||
// pointer, so we'd have to "dig down" to find `*dyn Trait`.
|
||||
let pointee = layout.ty.builtin_deref(true)
|
||||
.unwrap_or_else(|| {
|
||||
bug!("FnType::new_vtable: non-pointer self {:?}", layout)
|
||||
}).ty;
|
||||
let pointee = if layout.is_unsized() {
|
||||
layout.ty
|
||||
} else {
|
||||
layout.ty.builtin_deref(true)
|
||||
.unwrap_or_else(|| {
|
||||
bug!("FnType::new_vtable: non-pointer self {:?}", layout)
|
||||
}).ty
|
||||
};
|
||||
let fat_ptr_ty = cx.tcx.mk_mut_ptr(pointee);
|
||||
layout = cx.layout_of(fat_ptr_ty).field(cx, 0);
|
||||
}
|
||||
|
@ -651,6 +651,12 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||
.get_fn(&bx, meta, &fn_ty));
|
||||
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(&bx, meta, &fn_ty));
|
||||
llargs.push(data_ptr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user