about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/mir
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-08-29 06:00:58 +0000
committerEric Holk <ericholk@microsoft.com>2022-09-12 16:56:00 -0700
commit03148ff735c561629c7e880383d3e0d44eebf738 (patch)
treeafeb0548c435cf9484aaaec033fa788ab1fc84a2 /compiler/rustc_codegen_ssa/src/mir
parentb2ed2dcaaedf0a96dece85a5409b3a1f30a84360 (diff)
downloadrust-03148ff735c561629c7e880383d3e0d44eebf738.tar.gz
rust-03148ff735c561629c7e880383d3e0d44eebf738.zip
Make dyn-trait-method work
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 59bae7f7e91..7cee9ea3e1d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -907,7 +907,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         llargs.push(data_ptr);
                         continue;
                     }
-                    _ => span_bug!(span, "can't codegen a virtual call on {:#?}", op),
+                    Immediate(_) => {
+                        let ty::Ref(_, ty, _) = op.layout.ty.kind() else {
+                            span_bug!(span, "can't codegen a virtual call on {:#?}", op);
+                        };
+                        if !ty.is_dyn_star() {
+                            span_bug!(span, "can't codegen a virtual call on {:#?}", op);
+                        }
+                        // FIXME(dyn-star): Make sure this is done on a &dyn* receiver
+                        let place = op.deref(bx.cx());
+                        let data_ptr = place.project_field(&mut bx, 0);
+                        let meta_ptr = place.project_field(&mut bx, 1);
+                        let meta = bx.load_operand(meta_ptr);
+                        llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
+                            &mut bx,
+                            meta.immediate(),
+                            op.layout.ty,
+                            &fn_abi,
+                        ));
+                        llargs.push(data_ptr.llval);
+                        continue;
+                    }
+                    _ => {
+                        span_bug!(span, "can't codegen a virtual call on {:#?}", op);
+                    }
                 }
             }