Auto merge of #26870 - jroesch:default-typaram-fallback, r=nikomatsakis
This PR completes [RFC 213](https://github.com/rust-lang/rfcs/blob/master/text/0213-defaulted-type-params.md) by allowing default type parameters to influence inference. This is almost certainly a breaking change due to interactions between default type parameters and the old fallback algorithm used for integral and floating point literals. The error messages still require polish but I wanted to get early review and feedback from others on the the changes, error messages, and test cases. I also imagine we will want to run anywhere from 1-3 versions of this on crater and evaluate the impact, and it would be best to get that ball rolling. The only outstanding issue I'm aware of is that type alias defaults don't work. It seems this may require significant restructuring, since during inference type aliases have already been expanded. @nikomatsakis might be able to provide some clarity here. r? @nikomatsakis cc @eddyb @Gankro @aturon @brson
This commit is contained in:
commit
a5c12f4e39
31 changed files with 952 additions and 120 deletions
19
src/test/auxiliary/default_ty_param_cross_crate_crate.rs
Normal file
19
src/test/auxiliary/default_ty_param_cross_crate_crate.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![crate_name = "default_param_test"]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct Foo<A, B>(PhantomData<(A, B)>);
|
||||
|
||||
pub fn bleh<A=i32, X=char>() -> Foo<A, X> { Foo(PhantomData) }
|
||||
|
||||
32
src/test/compile-fail/default_ty_param_conflict.rs
Normal file
32
src/test/compile-fail/default_ty_param_conflict.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
// Example from the RFC
|
||||
fn foo<F:Default=usize>() -> F { F::default() }
|
||||
//~^ NOTE: a default was defined here...
|
||||
|
||||
fn bar<B:Debug=isize>(b: B) { println!("{:?}", b); }
|
||||
//~^ NOTE: a second default was defined here...
|
||||
|
||||
fn main() {
|
||||
// Here, F is instantiated with $0=uint
|
||||
let x = foo();
|
||||
//~^ ERROR: mismatched types
|
||||
//~| NOTE: conflicting type parameter defaults `usize` and `isize`
|
||||
//~| NOTE: ...that was applied to an unconstrained type variable here
|
||||
|
||||
// Here, B is instantiated with $1=uint, and constraint $0 <: $1 is added.
|
||||
bar(x);
|
||||
//~^ NOTE: ...that also applies to the same type variable here
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
//aux-build:default_ty_param_cross_crate_crate.rs
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
extern crate default_param_test;
|
||||
|
||||
use default_param_test::{Foo, bleh};
|
||||
|
||||
fn meh<X, B=bool>(x: Foo<X, B>) {}
|
||||
//~^ NOTE: a default was defined here...
|
||||
|
||||
fn main() {
|
||||
let foo = bleh();
|
||||
//~^ NOTE: ...that also applies to the same type variable here
|
||||
|
||||
meh(foo);
|
||||
//~^ ERROR: mismatched types:
|
||||
//~| NOTE: conflicting type parameter defaults `bool` and `char`
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
trait Id {
|
||||
type This;
|
||||
}
|
||||
|
||||
impl<A> Id for A {
|
||||
type This = A;
|
||||
}
|
||||
|
||||
struct Foo<X: Default = usize, Y = <X as Id>::This> {
|
||||
data: PhantomData<(X, Y)>
|
||||
}
|
||||
|
||||
impl<X: Default, Y> Foo<X, Y> {
|
||||
fn new() -> Foo<X, Y> {
|
||||
Foo { data: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo = Foo::new();
|
||||
}
|
||||
19
src/test/run-pass/default_ty_param_dependent_defaults.rs
Normal file
19
src/test/run-pass/default_ty_param_dependent_defaults.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct Foo<T,U=T> { t: T, data: PhantomData<U> }
|
||||
|
||||
fn main() {
|
||||
let foo = Foo { t: 'a', data: PhantomData };
|
||||
}
|
||||
24
src/test/run-pass/default_ty_param_method_call_test.rs
Normal file
24
src/test/run-pass/default_ty_param_method_call_test.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn method<A:Default=String>(&self) -> A {
|
||||
A::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f = Foo.method();
|
||||
println!("{}", f);
|
||||
}
|
||||
23
src/test/run-pass/default_ty_param_struct.rs
Normal file
23
src/test/run-pass/default_ty_param_struct.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
struct Foo<A>(A);
|
||||
|
||||
impl<A:Default=i32> Foo<A> {
|
||||
fn new() -> Foo<A> {
|
||||
Foo(A::default())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo = Foo::new();
|
||||
}
|
||||
40
src/test/run-pass/default_ty_param_struct_and_type_alias.rs
Normal file
40
src/test/run-pass/default_ty_param_struct_and_type_alias.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct DeterministicHasher;
|
||||
struct RandomHasher;
|
||||
|
||||
|
||||
struct MyHashMap<K, V, H=DeterministicHasher> {
|
||||
data: PhantomData<(K, V, H)>
|
||||
}
|
||||
|
||||
impl<K, V, H> MyHashMap<K, V, H> {
|
||||
fn new() -> MyHashMap<K, V, H> {
|
||||
MyHashMap { data: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
mod mystd {
|
||||
use super::{MyHashMap, RandomHasher};
|
||||
pub type HashMap<K, V, H=RandomHasher> = MyHashMap<K, V, H>;
|
||||
}
|
||||
|
||||
fn try_me<H>(hash_map: mystd::HashMap<i32, i32, H>) {}
|
||||
|
||||
fn main() {
|
||||
let hash_map = mystd::HashMap::new();
|
||||
try_me(hash_map);
|
||||
}
|
||||
25
src/test/run-pass/default_ty_param_trait_impl.rs
Normal file
25
src/test/run-pass/default_ty_param_trait_impl.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
// Another example from the RFC
|
||||
trait Foo { }
|
||||
trait Bar { }
|
||||
|
||||
impl<T:Bar=usize> Foo for Vec<T> {}
|
||||
impl Bar for usize {}
|
||||
|
||||
fn takes_foo<F:Foo>(f: F) {}
|
||||
|
||||
fn main() {
|
||||
let x = Vec::new(); // x: Vec<$0>
|
||||
takes_foo(x); // adds oblig Vec<$0> : Foo
|
||||
}
|
||||
26
src/test/run-pass/default_ty_param_trait_impl_simple.rs
Normal file
26
src/test/run-pass/default_ty_param_trait_impl_simple.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
// An example from the RFC
|
||||
trait Foo { fn takes_foo(&self); }
|
||||
trait Bar { }
|
||||
|
||||
impl<T:Bar=usize> Foo for Vec<T> {
|
||||
fn takes_foo(&self) {}
|
||||
}
|
||||
|
||||
impl Bar for usize {}
|
||||
|
||||
fn main() {
|
||||
let x = Vec::new(); // x: Vec<$0>
|
||||
x.takes_foo(); // adds oblig Vec<$0> : Foo
|
||||
}
|
||||
19
src/test/run-pass/default_ty_param_type_alias.rs
Normal file
19
src/test/run-pass/default_ty_param_type_alias.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
type IntMap<K=usize> = HashMap<K, usize>;
|
||||
|
||||
fn main() {
|
||||
let x = IntMap::new();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue