Skip to content

Commit 5eceab0

Browse files
committed
Implement by-value trait object method call.
1 parent f2ef005 commit 5eceab0

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

src/librustc_codegen_llvm/abi.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,17 +305,17 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
305305
// Don't pass the vtable, it's not an argument of the virtual fn.
306306
// Instead, pass just the (thin pointer) first field of `*dyn Trait`.
307307
if arg_idx == Some(0) {
308-
if layout.is_unsized() {
309-
unimplemented!("by-value trait object is not \
310-
yet implemented in #![feature(unsized_locals)]");
311-
}
312308
// FIXME(eddyb) `layout.field(cx, 0)` is not enough because e.g.
313309
// `Box<dyn Trait>` has a few newtype wrappers around the raw
314310
// pointer, so we'd have to "dig down" to find `*dyn Trait`.
315-
let pointee = layout.ty.builtin_deref(true)
316-
.unwrap_or_else(|| {
317-
bug!("FnType::new_vtable: non-pointer self {:?}", layout)
318-
}).ty;
311+
let pointee = if layout.is_unsized() {
312+
layout.ty
313+
} else {
314+
layout.ty.builtin_deref(true)
315+
.unwrap_or_else(|| {
316+
bug!("FnType::new_vtable: non-pointer self {:?}", layout)
317+
}).ty
318+
};
319319
let fat_ptr_ty = cx.tcx.mk_mut_ptr(pointee);
320320
layout = cx.layout_of(fat_ptr_ty).field(cx, 0);
321321
}

src/librustc_codegen_llvm/mir/block.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,12 @@ impl FunctionCx<'a, 'll, 'tcx> {
651651
.get_fn(&bx, meta, &fn_ty));
652652
llargs.push(data_ptr);
653653
continue;
654+
} else if let Ref(data_ptr, Some(meta), _) = op.val {
655+
// by-value dynamic dispatch
656+
llfn = Some(meth::VirtualIndex::from_index(idx)
657+
.get_fn(&bx, meta, &fn_ty));
658+
llargs.push(data_ptr);
659+
continue;
654660
}
655661
}
656662

0 commit comments

Comments
 (0)