Skip to content

AliasRelate hides info in transitive cases  #7

Open
@lcnr

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

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions