Open
Description
the concept of a "non-defining use" is fragile. It is highly likely to change when moving to the new solver, see the discussion starting in https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2023-06-12.20TAIT.20in.20new.20solver/near/365587211
// passes with old impl, ambiguous with the new one.
#![feature(type_alias_impl_trait)]
trait Trait {
type Assoc;
}
impl<T: Copy> Trait for T {
type Assoc = T;
}
fn needs_trait<T: Trait<Assoc = T>>() {}
type Tait = impl Copy;
fn define() -> Tait {}
fn check() {
needs_trait::<Tait>();
//[new]~^ ERROR type annotations needed
//[new]~| NOTE cannot satisfy `<Tait as Trait>::Assoc == Tait`
}
fn main() {}
this is ambiguous due to
- prove
<Tait as Trait>::Assoc = Tait
(uses<Tait as Trait>::Assoc = ?projection_term
)- impl candidate using TAIT
- assemble candidates after normalizing self ty:
Tait => ?new_infer
(ambiguity because self type is an infer var) - impl candidate and ambiguity for ambig self types (winnowing fails: could have
u32: Trait<Assoc = u32>
in env)
as stated in https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/lcnr.20oli.20meeting/near/370712246 I would instead like to forbid non-defining uses in the defining scope, at least until we finished switching the solvers.