about summary refs log tree commit diff
path: root/compiler/rustc_codegen_cranelift/src/vtable.rs
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-03-15 14:41:48 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-03-15 14:41:48 +0000
commitfce629d2e9eddd957411caa5fed0e1146c745bd8 (patch)
treef539d967c8dac4932b09de113b12b5115e352849 /compiler/rustc_codegen_cranelift/src/vtable.rs
parent992d154f3a84cc8abcefcf6e6cf3698e4821b506 (diff)
parentdec0daa8f6d0a0e1c702f169abb6bf3eee198c67 (diff)
downloadrust-fce629d2e9eddd957411caa5fed0e1146c745bd8.tar.gz
rust-fce629d2e9eddd957411caa5fed0e1146c745bd8.zip
Merge commit 'dec0daa8f6d0a0e1c702f169abb6bf3eee198c67' into sync_cg_clif-2023-03-15
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/vtable.rs')
-rw-r--r--compiler/rustc_codegen_cranelift/src/vtable.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs
index f04fb82de8c..b7bfd8fd395 100644
--- a/compiler/rustc_codegen_cranelift/src/vtable.rs
+++ b/compiler/rustc_codegen_cranelift/src/vtable.rs
@@ -43,10 +43,29 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -
 
 pub(crate) fn get_ptr_and_method_ref<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
-    arg: CValue<'tcx>,
+    mut arg: CValue<'tcx>,
     idx: usize,
 ) -> (Pointer, Value) {
     let (ptr, vtable) = 'block: {
+        if let Abi::Scalar(_) = arg.layout().abi {
+            'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr()
+                && !arg.layout().ty.is_region_ptr()
+            {
+                for i in 0..arg.layout().fields.count() {
+                    let field = arg.value_field(fx, mir::Field::new(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
+                        arg = field;
+                        continue 'descend_newtypes;
+                    }
+                }
+
+                bug!("receiver has no non-zero-sized fields {:?}", arg);
+            }
+        }
+
         if let ty::Ref(_, ty, _) = arg.layout().ty.kind() {
             if ty.is_dyn_star() {
                 let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);