Description
if we have A == alias == B
and A
and B
are partially inferred, AliasRelate
is weaker than the current eager_inference_replacement
.
Due to our new approach to generalization in rust-lang/rust#119106 this example now compiles in the new solver. While the underlying issue is still not fixed, it feels incredibly hard to trigger now.
use std::marker::PhantomData;
#[derive(Default)]
struct Foo<T, U>(PhantomData<(T, U)>);
trait Trait {
type Assoc;
fn to_assoc(self) -> Self::Assoc;
}
impl Trait for Foo<u32, i32> {
type Assoc = Foo<u32, i32>;
fn to_assoc(self) -> Self::Assoc {
Foo(PhantomData)
}
}
impl Trait for Foo<i32, u32> {
type Assoc = Foo<i32, u32>;
fn to_assoc(self) -> Self::Assoc {
Foo(PhantomData)
}
}
fn main() {
let mut x: Foo<_, _> = Default::default();
let mut assoc = x.to_assoc();
assoc = Foo::<u32, _>(PhantomData);
assoc = Foo::<_, i32>(PhantomData);
x = assoc;
}
passes on stable, results in the following error with the new solver
error[E0282]: type annotations needed
--> <source>:26:12
|
26 | let x: Foo<_, _> = Default::default();
| ^^^^^^^^^ cannot infer type for struct `Foo<_, _>`
error[E0283]: type annotations needed
--> <source>:27:23
|
27 | let mut assoc = x.to_assoc();
| ^^^^^^^^
|
note: multiple `impl`s satisfying `Foo<_, _>: Trait` found
--> <source>:12:1
|
12 | impl Trait for Foo<u32, i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
18 | impl Trait for Foo<i32, u32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: try using a fully qualified path to specify the expected types
|
27 | let mut assoc = <Foo<_, _> as Trait>::to_assoc(x);
| +++++++++++++++++++++++++++++++ ~
The new solver has 3 obligations: AliasRelate(<Foo<_, _> as Trait>::Assoc, Foo<u32, _>)
and AliasRelate(<Foo<_, _> as Trait>::Assoc, Foo<_, i32>)
and then AliasRelate(<Foo<_, _> as Trait>::Assoc, Foo<_, _>)
from the assignment x == assoc
.
TODO: I expect us to keep shallow norm inside of the trait solver, so we need to add a test where we this happens while proving some goal