rust-lang / rust-lang/rfcs

Idea: default types for traits

Open
#2,211 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

T-lang
Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

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?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the proposed default declarations and the Iterator::unzip example in this issue. Investigate how Rust currently handles unconstrained type inference and defaulting, then determine whether trait-directed defaults have a sufficiently defined model and implementation scope. Done would require a concrete, accepted design rather than a small code edit.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.