Skip to content

associated_type_defaults are unsound in the new solver #46

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions