about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs23
-rw-r--r--tests/ui/traits/winnowing/global-non-global-env-1.rs18
-rw-r--r--tests/ui/traits/winnowing/global-non-global-env-2.rs20
-rw-r--r--tests/ui/traits/winnowing/global-non-global-env-3.rs20
-rw-r--r--tests/ui/traits/winnowing/global-non-global-env-4.rs21
5 files changed, 102 insertions, 0 deletions
diff --git a/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs b/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs
new file mode 100644
index 00000000000..9600b3875ba
--- /dev/null
+++ b/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs
@@ -0,0 +1,23 @@
+//@ check-pass
+
+// This caused a regression in a crater run in #132325.
+//
+// The underlying issue is a really subtle implementation detail.
+//
+// When building the `param_env` for `Trait` we start out with its
+// explicit predicates `Self: Trait` and `Self: for<'a> Super<'a, { 1 + 1 }>`.
+//
+// When normalizing the environment we also elaborate. This implicitly
+// deduplicates its returned predicates. We currently first eagerly
+// normalize constants in the unnormalized param env to avoid issues
+// caused by our lack of deferred alias equality.
+//
+// So we actually elaborate `Self: Trait` and `Self: for<'a> Super<'a, 2>`,
+// resulting in a third `Self: for<'a> Super<'a, { 1 + 1 }>` predicate which
+// then gets normalized to  `Self: for<'a> Super<'a, 2>` at which point we
+// do not deduplicate however. By failing to handle equal where-bounds in
+// candidate selection, this caused ambiguity when checking that `Trait` is
+// well-formed.
+trait Super<'a, const N: usize> {}
+trait Trait: for<'a> Super<'a, { 1 + 1 }> {}
+fn main() {}
diff --git a/tests/ui/traits/winnowing/global-non-global-env-1.rs b/tests/ui/traits/winnowing/global-non-global-env-1.rs
new file mode 100644
index 00000000000..d232d32dddf
--- /dev/null
+++ b/tests/ui/traits/winnowing/global-non-global-env-1.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+
+// A regression test for an edge case of candidate selection
+// in the old trait solver, see #132325 for more details.
+
+trait Trait<T> {}
+impl<T> Trait<T> for () {}
+
+fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
+fn foo<T>() -> u32
+where
+    (): Trait<u32>,
+    (): Trait<T>,
+{
+    impls_trait(())
+}
+
+fn main() {}
diff --git a/tests/ui/traits/winnowing/global-non-global-env-2.rs b/tests/ui/traits/winnowing/global-non-global-env-2.rs
new file mode 100644
index 00000000000..c73d0f06cd9
--- /dev/null
+++ b/tests/ui/traits/winnowing/global-non-global-env-2.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+
+// A regression test for an edge case of candidate selection
+// in the old trait solver, see #132325 for more details. Unlike
+// the first test, this one has two impl candidates.
+
+trait Trait<T> {}
+impl Trait<u32> for () {}
+impl Trait<u64> for () {}
+
+fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
+fn foo<T>() -> u32
+where
+    (): Trait<u32>,
+    (): Trait<T>,
+{
+    impls_trait(())
+}
+
+fn main() {}
diff --git a/tests/ui/traits/winnowing/global-non-global-env-3.rs b/tests/ui/traits/winnowing/global-non-global-env-3.rs
new file mode 100644
index 00000000000..008d07e4144
--- /dev/null
+++ b/tests/ui/traits/winnowing/global-non-global-env-3.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+
+// A regression test for an edge case of candidate selection
+// in the old trait solver, see #132325 for more details. Unlike
+// the second test, the where-bounds are in a different order.
+
+trait Trait<T> {}
+impl Trait<u32> for () {}
+impl Trait<u64> for () {}
+
+fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
+fn foo<T>() -> u32
+where
+    (): Trait<T>,
+    (): Trait<u32>,
+{
+    impls_trait(())
+}
+
+fn main() {}
diff --git a/tests/ui/traits/winnowing/global-non-global-env-4.rs b/tests/ui/traits/winnowing/global-non-global-env-4.rs
new file mode 100644
index 00000000000..74793620c9e
--- /dev/null
+++ b/tests/ui/traits/winnowing/global-non-global-env-4.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+
+// A regression test for an edge case of candidate selection
+// in the old trait solver, see #132325 for more details. Unlike
+// the third test, this one has 3 impl candidates.
+
+trait Trait<T> {}
+impl Trait<u32> for () {}
+impl Trait<u64> for () {}
+impl Trait<u128> for () {}
+
+fn impls_trait<T: Trait<U>, U>(_: T) -> U { todo!() }
+fn foo<T>() -> u32
+where
+    (): Trait<T>,
+    (): Trait<u32>,
+{
+    impls_trait(())
+}
+
+fn main() {}