Skip to content

treatment of subtyping in trait matching is unsound #5781

Closed
@nikomatsakis

Description

@nikomatsakis

We currently assume (at least in vtable.rs. though not in infer) that self types are contravariant. This is not sound since the Self type can appear anywhere, including return types.

For example, this program compiles:

trait Make {
    fn make() -> Self;
}

impl Make for *const uint {
    fn make() -> *const uint {
        ptr::null()
    }
}

fn maker<M:Make>() -> M {
    Make::make()
}

fn main() {
    let a: *uint = maker::<*uint>();
}

Note that we have "produced" a *uint even though there is no function in this program that returns one. In this case, it's harmless, but of course one can construct other more harmful examples (particularly if we add other forms of subtyping such as struct inheritance or datasort refinements).

The fix is a straight-forward modification (search for FIXMEs) but it invalidates a number of existing impls based around *const T and I didn't feel like dealing with the fallout as part of the patch I'm working on.

See also #3598---effectively we need a way to infer/declare variance for the Self parameter as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions