Implement by-value trait object method call.
This commit is contained in:
@@ -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.
|
// 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`.
|
// Instead, pass just the (thin pointer) first field of `*dyn Trait`.
|
||||||
if arg_idx == Some(0) {
|
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.
|
// FIXME(eddyb) `layout.field(cx, 0)` is not enough because e.g.
|
||||||
// `Box<dyn Trait>` has a few newtype wrappers around the raw
|
// `Box<dyn Trait>` has a few newtype wrappers around the raw
|
||||||
// pointer, so we'd have to "dig down" to find `*dyn Trait`.
|
// pointer, so we'd have to "dig down" to find `*dyn Trait`.
|
||||||
let pointee = layout.ty.builtin_deref(true)
|
let pointee = if layout.is_unsized() {
|
||||||
.unwrap_or_else(|| {
|
layout.ty
|
||||||
bug!("FnType::new_vtable: non-pointer self {:?}", layout)
|
} else {
|
||||||
}).ty;
|
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);
|
let fat_ptr_ty = cx.tcx.mk_mut_ptr(pointee);
|
||||||
layout = cx.layout_of(fat_ptr_ty).field(cx, 0);
|
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));
|
.get_fn(&bx, meta, &fn_ty));
|
||||||
llargs.push(data_ptr);
|
llargs.push(data_ptr);
|
||||||
continue;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user