mozilla/rust — pull request #13702 by eddyb (2014-04-23 10:00:02+00:00)
Title: Use defaults from formal type parameters in type inference, as fallbacks.

This enables more powerful uses of default type params, while maintaining backwards compatibility.
```rust
// A simple function example.
fn foo() -> T {Default::default()}
println!("{}", foo());

// Making constructors generic over type params, falling back to a default.
// This allows making, e.g. containers parametric over an allocator without
// affecting existing code bases and without using different constructors.
#[deriving(Default)]
struct Heap;
struct Vec(A);
impl Vec {
fn new() -> Vec {
Vec(Default::default())
}
fn push(&self, _: T) {}
}

// error: mismatched types: expected `main::Vec<>` but found `()`
let () = Vec::new(); // ^^ the error message omits A, it was inferred to Heap

let v = Vec::new();
v.push(5u);
// error: mismatched types: expected `main::Vec` but found `()`
let () = v; // ^^ fully inferred type (again omitting A)

let v: Vec<_, char> = Vec::new();
v.push(5u);
// error: mismatched types: expected `main::Vec` but found `()`
let () = v; // ^^ overriding the defaults still works
```
**Disclaimer**: the current implementation is only a proof of concept, missing substitution (for ``) and any form of lifetime environment (for `<'a, T = &'a int>`).
Also, I somehow managed to break overriding the defaults (the last example doesn't actually compile).
It seems odd given that fallbacls should only be used when `force_tvar` is set, and that shouldn't happen for `let v: Vec<_, char> = Vec::new();` (otherwise our inference would be unusable).