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
This commit is contained in:
commit
1623ab0246
46 changed files with 585 additions and 163 deletions
|
|
@ -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>();
|
||||
}
|
||||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
22
tests/ui/traits/new-solver/alias_eq_simple.rs
Normal file
22
tests/ui/traits/new-solver/alias_eq_simple.rs
Normal file
|
|
@ -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)>();
|
||||
}
|
||||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue