about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-14 21:50:23 +0000
committerbors <bors@rust-lang.org>2018-10-14 21:50:23 +0000
commit0c665e20db6c61de8f741bca3ca7660e679885c0 (patch)
tree75dee248bd4429b18a0674792db54a576e3c56e3
parent14f42a732ff9562fb5f07eca5a7f92224dbe8881 (diff)
parent69eaa11633b1279d4f2edb734e541f545d583b0a (diff)
downloadrust-0c665e20db6c61de8f741bca3ca7660e679885c0.tar.gz
rust-0c665e20db6c61de8f741bca3ca7660e679885c0.zip
Auto merge of #55046 - wesleywiser:no_virtual_call_inlining, r=varkor
[mir-inlining] Don't inline virtual calls
-rw-r--r--src/librustc_mir/transform/inline.rs23
-rw-r--r--src/test/mir-opt/inline-trait-method.rs31
2 files changed, 47 insertions, 7 deletions
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 040ee35632c..5963f1a481c 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 
 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 @@ impl<'a, 'tcx> Inliner<'a, '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
index 00000000000..0f79f43ee2d
--- /dev/null
+++ b/src/test/mir-opt/inline-trait-method.rs
@@ -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