From e53b2baf29856dad9d47146b00c05a3fb5abe65a Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Sat, 11 Jun 2022 14:31:33 -0700
Subject: [PATCH] Add some tests for impossible bounds

---
 src/test/ui/trait-bounds/issue-93008.rs       | 17 +++++---
 src/test/ui/trait-bounds/issue-93008.stderr   | 12 ------
 src/test/ui/trait-bounds/issue-94680.rs       | 14 ++++++
 src/test/ui/trait-bounds/issue-94999.rs       | 34 +++++++++++++++
 src/test/ui/trait-bounds/issue-95640.rs       | 31 +++++++++++++
 .../select-param-env-instead-of-blanket.rs    | 43 +++++++++++++++++++
 ...select-param-env-instead-of-blanket.stderr | 18 ++++++++
 7 files changed, 151 insertions(+), 18 deletions(-)
 delete mode 100644 src/test/ui/trait-bounds/issue-93008.stderr
 create mode 100644 src/test/ui/trait-bounds/issue-94680.rs
 create mode 100644 src/test/ui/trait-bounds/issue-94999.rs
 create mode 100644 src/test/ui/trait-bounds/issue-95640.rs
 create mode 100644 src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
 create mode 100644 src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr

diff --git a/src/test/ui/trait-bounds/issue-93008.rs b/src/test/ui/trait-bounds/issue-93008.rs
index 1b010566cbc6e..f4d21a160b695 100644
--- a/src/test/ui/trait-bounds/issue-93008.rs
+++ b/src/test/ui/trait-bounds/issue-93008.rs
@@ -1,10 +1,15 @@
-// compile-flags: -Zmir-opt-level=4
+// build-pass
+// compile-flags: -Zmir-opt-level=3 --crate-type=lib
 
-pub fn bar<T>(s: &'static mut ())
+#![feature(trivial_bounds)]
+#![allow(trivial_bounds)]
+
+trait Foo {
+    fn test(self);
+}
+fn baz<T>()
 where
-    &'static mut (): Clone, //~ ERROR the trait bound
+    &'static str: Foo,
 {
-    <&'static mut () as Clone>::clone(&s);
+    "Foo".test()
 }
-
-fn main() {}
diff --git a/src/test/ui/trait-bounds/issue-93008.stderr b/src/test/ui/trait-bounds/issue-93008.stderr
deleted file mode 100644
index 10f80f8de0c9b..0000000000000
--- a/src/test/ui/trait-bounds/issue-93008.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0277]: the trait bound `&'static mut (): Clone` is not satisfied
-  --> $DIR/issue-93008.rs:5:5
-   |
-LL |     &'static mut (): Clone,
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&'static mut ()`
-   |
-   = help: see issue #48214
-   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/trait-bounds/issue-94680.rs b/src/test/ui/trait-bounds/issue-94680.rs
new file mode 100644
index 0000000000000..58e892079e65f
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-94680.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+fn main() {
+    println!("{:?}", {
+        type T = ();
+
+        pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
+        where
+            for<'any> &'any mut T: Clone,
+        {
+            (it.clone(), it)
+        }
+    });
+}
diff --git a/src/test/ui/trait-bounds/issue-94999.rs b/src/test/ui/trait-bounds/issue-94999.rs
new file mode 100644
index 0000000000000..e131902346f1b
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-94999.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+trait Identity<Q> {
+    type T;
+}
+
+impl<Q, T> Identity<Q> for T {
+    type T = T;
+}
+
+trait Holds {
+    type Q;
+}
+
+struct S;
+struct X(S);
+
+struct XHelper;
+
+impl Holds for X {
+    type Q = XHelper;
+}
+
+impl<Q> Clone for X
+where
+    <S as Identity<Q>>::T: Clone,
+    X: Holds<Q = Q>,
+{
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/issue-95640.rs b/src/test/ui/trait-bounds/issue-95640.rs
new file mode 100644
index 0000000000000..e4e998b5d0bb8
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-95640.rs
@@ -0,0 +1,31 @@
+// build-pass
+// compile-flags:-Zmir-opt-level=3
+
+struct D;
+
+trait Tr {
+    type It;
+    fn foo(self) -> Option<Self::It>;
+}
+
+impl<'a> Tr for &'a D {
+    type It = ();
+    fn foo(self) -> Option<()> {
+        None
+    }
+}
+
+fn run<F>(f: F)
+where
+    for<'a> &'a D: Tr,
+    F: Fn(<&D as Tr>::It),
+{
+    let d = &D;
+    while let Some(i) = d.foo() {
+        f(i);
+    }
+}
+
+fn main() {
+    run(|_| {});
+}
diff --git a/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
new file mode 100644
index 0000000000000..288b2098b4c02
--- /dev/null
+++ b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
@@ -0,0 +1,43 @@
+// known-bug
+// build-fail
+// failure-status: 101
+// compile-flags:--crate-type=lib -Zmir-opt-level=3
+// rustc-env:RUST_BACKTRACE=0
+
+// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "error: internal compiler error.*" -> "error: internal compiler error"
+// normalize-stderr-test "encountered.*with incompatible types:" "encountered ... with incompatible types:"
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "query stack during panic:\n" -> ""
+// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
+// normalize-stderr-test "end of query stack\n" -> ""
+// normalize-stderr-test "#.*\n" -> ""
+
+// This is a known bug that @compiler-errors tried to fix in #94238,
+// but the solution was probably not correct.
+
+pub trait Factory<T> {
+    type Item;
+}
+
+pub struct IntFactory;
+
+impl<T> Factory<T> for IntFactory {
+    type Item = usize;
+}
+
+pub fn foo<T>()
+where
+    IntFactory: Factory<T>,
+{
+    let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
+}
+
+#[inline]
+pub fn bar<T>() -> <IntFactory as Factory<T>>::Item {
+    0usize
+}
diff --git a/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr
new file mode 100644
index 0000000000000..56cc5c93c96f2
--- /dev/null
+++ b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr
@@ -0,0 +1,18 @@
+error: internal compiler error
+
+error: internal compiler error
+                                encountered ... with incompatible types:
+                                left-hand side has type: <IntFactory as Factory<T>>::Item
+                                right-hand side has type: usize
+  --> $DIR/select-param-env-instead-of-blanket.rs:42:5
+   |
+LL |     let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
+   |                                                   ---------- in this inlined function call
+...
+LL |     0usize
+   |     ^^^^^^
+   |
+   = note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:128:36
+
+thread 'rustc' panicked
+