Skip to content

associated_type_defaults are unsound in the new solver #46

Closed
@compiler-errors

Description

@compiler-errors

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions