rust-lang/rust#110673 attempted to make alias bounds sound in the new solver by only assembling alias bounds for a projection (such as <A as B>::C) when the trait that the projection comes from (<A as B>) can be satisfied via a param-env candidate.
This is problematic when checking whether an associated type default is well-formed, because we assume within the trait that Self: Trait<..> holds.
// compile-flags: -Ztrait-solver=next
#![feature(associated_type_defaults)]
trait Tr {
type Ty: Copy = String;
fn clone(x: &Self::Ty) -> Self::Ty {
*x
}
}
impl Tr for () {}
fn main() {
let x = String::from("hello, world");
let y = <() as Tr>::clone(&x);
drop(x);
println!("{y}");
// ^^
}
During check_type_bounds in the above program, we must prove:
[
Obligation(predicate=Binder { value: TraitPredicate(<<Self as Tr>::Ty as std::marker::Sized>, polarity:Positive), bound_vars: [] }, depth=0),
Obligation(predicate=Binder { value: TraitPredicate(<<Self as Tr>::Ty as std::marker::Copy>, polarity:Positive), bound_vars: [] }, depth=0),
]
given the caller bounds of:
[
Binder { value: TraitPredicate(<Self as Tr>, polarity:Positive), bound_vars: [] },
]
Which means that the check implemented in EvalCtxt::validate_alias_bound_self_from_param_env succeeds.
rust-lang/rust#110673 attempted to make alias bounds sound in the new solver by only assembling alias bounds for a projection (such as
<A as B>::C) when the trait that the projection comes from (<A as B>) can be satisfied via a param-env candidate.This is problematic when checking whether an associated type default is well-formed, because we assume within the trait that
Self: Trait<..>holds.During
check_type_boundsin the above program, we must prove:given the caller bounds of:
Which means that the check implemented in
EvalCtxt::validate_alias_bound_self_from_param_envsucceeds.