about summary refs log tree commit diff
path: root/src/test/mir-opt/inline
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2020-12-29 16:21:52 +0000
committeroli <github35764891676564198441@oli-obk.de>2021-01-23 16:51:22 +0000
commitb8727e2d604e37a1510afaa9bd8777fecdcb5da4 (patch)
treef3659f892e7f967860ead03af063767f760a7576 /src/test/mir-opt/inline
parent4d0dd02ee07bddad9136f95c9f7846ebf3eb3fc5 (diff)
downloadrust-b8727e2d604e37a1510afaa9bd8777fecdcb5da4.tar.gz
rust-b8727e2d604e37a1510afaa9bd8777fecdcb5da4.zip
Prevent query cycles during inlining
Diffstat (limited to 'src/test/mir-opt/inline')
-rw-r--r--src/test/mir-opt/inline/inline-cycle-generic.rs40
-rw-r--r--src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff29
2 files changed, 69 insertions, 0 deletions
diff --git a/src/test/mir-opt/inline/inline-cycle-generic.rs b/src/test/mir-opt/inline/inline-cycle-generic.rs
new file mode 100644
index 00000000000..24b4f37939a
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-cycle-generic.rs
@@ -0,0 +1,40 @@
+// Check that inliner handles various forms of recursion and doesn't fall into
+// an infinite inlining cycle. The particular outcome of inlining is not
+// crucial otherwise.
+//
+// Regression test for issue #78573.
+
+// EMIT_MIR inline_cycle_generic.main.Inline.diff
+fn main() {
+    <C as Call>::call();
+}
+
+pub trait Call {
+    fn call();
+}
+
+pub struct A;
+pub struct B<T>(T);
+pub struct C;
+
+impl Call for A {
+    #[inline]
+    fn call() {
+        <B<C> as Call>::call()
+    }
+}
+
+
+impl<T: Call> Call for B<T> {
+    #[inline]
+    fn call() {
+        <T as Call>::call()
+    }
+}
+
+impl Call for C {
+    #[inline]
+    fn call() {
+        <B<A> as Call>::call()
+    }
+}
diff --git a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
new file mode 100644
index 00000000000..9709f273779
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
@@ -0,0 +1,29 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inline-cycle-generic.rs:8:11: 8:11
+      let _1: ();                          // in scope 0 at $DIR/inline-cycle-generic.rs:9:5: 9:24
++     scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle-generic.rs:9:5: 9:24
++         scope 2 (inlined <B<A> as Call>::call) { // at $DIR/inline-cycle-generic.rs:9:5: 9:24
++         }
++     }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inline-cycle-generic.rs:9:5: 9:24
+-         _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle-generic.rs:9:5: 9:24
++         _1 = <A as Call>::call() -> bb1; // scope 2 at $DIR/inline-cycle-generic.rs:9:5: 9:24
+                                           // mir::Constant
+-                                          // + span: $DIR/inline-cycle-generic.rs:9:5: 9:22
+-                                          // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(Scalar(<ZST>)) }
++                                          // + span: $DIR/inline-cycle-generic.rs:9:5: 9:24
++                                          // + literal: Const { ty: fn() {<A as Call>::call}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageDead(_1);                 // scope 0 at $DIR/inline-cycle-generic.rs:9:24: 9:25
+          _0 = const ();                   // scope 0 at $DIR/inline-cycle-generic.rs:8:11: 10:2
+          return;                          // scope 0 at $DIR/inline-cycle-generic.rs:10:2: 10:2
+      }
+  }
+