about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/mir-opt/inline/dyn-trait.rs35
-rw-r--r--src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff62
-rw-r--r--src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff23
-rw-r--r--src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff37
-rw-r--r--src/test/ui/associated-consts/issue-88599-ref-self.rs24
-rw-r--r--src/test/ui/issues/issue-37725.rs2
-rw-r--r--src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr46
-rw-r--r--src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr46
-rw-r--r--src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs71
9 files changed, 346 insertions, 0 deletions
diff --git a/src/test/mir-opt/inline/dyn-trait.rs b/src/test/mir-opt/inline/dyn-trait.rs
new file mode 100644
index 00000000000..6a46e1e07b1
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn-trait.rs
@@ -0,0 +1,35 @@
+#![crate_type = "lib"]
+
+use std::fmt::Debug;
+
+pub trait Cache {
+    type V: Debug;
+
+    fn store_nocache(&self);
+}
+
+pub trait Query {
+    type V;
+    type C: Cache<V = Self::V>;
+
+    fn cache<T>(s: &T) -> &Self::C;
+}
+
+// EMIT_MIR dyn_trait.mk_cycle.Inline.diff
+#[inline(always)]
+pub fn mk_cycle<V: Debug>(c: &dyn Cache<V = V>) {
+    c.store_nocache()
+}
+
+// EMIT_MIR dyn_trait.try_execute_query.Inline.diff
+#[inline(always)]
+pub fn try_execute_query<C: Cache>(c: &C) {
+    mk_cycle(c)
+}
+
+// EMIT_MIR dyn_trait.get_query.Inline.diff
+#[inline(always)]
+pub fn get_query<Q: Query, T>(t: &T) {
+    let c = Q::cache(t);
+    try_execute_query(c)
+}
diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
new file mode 100644
index 00000000000..953d7b85c5b
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
@@ -0,0 +1,62 @@
+- // MIR for `get_query` before Inline
++ // MIR for `get_query` after Inline
+  
+  fn get_query(_1: &T) -> () {
+      debug t => _1;                       // in scope 0 at $DIR/dyn-trait.rs:32:31: 32:32
+      let mut _0: ();                      // return place in scope 0 at $DIR/dyn-trait.rs:32:38: 32:38
+      let _2: &<Q as Query>::C;            // in scope 0 at $DIR/dyn-trait.rs:33:9: 33:10
+      let mut _3: &T;                      // in scope 0 at $DIR/dyn-trait.rs:33:22: 33:23
+      let mut _4: &<Q as Query>::C;        // in scope 0 at $DIR/dyn-trait.rs:34:23: 34:24
+      scope 1 {
+          debug c => _2;                   // in scope 1 at $DIR/dyn-trait.rs:33:9: 33:10
++         scope 2 (inlined try_execute_query::<<Q as Query>::C>) { // at $DIR/dyn-trait.rs:34:5: 34:25
++             debug c => _4;               // in scope 2 at $DIR/dyn-trait.rs:26:36: 26:37
++             let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++             let mut _6: &<Q as Query>::C; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++             scope 3 (inlined mk_cycle::<<Q as Query>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
++                 debug c => _5;           // in scope 3 at $DIR/dyn-trait.rs:20:27: 20:28
++                 let mut _7: &dyn Cache<V = <Q as Query>::V>; // in scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
++             }
++         }
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/dyn-trait.rs:33:9: 33:10
+          StorageLive(_3);                 // scope 0 at $DIR/dyn-trait.rs:33:22: 33:23
+          _3 = &(*_1);                     // scope 0 at $DIR/dyn-trait.rs:33:22: 33:23
+          _2 = <Q as Query>::cache::<T>(move _3) -> bb1; // scope 0 at $DIR/dyn-trait.rs:33:13: 33:24
+                                           // mir::Constant
+                                           // + span: $DIR/dyn-trait.rs:33:13: 33:21
+                                           // + user_ty: UserType(0)
+                                           // + literal: Const { ty: for<'r> fn(&'r T) -> &'r <Q as Query>::C {<Q as Query>::cache::<T>}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageDead(_3);                 // scope 0 at $DIR/dyn-trait.rs:33:23: 33:24
+          StorageLive(_4);                 // scope 1 at $DIR/dyn-trait.rs:34:23: 34:24
+          _4 = &(*_2);                     // scope 1 at $DIR/dyn-trait.rs:34:23: 34:24
+-         _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn-trait.rs:34:5: 34:25
++         StorageLive(_5);                 // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++         StorageLive(_6);                 // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++         _6 = _4;                         // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++         _5 = move _6 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++         StorageDead(_6);                 // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
++         StorageLive(_7);                 // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
++         _7 = _5;                         // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
++         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
+                                           // mir::Constant
+-                                          // + span: $DIR/dyn-trait.rs:34:5: 34:22
+-                                          // + literal: Const { ty: for<'r> fn(&'r <Q as Query>::C) {try_execute_query::<<Q as Query>::C>}, val: Value(Scalar(<ZST>)) }
++                                          // + span: $DIR/dyn-trait.rs:21:7: 21:20
++                                          // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = <Q as Query>::V>) {<dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb2: {
++         StorageDead(_7);                 // scope 3 at $DIR/dyn-trait.rs:21:21: 21:22
++         StorageDead(_5);                 // scope 2 at $DIR/dyn-trait.rs:27:15: 27:16
+          StorageDead(_4);                 // scope 1 at $DIR/dyn-trait.rs:34:24: 34:25
+          StorageDead(_2);                 // scope 0 at $DIR/dyn-trait.rs:35:1: 35:2
+          return;                          // scope 0 at $DIR/dyn-trait.rs:35:2: 35:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
new file mode 100644
index 00000000000..27309328052
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
@@ -0,0 +1,23 @@
+- // MIR for `mk_cycle` before Inline
++ // MIR for `mk_cycle` after Inline
+  
+  fn mk_cycle(_1: &dyn Cache<V = V>) -> () {
+      debug c => _1;                       // in scope 0 at $DIR/dyn-trait.rs:20:27: 20:28
+      let mut _0: ();                      // return place in scope 0 at $DIR/dyn-trait.rs:20:49: 20:49
+      let mut _2: &dyn Cache<V = V>;       // in scope 0 at $DIR/dyn-trait.rs:21:5: 21:22
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/dyn-trait.rs:21:5: 21:22
+          _2 = &(*_1);                     // scope 0 at $DIR/dyn-trait.rs:21:5: 21:22
+          _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:21:5: 21:22
+                                           // mir::Constant
+                                           // + span: $DIR/dyn-trait.rs:21:7: 21:20
+                                           // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = V>) {<dyn Cache<V = V> as Cache>::store_nocache}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageDead(_2);                 // scope 0 at $DIR/dyn-trait.rs:21:21: 21:22
+          return;                          // scope 0 at $DIR/dyn-trait.rs:22:2: 22:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
new file mode 100644
index 00000000000..93bba58825d
--- /dev/null
+++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
@@ -0,0 +1,37 @@
+- // MIR for `try_execute_query` before Inline
++ // MIR for `try_execute_query` after Inline
+  
+  fn try_execute_query(_1: &C) -> () {
+      debug c => _1;                       // in scope 0 at $DIR/dyn-trait.rs:26:36: 26:37
+      let mut _0: ();                      // return place in scope 0 at $DIR/dyn-trait.rs:26:43: 26:43
+      let mut _2: &dyn Cache<V = <C as Cache>::V>; // in scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
+      let mut _3: &C;                      // in scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
++     scope 1 (inlined mk_cycle::<<C as Cache>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
++         debug c => _2;                   // in scope 1 at $DIR/dyn-trait.rs:20:27: 20:28
++         let mut _4: &dyn Cache<V = <C as Cache>::V>; // in scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
++     }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
+          StorageLive(_3);                 // scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
+          _3 = &(*_1);                     // scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
+          _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
+          StorageDead(_3);                 // scope 0 at $DIR/dyn-trait.rs:27:14: 27:15
+-         _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:27:5: 27:16
++         StorageLive(_4);                 // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
++         _4 = _2;                         // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
++         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
+                                           // mir::Constant
+-                                          // + span: $DIR/dyn-trait.rs:27:5: 27:13
+-                                          // + literal: Const { ty: for<'r> fn(&'r (dyn Cache<V = <C as Cache>::V> + 'r)) {mk_cycle::<<C as Cache>::V>}, val: Value(Scalar(<ZST>)) }
++                                          // + span: $DIR/dyn-trait.rs:21:7: 21:20
++                                          // + literal: Const { ty: for<'r> fn(&'r dyn Cache<V = <C as Cache>::V>) {<dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
++         StorageDead(_4);                 // scope 1 at $DIR/dyn-trait.rs:21:21: 21:22
+          StorageDead(_2);                 // scope 0 at $DIR/dyn-trait.rs:27:15: 27:16
+          return;                          // scope 0 at $DIR/dyn-trait.rs:28:2: 28:2
+      }
+  }
+  
diff --git a/src/test/ui/associated-consts/issue-88599-ref-self.rs b/src/test/ui/associated-consts/issue-88599-ref-self.rs
new file mode 100644
index 00000000000..f1144db44ca
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-88599-ref-self.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait First {
+    const CONST: usize;
+}
+pub trait Second {}
+
+impl<'a> First for dyn Second
+where
+    &'a Self: First,
+{
+    const CONST: usize = <&Self>::CONST;
+}
+
+trait Third: First
+where
+    [u8; Self::CONST]:
+{
+    const VAL: [u8; Self::CONST] = [0; Self::CONST];
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-37725.rs b/src/test/ui/issues/issue-37725.rs
index 965ecde6f3c..1c6df0da60c 100644
--- a/src/test/ui/issues/issue-37725.rs
+++ b/src/test/ui/issues/issue-37725.rs
@@ -1,4 +1,6 @@
 // build-pass
+// compiler-opts: -Zmir-opt-level=2
+
 #![allow(dead_code)]
 trait Foo {
     fn foo(&self);
diff --git a/src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr
new file mode 100644
index 00000000000..40829f53709
--- /dev/null
+++ b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.inline.stderr
@@ -0,0 +1,46 @@
+warning: trait bound for<'any> &'any mut (): Clone does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:20:29
+   |
+LL |     for<'any> &'any mut (): Clone,
+   |                             ^^^^^
+   |
+   = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:28:21
+   |
+LL | struct S where i32: Foo;
+   |                     ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:31:28
+   |
+LL | impl Foo for () where i32: Foo {
+   |                            ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:40:19
+   |
+LL | fn f() where i32: Foo {
+   |                   ^^^
+
+warning: trait bound &'static str: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:48:28
+   |
+LL | fn g() where &'static str: Foo {
+   |                            ^^^
+
+warning: trait bound String: Neg does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:57:13
+   |
+LL |     String: ::std::ops::Neg<Output = String>,
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: trait bound i32: Iterator does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:65:10
+   |
+LL |     i32: Iterator,
+   |          ^^^^^^^^
+
+warning: 7 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr
new file mode 100644
index 00000000000..40829f53709
--- /dev/null
+++ b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.no-opt.stderr
@@ -0,0 +1,46 @@
+warning: trait bound for<'any> &'any mut (): Clone does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:20:29
+   |
+LL |     for<'any> &'any mut (): Clone,
+   |                             ^^^^^
+   |
+   = note: `#[warn(trivial_bounds)]` on by default
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:28:21
+   |
+LL | struct S where i32: Foo;
+   |                     ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:31:28
+   |
+LL | impl Foo for () where i32: Foo {
+   |                            ^^^
+
+warning: trait bound i32: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:40:19
+   |
+LL | fn f() where i32: Foo {
+   |                   ^^^
+
+warning: trait bound &'static str: Foo does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:48:28
+   |
+LL | fn g() where &'static str: Foo {
+   |                            ^^^
+
+warning: trait bound String: Neg does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:57:13
+   |
+LL |     String: ::std::ops::Neg<Output = String>,
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: trait bound i32: Iterator does not depend on any type or lifetime parameters
+  --> $DIR/issue-73021-impossible-inline.rs:65:10
+   |
+LL |     i32: Iterator,
+   |          ^^^^^^^^
+
+warning: 7 warnings emitted
+
diff --git a/src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs
new file mode 100644
index 00000000000..ab6677e911b
--- /dev/null
+++ b/src/test/ui/trivial-bounds/issue-73021-impossible-inline.rs
@@ -0,0 +1,71 @@
+// build-pass
+// revisions: no-opt inline
+// [inline]compile-flags: -Zmir-opt-level=3 --emit=mir
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+trait Foo {
+    fn test(&self);
+}
+
+fn foo<'a>(s: &'a mut ())
+where
+    &'a mut (): Foo,
+{
+    s.test();
+}
+
+fn clone(it: &mut ()) -> &mut ()
+where
+    for<'any> &'any mut (): Clone,
+    //~^ WARN trait bound for<'any> &'any mut (): Clone does not depend on any type or lifetime parameters
+{
+    it.clone()
+}
+
+fn generic_function<X: Foo>(x: X) {}
+
+struct S where i32: Foo;
+//~^ WARN trait bound i32: Foo does not depend on any type or lifetime parameters
+
+impl Foo for () where i32: Foo {
+//~^ WARN trait bound i32: Foo does not depend on any type or lifetime parameters
+    fn test(&self) {
+        3i32.test();
+        Foo::test(&4i32);
+        generic_function(5i32);
+    }
+}
+
+fn f() where i32: Foo {
+//~^ WARN trait bound i32: Foo does not depend on any type or lifetime parameters
+    let s = S;
+    3i32.test();
+    Foo::test(&4i32);
+    generic_function(5i32);
+}
+
+fn g() where &'static str: Foo {
+//~^ WARN trait bound &'static str: Foo does not depend on any type or lifetime parameters
+    "Foo".test();
+    Foo::test(&"Foo");
+    generic_function("Foo");
+}
+
+fn use_op(s: String) -> String
+where
+    String: ::std::ops::Neg<Output = String>,
+//~^ WARN trait bound String: Neg does not depend on any type or lifetime parameters
+{
+    -s
+}
+
+fn use_for()
+where
+    i32: Iterator,
+//~^ WARN trait bound i32: Iterator does not depend on any type or lifetime parameters
+{
+    for _ in 2i32 {}
+}
+
+fn main() {}