about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-02-11 05:46:24 +0000
committerbors <bors@rust-lang.org>2023-02-11 05:46:24 +0000
commit1623ab0246deebec4fe32dc525d20bf8a88096f2 (patch)
treeb53f139b7fbe2cd91228c2724e4affccfc1a85c9 /tests
parent5a8dfd933a70cc47e44502a20fd67dfaec6555d5 (diff)
parent4c98429d8c7b05276fa94eac2e78b24c947509c3 (diff)
downloadrust-1623ab0246deebec4fe32dc525d20bf8a88096f2.tar.gz
rust-1623ab0246deebec4fe32dc525d20bf8a88096f2.zip
Auto merge of #107507 - BoxyUwU:deferred_projection_equality, r=lcnr
Implement `deferred_projection_equality` for erica solver

Somewhat of a revival of #96912. When relating projections now emit an `AliasEq` obligation instead of attempting to determine equality of projections that may not be as normalized as possible (i.e. because of lazy norm, or just containing inference variables that prevent us from resolving an impl). Only do this when the new solver is enabled
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs29
-rw-r--r--tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs45
-rw-r--r--tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr9
-rw-r--r--tests/ui/traits/new-solver/alias_eq_simple.rs22
-rw-r--r--tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs20
-rw-r--r--tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr9
-rw-r--r--tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs40
-rw-r--r--tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr14
8 files changed, 188 insertions, 0 deletions
diff --git a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs
new file mode 100644
index 00000000000..dc726ba51f9
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs
@@ -0,0 +1,29 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+
+// check that a goal such as `alias-eq(<T as TraitB>::Assoc<bool>, <T as TraitB>::Assoc<?0>)`
+// succeeds with a constraint that `?0 = bool`
+
+// FIXME(deferred_projection_equality): add a test that this is true during coherence
+
+trait TraitA {}
+
+trait TraitB {
+    type Assoc<T: ?Sized>;
+}
+
+impl<T: TraitB> TraitA for (T, T::Assoc<bool>) {}
+
+impl TraitB for i32 {
+    type Assoc<T: ?Sized> = u32;
+}
+
+fn needs_a<T: TraitA>() {}
+
+fn bar<T: TraitB>() {
+    needs_a::<(T, <T as TraitB>::Assoc<_>)>();
+}
+
+fn main() {
+    bar::<i32>();
+}
diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
new file mode 100644
index 00000000000..fd5d0e3b194
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
@@ -0,0 +1,45 @@
+// compile-flags: -Ztrait-solver=next
+
+// check that when computing `alias-eq(<() as Foo<u16, T>>::Assoc, <() as Foo<?0, T>>::Assoc)`
+//  we do not infer `?0 = u8` via the `for<STOP> (): Foo<u8, STOP>` impl or `?0 = u16` by
+// relating substs as either could be a valid solution.
+
+trait Foo<T, STOP> {
+    type Assoc;
+}
+
+impl<STOP> Foo<u8, STOP> for ()
+where
+    (): Foo<u16, STOP>,
+{
+    type Assoc = <() as Foo<u16, STOP>>::Assoc;
+}
+
+impl Foo<u16, i8> for () {
+    type Assoc = u8;
+}
+
+impl Foo<u16, i16> for () {
+    type Assoc = u16;
+}
+
+fn output<T, U>() -> <() as Foo<T, U>>::Assoc
+where
+    (): Foo<T, U>,
+{
+    todo!()
+}
+
+fn incomplete<T>()
+where
+    (): Foo<u16, T>,
+{
+    // `<() as Foo<u16, STOP>>::Assoc == <() as Foo<_, STOP>>::Assoc`
+    let _: <() as Foo<u16, T>>::Assoc = output::<_, T>();
+    //~^ error: type annotations needed
+
+    // let _: <() as Foo<u16, T>>::Assoc = output::<u8, T>(); // OK
+    // let _: <() as Foo<u16, T>>::Assoc = output::<u16, T>(); // OK
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr
new file mode 100644
index 00000000000..a6712332c37
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/alias_eq_dont_use_normalizes_to_if_substs_eq.rs:38:41
+   |
+LL |     let _: <() as Foo<u16, T>>::Assoc = output::<_, T>();
+   |                                         ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `output`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/new-solver/alias_eq_simple.rs b/tests/ui/traits/new-solver/alias_eq_simple.rs
new file mode 100644
index 00000000000..6792cf3ce35
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias_eq_simple.rs
@@ -0,0 +1,22 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+
+// test that the new solver can handle `alias-eq(<i32 as TraitB>::Assoc, u32)`
+
+trait TraitA {}
+
+trait TraitB {
+    type Assoc;
+}
+
+impl<T: TraitB> TraitA for (T, T::Assoc) {}
+
+impl TraitB for i32 {
+    type Assoc = u32;
+}
+
+fn needs_a<T: TraitA>() {}
+
+fn main() {
+    needs_a::<(i32, u32)>();
+}
diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs
new file mode 100644
index 00000000000..d4cc380fa21
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+
+// check that a `alias-eq(<?0 as TraitB>::Assoc, <T as TraitB>::Assoc)` goal fails.
+
+// FIXME(deferred_projection_equality): add a test that this is true during coherence
+
+trait TraitB {
+    type Assoc;
+}
+
+fn needs_a<T: TraitB>() -> T::Assoc {
+    unimplemented!()
+}
+
+fn bar<T: TraitB>() {
+    let _: <_ as TraitB>::Assoc = needs_a::<T>();
+    //~^ error: type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr
new file mode 100644
index 00000000000..d063d8fce11
--- /dev/null
+++ b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/alias_eq_substs_eq_not_intercrate.rs:16:12
+   |
+LL |     let _: <_ as TraitB>::Assoc = needs_a::<T>();
+   |            ^^^^^^^^^^^^^^^^^^^^ cannot infer type for associated type `<_ as TraitB>::Assoc`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs
new file mode 100644
index 00000000000..46343241b45
--- /dev/null
+++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs
@@ -0,0 +1,40 @@
+// [no_self_infer] check-pass
+// compile-flags: -Ztrait-solver=next
+// revisions: self_infer no_self_infer
+
+// checks that the new solver is smart enough to infer `?0 = U` when solving:
+// `normalizes-to(<Vec<?0> as Trait>::Assoc, u8)`
+// with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when
+// there is a separate `Vec<T>: Trait` bound  in the paramenv.
+//
+// FIXME(-Ztrait-solver=next)
+// This could also compile for `normalizes-to(<?0 as Trait>::Assoc, u8)` but
+// we currently immediately consider a goal ambiguous if the self type is an
+// inference variable.
+
+trait Trait {
+    type Assoc;
+}
+
+fn foo<T: Trait<Assoc = u8>>(x: T) {}
+
+#[cfg(self_infer)]
+fn unconstrained<T>() -> T {
+    todo!()
+}
+
+#[cfg(no_self_infer)]
+fn unconstrained<T>() -> Vec<T> {
+    todo!()
+}
+
+fn bar<T, U>()
+where
+    Vec<T>: Trait,
+    Vec<U>: Trait<Assoc = u8>,
+{
+    foo(unconstrained())
+    //[self_infer]~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr
new file mode 100644
index 00000000000..06283201261
--- /dev/null
+++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+  --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:36:5
+   |
+LL |     foo(unconstrained())
+   |     ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
+   |
+help: consider specifying the generic argument
+   |
+LL |     foo::<T>(unconstrained())
+   |        +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.