]> git.lizzy.rs Git - rust.git/commitdiff
[mir-inlining] Don't inline virtual calls
authorWesley Wiser <wwiser@gmail.com>
Fri, 12 Oct 2018 01:28:20 +0000 (21:28 -0400)
committerWesley Wiser <wwiser@gmail.com>
Sun, 14 Oct 2018 17:45:46 +0000 (13:45 -0400)
Prior to this change, the test case would output `1` instead of `2` like
it should.

src/librustc_mir/transform/inline.rs
src/test/mir-opt/inline-trait-method.rs [new file with mode: 0644]

index 040ee35632cbba871067e03fbbb19e32a97cefa9..5963f1a481c659942fca679b6ce4d13ea7696718 100644 (file)
@@ -19,7 +19,7 @@
 
 use rustc::mir::*;
 use rustc::mir::visit::*;
-use rustc::ty::{self, Instance, Ty, TyCtxt};
+use rustc::ty::{self, Instance, InstanceDef, Ty, TyCtxt};
 use rustc::ty::subst::{Subst,Substs};
 
 use std::collections::VecDeque;
@@ -100,12 +100,21 @@ fn run_pass(&self, caller_mir: &mut Mir<'tcx>) {
                                                                       param_env,
                                                                       callee_def_id,
                                                                       substs) {
-                                callsites.push_back(CallSite {
-                                    callee: instance.def_id(),
-                                    substs: instance.substs,
-                                    bb,
-                                    location: terminator.source_info
-                                });
+                                let is_virtual =
+                                    if let InstanceDef::Virtual(..) = instance.def {
+                                        true
+                                    } else {
+                                        false
+                                    };
+
+                                if !is_virtual {
+                                    callsites.push_back(CallSite {
+                                        callee: instance.def_id(),
+                                        substs: instance.substs,
+                                        bb,
+                                        location: terminator.source_info
+                                    });
+                                }
                             }
                         }
                     }
diff --git a/src/test/mir-opt/inline-trait-method.rs b/src/test/mir-opt/inline-trait-method.rs
new file mode 100644 (file)
index 0000000..0f79f43
--- /dev/null
@@ -0,0 +1,31 @@
+// compile-flags: -Z span_free_formats
+
+fn main() {
+    println!("{}", test(&()));
+}
+
+fn test(x: &dyn X) -> u32 {
+    x.y()
+}
+
+trait X {
+    fn y(&self) -> u32 {
+        1
+    }
+}
+
+impl X for () {
+    fn y(&self) -> u32 {
+        2
+    }
+}
+
+// END RUST SOURCE
+// START rustc.test.Inline.after.mir
+// ...
+// bb0: {
+// ...
+//     _0 = const X::y(move _2) -> bb1;
+// }
+// ...
+// END rustc.test.Inline.after.mir