associated_type_defaults
are unsound in the new solver · Issue #46 · rust-lang/trait-system-refactor-initiative (original) (raw)
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:📑:Sized>, polarity:Positive), bound_vars: [] }, depth=0),
Obligation(predicate=Binder { value: TraitPredicate(<<Self as Tr>::Ty as std:📑: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.