rust-lang / trait-system-refactor-initiative

The Rustc Trait System Refactor Initiative
21 stars 0 forks source link

normalizes-to for projections ignores term when choosing candidates #22

Open lcnr opened 1 year ago

lcnr commented 1 year ago

// When we're solving `<T as Foo>::Assoc = i32`, we actually first solve
// `<T as Foo>::Assoc = ?1t`, then unify `?1t` with `i32`. That goal
// with the inference variable is ambiguous when there are >1 param-env
// candidates.

// We don't unify the RHS of a projection goal eagerly when solving, both
// for caching reasons and partly to make sure that we don't make the new
// trait solver smarter than it should be.

// This is (as far as I can tell) a forwards-compatible decision, but if you
// make this test go from fail to pass, be sure you understand the implications!

trait Foo {
    type Assoc;
}

trait Bar {}

impl<T> Bar for T where T: Foo<Assoc = i32> {}

fn needs_bar<T: Bar>() {}

fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() {
    needs_bar::<T>();
    //~^ ERROR type annotations needed: cannot satisfy `T: Bar`
}

fn main() {}

Feels pretty desirable to me and is backcompat to change later. Keeps the existing behavior of the old solver. We do this by replacing the expected term of NormalizesTo goals with inference variables before evaluating the QueryInput. This means that inside of the goal, the actual expected type is unknowable.