summaryrefslogtreecommitdiffstats
path: root/tests/ui/traits/next-solver/generalize
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/traits/next-solver/generalize')
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs73
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs75
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr19
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr11
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs38
5 files changed, 216 insertions, 0 deletions
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs
new file mode 100644
index 000000000..4a70bd5f8
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs
@@ -0,0 +1,73 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+// A minimization of an ambiguity when using typenum. See
+// https://github.com/rust-lang/trait-system-refactor-initiative/issues/55
+// for more details.
+trait Id {
+ type Assoc: ?Sized;
+}
+impl<T: ?Sized> Id for T {
+ type Assoc = T;
+}
+
+trait WithAssoc<T: ?Sized> {
+ type Assoc: ?Sized;
+}
+
+
+struct Leaf;
+struct Wrapper<U: ?Sized>(U);
+
+impl<U: ?Sized> WithAssoc<U> for Leaf {
+ type Assoc = U;
+}
+
+impl<Ul: ?Sized, Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Wrapper<Ul>
+where
+ Ul: WithAssoc<Ur>,
+{
+ type Assoc = <<Ul as WithAssoc<Ur>>::Assoc as Id>::Assoc;
+}
+
+fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
+where
+ T: WithAssoc<U, Assoc = V>,
+{
+}
+
+// normalize self type to `Wrapper<Leaf>`
+// This succeeds, HOWEVER, instantiating the query response previously
+// incremented the universe index counter.
+// equate impl headers:
+// <Wrapper<Leaf> as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>
+// <Wrapper<?2t> as WithAssoc<Wrapper<?3t>>>
+// ~> AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
+// add where bounds:
+// ~> Leaf: WithAssoc<?3t>
+// equate with assoc type:
+// ?0t
+// <Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc
+// ~> AliasRelate(
+// <<Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc,
+// Equate,
+// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
+// )
+//
+// We do not reuse `?3t` during generalization because `?0t` cannot name `?4t` as we created
+// it after incrementing the universe index while normalizing the self type.
+//
+// evaluate_added_goals_and_make_query_response:
+// AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
+// YES, constrains ?3t to Leaf
+// AliasRelate(
+// <<Leaf as WithAssoc<Leaf>>::Assoc as Id>::Assoc,
+// Equate,
+// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
+// )
+//
+// Normalizing <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc then *correctly*
+// results in ambiguity.
+fn main() {
+ bound::<<Wrapper<Leaf> as Id>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
+}
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
new file mode 100644
index 000000000..70758e7de
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
@@ -0,0 +1,75 @@
+// compile-flags: -Znext-solver
+// known-bug: trait-system-refactor-initiative#60
+
+// Generalizing a projection containing an inference variable
+// which cannot be named by the `root_vid` can result in ambiguity.
+//
+// Because we do not decrement the universe index when exiting a forall,
+// this can cause unexpected failures.
+//
+// See generalize-proj-new-universe-index-1.rs for more details.
+
+// For this reproduction we need:
+// - an inference variable with a lower universe
+// - enter a binder to increment the current universe
+// - create a new inference variable which is constrained by proving a goal
+// - equate a projection containing the new variable with the first variable
+// - generalization creates yet another inference variable which is then
+// part of an alias-relate, resulting this to fail with ambiguity.
+//
+// Because we need to enter the binder in-between the creation of the first
+// and second inference variable, this is easiest via
+// `assemble_candidates_after_normalizing_self_ty` because eagerly call
+// `try_evaluate_added_goals` there before creating the inference variables
+// for the impl parameters.
+trait Id {
+ type Assoc: ?Sized;
+}
+impl<T: ?Sized> Id for T {
+ type Assoc = T;
+}
+
+// By adding an higher ranked bound to the impl we currently
+// propagate this bound to the caller, forcing us to create a new
+// universe.
+trait IdHigherRankedBound {
+ type Assoc: ?Sized;
+}
+
+impl<T: ?Sized> IdHigherRankedBound for T
+where
+ for<'a> T: 'a,
+{
+ type Assoc = T;
+}
+
+trait WithAssoc<T: ?Sized> {
+ type Assoc: ?Sized;
+}
+
+
+struct Leaf;
+struct Wrapper<U: ?Sized>(U);
+struct Rigid;
+
+impl<U: ?Sized> WithAssoc<U> for Leaf {
+ type Assoc = U;
+}
+
+
+impl<Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Rigid
+where
+ Leaf: WithAssoc<Ur>,
+{
+ type Assoc = <<Leaf as WithAssoc<Ur>>::Assoc as Id>::Assoc;
+}
+
+fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
+where
+ T: WithAssoc<U, Assoc = V>,
+{
+}
+
+fn main() {
+ bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
+}
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr
new file mode 100644
index 000000000..4548ab1e2
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr
@@ -0,0 +1,19 @@
+error[E0284]: type annotations needed
+ --> $DIR/generalize-proj-new-universe-index-2.rs:74:5
+ |
+LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
+ |
+ = note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _`
+note: required by a bound in `bound`
+ --> $DIR/generalize-proj-new-universe-index-2.rs:69:21
+ |
+LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
+ | ----- required by a bound in this function
+LL | where
+LL | T: WithAssoc<U, Assoc = V>,
+ | ^^^^^^^^^ required by this bound in `bound`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
new file mode 100644
index 000000000..ad8b24a39
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
@@ -0,0 +1,11 @@
+error[E0275]: overflow evaluating the requirement `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _`
+ --> $DIR/occurs-check-nested-alias.rs:36:9
+ |
+LL | x = y;
+ | ^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`occurs_check_nested_alias`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
new file mode 100644
index 000000000..e51508d68
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
@@ -0,0 +1,38 @@
+// revisions: old next
+//[old] check-pass
+
+// Currently always fails to generalize the outer alias, even if it
+// is treated as rigid by `alias-relate`.
+//[next] compile-flags: -Znext-solver
+//[next] known-bug: trait-system-refactor-initiative#8
+#![crate_type = "lib"]
+#![allow(unused)]
+trait Unnormalizable {
+ type Assoc;
+}
+
+trait Id<T> {
+ type Id;
+}
+impl<T, U> Id<T> for U {
+ type Id = U;
+}
+
+struct Inv<T>(*mut T);
+
+fn unconstrained<T>() -> T {
+ todo!()
+}
+
+fn create<T, U: Unnormalizable>(
+ x: &U,
+) -> (Inv<T>, Inv<<<U as Id<T>>::Id as Unnormalizable>::Assoc>) {
+ todo!()
+}
+
+fn foo<T: Unnormalizable>() {
+ let q = unconstrained();
+ let (mut x, y) = create::<_, _>(&q);
+ x = y;
+ drop::<T>(q);
+}