From 192e7c4b51ab35f4cfbbacde9eeffa8e12dba873 Mon Sep 17 00:00:00 2001 From: Michael Hewson Date: Thu, 1 Nov 2018 18:28:52 -0400 Subject: [PATCH] Add comments explaining how codegen works for `dyn Trait` methods --- src/librustc_codegen_llvm/abi.rs | 5 +++++ src/librustc_codegen_llvm/mir/block.rs | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 1662b57b8b319..e50534a4e1dc9 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -315,6 +315,11 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { _ => bug!("receiver type has unsupported layout: {:?}", layout) } + // In the case of Rc, we need to explicitly pass a *mut RcBox + // with a Scalar (not ScalarPair) ABI. This is a hack that is understood + // elsewhere in the compiler as a method on a `dyn Trait`. + // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we + // get a built-in pointer type let mut fat_pointer_layout = layout; 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() && !fat_pointer_layout.ty.is_region_ptr() diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 0cb4963f97fae..a7f4c48c89bd6 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -647,8 +647,12 @@ impl FunctionCx<'a, 'll, 'tcx> { if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) { if let Pair(..) = op.val { - // descend through newtype wrappers until `op` is a builtin pointer to - // `dyn Trait`, e.g. `*const dyn Trait`, `&mut dyn Trait` + // In the case of Rc, we need to explicitly pass a + // *mut RcBox 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`, 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() {