Skip to content

Idea: default types for traits #2211

Open
@canndrew

Description

@canndrew

Some types are only visible through the traits that they implement. Currently, when Rust cannot infer a type it will either raise an error or, in some unclearly-defined situations, default the type to ! (or ()). Perhaps we could allow defaulting in more situations and allow the defaulting to be trait-directed.

For example, the signature of Iterator::unzip is:

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Iterator<Item = (A, B)>, 

Now suppose I write:

let (_, foo) = some_iterator.unzip();
...
for x in foo {
    ...
}

If I haven't touched foo anywhere else my code, then this won't compile. All rust knows about foo's type is that it must impl Default + Extend<X> + IntoIterator<Item=X>, and there may be lots of types that satisfy this requirement. However Vec<X> is, in some sense, the canonical type that satisfies these requirements - when iterated it gives back the exact same items that where .extend-ed into it, in the exact same order. Perhaps the compiler should be able to infer Vec<X> in this case. Perhaps the standard library should be able to specify Vec<X> as the inferred type in cases like this with a declaration like:

default<A> Default + Extend<A> + IntoIterator<Item=A> = Vec<A>;

Multiple default declarations could override each other by being more specific in much the same way that impl specialization works. When the compiler tries to default a type which satisfies some required bounds B, it looks for the most specific trait A <: B for which there is a default type, and uses that type if it satisfies B.

The current behaviour of defaulting to ! could be replaced by a declaration in libcore of:

default ?Sized = !;

There could also be default of (just for example):

default Default = ();

So, is this a good idea? Or is it terrible?

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions