auto merge of #20307 : nikomatsakis/rust/assoc-types-normalization-extend-bound, r=nrc
Rewrite associated types to use projection rather than dummy type parameters. This closes almost every (major) open issue, but I'm holding off on that until the code has landed and baked a bit. Probably it should have more tests, as well, but I wanted to get this landed as fast as possible so that we can collaborate on improving it. The commit history is a little messy, particularly the merge commit at the end. If I get some time, I might just "reset" to the beginning and try to carve up the final state into logical pieces. Let me know if it seems hard to follow. By far the most crucial commit is "Implement associated type projection and normalization." r? @nick29581
This commit is contained in:
commit
84f5ad8679
129 changed files with 5537 additions and 3126 deletions
27
src/test/auxiliary/associated-types-cc-lib.rs
Normal file
27
src/test/auxiliary/associated-types-cc-lib.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Helper for test issue-18048, which tests associated types in a
|
||||
// cross-crate scenario.
|
||||
|
||||
#![crate_type="lib"]
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Bar {
|
||||
type T;
|
||||
|
||||
fn get(x: Option<Self>) -> <Self as Bar>::T;
|
||||
}
|
||||
|
||||
impl Bar for int {
|
||||
type T = uint;
|
||||
|
||||
fn get(_: Option<int>) -> uint { 22 }
|
||||
}
|
||||
39
src/test/compile-fail/associated-types-bound-failure.rs
Normal file
39
src/test/compile-fail/associated-types-bound-failure.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test equality constraints on associated types in a where clause.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait ToInt {
|
||||
fn to_int(&self) -> int;
|
||||
}
|
||||
|
||||
pub trait GetToInt
|
||||
{
|
||||
type R;
|
||||
|
||||
fn get(&self) -> <Self as GetToInt>::R;
|
||||
}
|
||||
|
||||
fn foo<G>(g: G) -> int
|
||||
where G : GetToInt
|
||||
{
|
||||
ToInt::to_int(&g.get()) //~ ERROR not implemented
|
||||
}
|
||||
|
||||
fn bar<G : GetToInt>(g: G) -> int
|
||||
where G::R : ToInt
|
||||
{
|
||||
ToInt::to_int(&g.get()) // OK
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ impl Foo for int {
|
|||
fn boo(&self) -> uint { 42 }
|
||||
}
|
||||
|
||||
fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {} //~ERROR equality constraints are not allowed in this
|
||||
fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
|
||||
//~^ ERROR associated type bindings are not allowed here
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -43,6 +43,6 @@ pub fn baz(x: &Foo<A=Bar>) {
|
|||
|
||||
pub fn main() {
|
||||
let a = 42i;
|
||||
foo1(a); //~ERROR the trait `Foo` is not implemented for the type `int`
|
||||
baz(&a); //~ERROR the trait `Foo` is not implemented for the type `int`
|
||||
foo1(a); //~ERROR expected uint, found struct Bar
|
||||
baz(&a); //~ERROR expected uint, found struct Bar
|
||||
}
|
||||
72
src/test/compile-fail/associated-types-eq-hr.rs
Normal file
72
src/test/compile-fail/associated-types-eq-hr.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check testing of equality constraints in a higher-ranked context.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait TheTrait<T> {
|
||||
type A;
|
||||
|
||||
fn get(&self, t: T) -> Self::A;
|
||||
}
|
||||
|
||||
struct IntStruct {
|
||||
x: int
|
||||
}
|
||||
|
||||
impl<'a> TheTrait<&'a int> for IntStruct {
|
||||
type A = &'a int;
|
||||
|
||||
fn get(&self, t: &'a int) -> &'a int {
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
struct UintStruct {
|
||||
x: int
|
||||
}
|
||||
|
||||
impl<'a> TheTrait<&'a int> for UintStruct {
|
||||
type A = &'a uint;
|
||||
|
||||
fn get(&self, t: &'a int) -> &'a uint {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn foo<T>()
|
||||
where T : for<'x> TheTrait<&'x int, A = &'x int>
|
||||
{
|
||||
// ok for IntStruct, but not UintStruct
|
||||
}
|
||||
|
||||
fn bar<T>()
|
||||
where T : for<'x> TheTrait<&'x int, A = &'x uint>
|
||||
{
|
||||
// ok for UintStruct, but not IntStruct
|
||||
}
|
||||
|
||||
fn baz<T>()
|
||||
where T : for<'x,'y> TheTrait<&'x int, A = &'y int>
|
||||
{
|
||||
// not ok for either struct, due to the use of two lifetimes
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
foo::<IntStruct>();
|
||||
foo::<UintStruct>(); //~ ERROR type mismatch
|
||||
|
||||
bar::<IntStruct>(); //~ ERROR type mismatch
|
||||
bar::<UintStruct>();
|
||||
|
||||
baz::<IntStruct>(); //~ ERROR type mismatch
|
||||
baz::<UintStruct>(); //~ ERROR type mismatch
|
||||
}
|
||||
25
src/test/compile-fail/associated-types-for-unimpl-trait.rs
Normal file
25
src/test/compile-fail/associated-types-for-unimpl-trait.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2014 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(associated_types)]
|
||||
|
||||
trait Get {
|
||||
type Value;
|
||||
fn get(&self) -> <Self as Get>::Value;
|
||||
}
|
||||
|
||||
trait Other {
|
||||
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
||||
//~^ ERROR the trait `Get` is not implemented for the type `Self`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
||||
|
|
@ -18,16 +18,6 @@ trait Get {
|
|||
fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
|
||||
//~^ ERROR ambiguous associated type
|
||||
|
||||
trait Other {
|
||||
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
||||
//~^ ERROR no suitable bound on `Self`
|
||||
}
|
||||
|
||||
impl<T:Get> Other for T {
|
||||
fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
|
||||
//~^ ERROR currently unsupported
|
||||
}
|
||||
|
||||
trait Grab {
|
||||
type Value;
|
||||
fn grab(&self) -> Grab::Value;
|
||||
|
|
|
|||
44
src/test/compile-fail/associated-types-incomplete-object.rs
Normal file
44
src/test/compile-fail/associated-types-incomplete-object.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check that the user gets an errror if they omit a binding from an
|
||||
// object type.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo {
|
||||
type A;
|
||||
type B;
|
||||
fn boo(&self) -> <Self as Foo>::A;
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for int {
|
||||
type A = uint;
|
||||
type B = char;
|
||||
fn boo(&self) -> uint {
|
||||
42
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let a = &42i as &Foo<A=uint, B=char>;
|
||||
|
||||
let b = &42i as &Foo<A=uint>;
|
||||
//~^ ERROR the value of the associated type `B` (from the trait `Foo`) must be specified
|
||||
|
||||
let c = &42i as &Foo<B=char>;
|
||||
//~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified
|
||||
|
||||
let d = &42i as &Foo;
|
||||
//~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified
|
||||
//~| ERROR the value of the associated type `B` (from the trait `Foo`) must be specified
|
||||
}
|
||||
|
|
@ -15,16 +15,13 @@ trait Get {
|
|||
fn get(&self) -> <Self as Get>::Value;
|
||||
}
|
||||
|
||||
fn get(x: int) -> <int as Get>::Value {}
|
||||
//~^ ERROR unsupported
|
||||
|
||||
struct Struct {
|
||||
x: int,
|
||||
}
|
||||
|
||||
impl Struct {
|
||||
fn uhoh<T>(foo: <T as Get>::Value) {}
|
||||
//~^ ERROR no suitable bound on `T`
|
||||
//~^ ERROR the trait `Get` is not implemented for the type `T`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 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(associated_types)]
|
||||
|
||||
// Check that we get an error when you use `<Self as Get>::Value` in
|
||||
// the trait definition but `Self` does not, in fact, implement `Get`.
|
||||
|
||||
trait Get {
|
||||
type Value;
|
||||
}
|
||||
|
||||
trait Other {
|
||||
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
|
||||
//~^ ERROR the trait `Get` is not implemented for the type `Self`
|
||||
}
|
||||
|
||||
impl<T:Get> Other for T {
|
||||
fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
|
||||
//~^ ERROR the trait `Get` is not implemented for the type `(T, U)`
|
||||
//~| ERROR the trait `Get` is not implemented for the type `(T, U)`
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -26,9 +26,10 @@ pub fn f2<T: Foo>(a: T) -> T::A {
|
|||
}
|
||||
|
||||
pub fn main() {
|
||||
f1(2i, 4i); //~ERROR the trait `Foo` is not implemented
|
||||
f1(2u, 4u); //~ERROR the trait `Foo` is not implemented
|
||||
f1(2u, 4i); //~ERROR the trait `Foo` is not implemented
|
||||
f1(2i, 4i); //~ ERROR expected uint, found int
|
||||
f1(2i, 4u);
|
||||
f1(2u, 4u); //~ ERROR the trait `Foo` is not implemented
|
||||
f1(2u, 4i); //~ ERROR the trait `Foo` is not implemented
|
||||
|
||||
let _: int = f2(2i); //~ERROR mismatched types: expected `int`, found `uint`
|
||||
let _: int = f2(2i); //~ERROR expected `int`, found `uint`
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test you can't use a higher-ranked trait bound inside of a qualified
|
||||
// path (just won't parse).
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo<T> {
|
||||
type A;
|
||||
|
||||
fn get(&self, t: T) -> Self::A;
|
||||
}
|
||||
|
||||
fn foo2<I>(x: <I as for<'x> Foo<&'x int>>::A)
|
||||
//~^ ERROR expected identifier, found keyword `for`
|
||||
//~| ERROR expected one of `::` or `>`
|
||||
{
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check projection of an associated type out of a higher-ranked
|
||||
// trait-bound in the context of a function body.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo<T> {
|
||||
type A;
|
||||
|
||||
fn get(&self, t: T) -> Self::A;
|
||||
}
|
||||
|
||||
fn foo<'a, I : for<'x> Foo<&'x int>>(
|
||||
x: <I as Foo<&'a int>>::A)
|
||||
{
|
||||
let y: I::A = x;
|
||||
}
|
||||
|
||||
fn bar<'a, 'b, I : for<'x> Foo<&'x int>>(
|
||||
x: <I as Foo<&'a int>>::A,
|
||||
y: <I as Foo<&'b int>>::A,
|
||||
cond: bool)
|
||||
{ //~ ERROR cannot infer
|
||||
// x and y here have two distinct lifetimes:
|
||||
let z: I::A = if cond { x } else { y };
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check projection of an associated type out of a higher-ranked trait-bound
|
||||
// in the context of a function signature.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo<T> {
|
||||
type A;
|
||||
|
||||
fn get(&self, t: T) -> Self::A;
|
||||
}
|
||||
|
||||
fn foo2<I : for<'x> Foo<&'x int>>(
|
||||
x: I::A)
|
||||
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
||||
{
|
||||
// This case is illegal because we have to instantiate `'x`, and
|
||||
// we don't know what region to instantiate it with.
|
||||
//
|
||||
// This could perhaps be made equivalent to the examples below,
|
||||
// specifically for fn signatures.
|
||||
}
|
||||
|
||||
fn foo3<I : for<'x> Foo<&'x int>>(
|
||||
x: <I as Foo<&int>>::A)
|
||||
{
|
||||
// OK, in this case we spelled out the precise regions involved, though we left one of
|
||||
// them anonymous.
|
||||
}
|
||||
|
||||
fn foo4<'a, I : for<'x> Foo<&'x int>>(
|
||||
x: <I as Foo<&'a int>>::A)
|
||||
{
|
||||
// OK, in this case we spelled out the precise regions involved.
|
||||
}
|
||||
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check projection of an associated type out of a higher-ranked trait-bound
|
||||
// in the context of a struct definition.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo<T> {
|
||||
type A;
|
||||
|
||||
fn get(&self, t: T) -> Self::A;
|
||||
}
|
||||
|
||||
struct SomeStruct<I : for<'x> Foo<&'x int>> {
|
||||
field: I::A
|
||||
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
||||
}
|
||||
|
||||
struct AnotherStruct<I : for<'x> Foo<&'x int>> {
|
||||
field: <I as Foo<&int>>::A
|
||||
//~^ ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
struct YetAnotherStruct<'a, I : for<'x> Foo<&'x int>> {
|
||||
field: <I as Foo<&'a int>>::A
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check projection of an associated type out of a higher-ranked trait-bound
|
||||
// in the context of a method definition in a trait.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo<T> {
|
||||
type A;
|
||||
|
||||
fn get(&self, t: T) -> Self::A;
|
||||
}
|
||||
|
||||
trait SomeTrait<I : for<'x> Foo<&'x int>> {
|
||||
fn some_method(&self, arg: I::A);
|
||||
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
||||
}
|
||||
|
||||
trait AnotherTrait<I : for<'x> Foo<&'x int>> {
|
||||
fn some_method(&self, arg: <I as Foo<&int>>::A);
|
||||
}
|
||||
|
||||
trait YetAnotherTrait<I : for<'x> Foo<&'x int>> {
|
||||
fn some_method<'a>(&self, arg: <I as Foo<&'a int>>::A);
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -8,6 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test an example where we fail to infer the type parameter H. This
|
||||
// is because there is really nothing constraining it. At one time, we
|
||||
// would infer based on the where clauses in scope, but that no longer
|
||||
// works.
|
||||
|
||||
trait Hash<H> {
|
||||
fn hash2(&self, hasher: &H) -> u64;
|
||||
}
|
||||
|
|
@ -30,7 +35,7 @@ trait StreamHash<S: Stream, H: StreamHasher<S>>: Hash<H> {
|
|||
impl<S: Stream, H: StreamHasher<S>> Hash<H> for u8 {
|
||||
fn hash2(&self, hasher: &H) -> u64 {
|
||||
let mut stream = hasher.stream();
|
||||
self.input_stream(&mut stream);
|
||||
self.input_stream(&mut stream); //~ ERROR type annotations required
|
||||
stream.result()
|
||||
}
|
||||
}
|
||||
|
|
@ -12,8 +12,6 @@ fn main() {
|
|||
return
|
||||
{ return () }
|
||||
//~^ ERROR the type of this value must be known in this context
|
||||
//~| ERROR this function takes 1 parameter
|
||||
//~| ERROR mismatched types
|
||||
()
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ fn mapping<'f, R, T, U>(f: |T|: 'f -> U) -> &'f Transducer<'f, R, T, U> {
|
|||
|step| |r, x|
|
||||
step(r, f(x))
|
||||
//~^ ERROR the type of this value must be known in this context
|
||||
//~| ERROR this function takes 1 parameter but 2 parameters were supplied
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,4 @@
|
|||
fn main() {
|
||||
(return)((),());
|
||||
//~^ ERROR the type of this value must be known
|
||||
//~| ERROR this function takes 1 parameter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,9 @@
|
|||
|
||||
#![feature(associated_types)]
|
||||
|
||||
fn add_state(op:
|
||||
<int as HasState>::State
|
||||
//~^ ERROR it is currently unsupported to access associated types except through a type parameter
|
||||
) {}
|
||||
fn add_state(op: <int as HasState>::State) {
|
||||
//~^ ERROR the trait `HasState` is not implemented for the type `int`
|
||||
}
|
||||
|
||||
trait HasState {
|
||||
type State;
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ enum Boo {
|
|||
Quux(Bar<uint>),
|
||||
}
|
||||
|
||||
struct Badness<T> {
|
||||
struct Badness<U> {
|
||||
//~^ ERROR not implemented
|
||||
b: Foo<T>,
|
||||
b: Foo<U>,
|
||||
}
|
||||
|
||||
enum MoreBadness<T> {
|
||||
enum MoreBadness<V> {
|
||||
//~^ ERROR not implemented
|
||||
EvenMoreBadness(Bar<T>),
|
||||
EvenMoreBadness(Bar<V>),
|
||||
}
|
||||
|
||||
trait PolyTrait<T> {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Issue #3902. We are (at least currently) unable to infer `Self`
|
||||
// based on `T`, even though there is only a single impl, because of
|
||||
// the possibility of associated types and other things (basically: no
|
||||
// constraints on `Self` here at all).
|
||||
|
||||
mod base {
|
||||
pub trait HasNew<T> {
|
||||
fn new() -> T;
|
||||
|
|
@ -22,19 +27,11 @@ mod base {
|
|||
Foo { dummy: () }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bar {
|
||||
dummy: (),
|
||||
}
|
||||
|
||||
impl HasNew<Bar> for Bar {
|
||||
fn new() -> Bar {
|
||||
Bar { dummy: () }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
pub fn foo() {
|
||||
let _f: base::Foo = base::HasNew::new();
|
||||
let _b: base::Bar = base::HasNew::new();
|
||||
//~^ ERROR type annotations required
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -21,7 +21,7 @@ unsafe fn f() {
|
|||
|
||||
unsafe fn g<T>(x: &T) {
|
||||
let _: i8 = transmute(x);
|
||||
//~^ ERROR transmute called on types with different sizes
|
||||
//~^ ERROR transmute called on types with potentially different sizes
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
41
src/test/compile-fail/transmute-fat-pointers.rs
Normal file
41
src/test/compile-fail/transmute-fat-pointers.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
// Tests that are conservative around thin/fat pointer mismatches.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
fn a<T, Sized? U>(x: &[T]) -> &U {
|
||||
unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
|
||||
}
|
||||
|
||||
fn b<Sized? T, Sized? U>(x: &T) -> &U {
|
||||
unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
|
||||
}
|
||||
|
||||
fn c<T, U>(x: &T) -> &U {
|
||||
unsafe { transmute(x) }
|
||||
}
|
||||
|
||||
fn d<T, U>(x: &[T]) -> &[U] {
|
||||
unsafe { transmute(x) }
|
||||
}
|
||||
|
||||
fn e<Sized? T, U>(x: &T) -> &U {
|
||||
unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
|
||||
}
|
||||
|
||||
fn f<T, Sized? U>(x: &T) -> &U {
|
||||
unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
33
src/test/compile-fail/transmute-impl.rs
Normal file
33
src/test/compile-fail/transmute-impl.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Tests that are conservative around thin/fat pointer mismatches.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
struct Foo<Sized? T> {
|
||||
t: Box<T>
|
||||
}
|
||||
|
||||
impl<Sized? T> Foo<T> {
|
||||
fn m(x: &T) -> &int where T : Sized {
|
||||
// OK here, because T : Sized is in scope.
|
||||
unsafe { transmute(x) }
|
||||
}
|
||||
|
||||
fn n(x: &T) -> &int {
|
||||
// Not OK here, because T : Sized is not in scope.
|
||||
unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
20
src/test/compile-fail/unsized-inherent-impl-self-type.rs
Normal file
20
src/test/compile-fail/unsized-inherent-impl-self-type.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test sized-ness checking in substitution in impls.
|
||||
|
||||
// impl - struct
|
||||
|
||||
struct S5<Y>;
|
||||
|
||||
impl<Sized? X> S5<X> { //~ ERROR not implemented
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
22
src/test/compile-fail/unsized-trait-impl-self-type.rs
Normal file
22
src/test/compile-fail/unsized-trait-impl-self-type.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test sized-ness checking in substitution in impls.
|
||||
|
||||
// impl - struct
|
||||
trait T3<Sized? Z> {
|
||||
}
|
||||
|
||||
struct S5<Y>;
|
||||
|
||||
impl<Sized? X> T3<X> for S5<X> { //~ ERROR not implemented
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
21
src/test/compile-fail/unsized-trait-impl-trait-arg.rs
Normal file
21
src/test/compile-fail/unsized-trait-impl-trait-arg.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test sized-ness checking in substitution in impls.
|
||||
|
||||
// impl - unbounded
|
||||
trait T2<Z> {
|
||||
}
|
||||
struct S4<Sized? Y>;
|
||||
impl<Sized? X> T2<X> for S4<X> {
|
||||
//~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -11,8 +11,9 @@
|
|||
// Test that bounds are sized-compatible.
|
||||
|
||||
trait T {}
|
||||
|
||||
fn f<Sized? Y: T>() {
|
||||
//~^ERROR incompatible bounds on type parameter `Y`, bound `T` does not allow unsized type
|
||||
//~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
|
|
|||
|
|
@ -21,23 +21,4 @@ impl<Sized? X: T> T1<X> for S3<X> {
|
|||
//~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
|
||||
}
|
||||
|
||||
// impl - unbounded
|
||||
trait T2<Z> {
|
||||
}
|
||||
struct S4<Sized? Y>;
|
||||
impl<Sized? X> T2<X> for S4<X> {
|
||||
//~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
|
||||
}
|
||||
|
||||
// impl - struct
|
||||
trait T3<Sized? Z> {
|
||||
}
|
||||
struct S5<Y>;
|
||||
impl<Sized? X> T3<X> for S5<X> { //~ ERROR not implemented
|
||||
}
|
||||
|
||||
impl<Sized? X> S5<X> { //~ ERROR not implemented
|
||||
}
|
||||
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
// Regions that just appear in normal spots are contravariant:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[];[];[]]
|
||||
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[];[]]
|
||||
x: &'a int,
|
||||
y: &'b [int],
|
||||
c: &'c str
|
||||
|
|
@ -23,7 +23,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[];[];[]]
|
|||
// Those same annotations in function arguments become covariant:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[];[];[]]
|
||||
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[];[]]
|
||||
x: extern "Rust" fn(&'a int),
|
||||
y: extern "Rust" fn(&'b [int]),
|
||||
c: extern "Rust" fn(&'c str),
|
||||
|
|
@ -32,7 +32,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[];[];[]]
|
|||
// Mutability induces invariance:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[];[];[]]
|
||||
struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[];[]]
|
||||
x: &'a mut &'b int,
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[];[];[]]
|
|||
// contravariant context:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test5<'a, 'b> { //~ ERROR regions=[[+, o];[];[];[]]
|
||||
struct Test5<'a, 'b> { //~ ERROR regions=[[+, o];[];[]]
|
||||
x: extern "Rust" fn(&'a mut &'b int),
|
||||
}
|
||||
|
||||
|
|
@ -50,21 +50,21 @@ struct Test5<'a, 'b> { //~ ERROR regions=[[+, o];[];[];[]]
|
|||
// argument list occurs in an invariant context.
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[];[]]
|
||||
struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]]
|
||||
x: &'a mut extern "Rust" fn(&'b int),
|
||||
}
|
||||
|
||||
// No uses at all is bivariant:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test7<'a> { //~ ERROR regions=[[*];[];[];[]]
|
||||
struct Test7<'a> { //~ ERROR regions=[[*];[];[]]
|
||||
x: int
|
||||
}
|
||||
|
||||
// Try enums too.
|
||||
|
||||
#[rustc_variance]
|
||||
enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[];[]]
|
||||
enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[]]
|
||||
Test8A(extern "Rust" fn(&'a int)),
|
||||
Test8B(&'b [int]),
|
||||
Test8C(&'b mut &'c str),
|
||||
|
|
|
|||
|
|
@ -13,29 +13,29 @@
|
|||
// Try enums too.
|
||||
|
||||
#[rustc_variance]
|
||||
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[];[]]
|
||||
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
|
||||
Test8A(extern "Rust" fn(&'a int)),
|
||||
Test8B(&'b [int]),
|
||||
Test8C(&'b mut &'c str),
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[];[]]
|
||||
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]]
|
||||
f: Base<'z, 'y, 'x, 'w>
|
||||
}
|
||||
|
||||
#[rustc_variance] // Combine - and + to yield o
|
||||
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[];[]]
|
||||
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]]
|
||||
f: Base<'a, 'a, 'b, 'c>
|
||||
}
|
||||
|
||||
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
|
||||
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[];[]]
|
||||
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]]
|
||||
f: Base<'a, 'b, 'a, 'c>
|
||||
}
|
||||
|
||||
#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
|
||||
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[];[]]
|
||||
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[]]
|
||||
f: Base<'a, 'b, 'c, 'a>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use std::mem;
|
|||
trait T { fn foo(); }
|
||||
|
||||
#[rustc_variance]
|
||||
struct TOption<'a> { //~ ERROR regions=[[-];[];[];[]]
|
||||
struct TOption<'a> { //~ ERROR regions=[[-];[];[]]
|
||||
v: Option<Box<T + 'a>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
26
src/test/run-pass/associated-types-basic.rs
Normal file
26
src/test/run-pass/associated-types-basic.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2014 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(associated_types)]
|
||||
|
||||
trait Foo {
|
||||
type T;
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
type T = int;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: <i32 as Foo>::T = 22;
|
||||
let y: int = 44;
|
||||
assert_eq!(x * 2, y);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test equality constraints on associated types in a where clause.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo {
|
||||
type A;
|
||||
fn boo(&self) -> <Self as Foo>::A;
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct Bar;
|
||||
|
||||
impl Foo for int {
|
||||
type A = uint;
|
||||
fn boo(&self) -> uint { 42 }
|
||||
}
|
||||
|
||||
impl Foo for char {
|
||||
type A = Bar;
|
||||
fn boo(&self) -> Bar { Bar }
|
||||
}
|
||||
|
||||
fn foo_bar<I: Foo<A=Bar>>(x: I) -> Bar {
|
||||
x.boo()
|
||||
}
|
||||
|
||||
fn foo_uint<I: Foo<A=uint>>(x: I) -> uint {
|
||||
x.boo()
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let a = 42i;
|
||||
foo_uint(a);
|
||||
|
||||
let a = 'a';
|
||||
foo_bar(a);
|
||||
}
|
||||
53
src/test/run-pass/associated-types-bound.rs
Normal file
53
src/test/run-pass/associated-types-bound.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test equality constraints on associated types in a where clause.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait ToInt {
|
||||
fn to_int(&self) -> int;
|
||||
}
|
||||
|
||||
impl ToInt for int {
|
||||
fn to_int(&self) -> int { *self }
|
||||
}
|
||||
|
||||
impl ToInt for uint {
|
||||
fn to_int(&self) -> int { *self as int }
|
||||
}
|
||||
|
||||
pub trait GetToInt
|
||||
{
|
||||
type R : ToInt;
|
||||
|
||||
fn get(&self) -> <Self as GetToInt>::R;
|
||||
}
|
||||
|
||||
impl GetToInt for int {
|
||||
type R = int;
|
||||
fn get(&self) -> int { *self }
|
||||
}
|
||||
|
||||
impl GetToInt for uint {
|
||||
type R = uint;
|
||||
fn get(&self) -> uint { *self }
|
||||
}
|
||||
|
||||
fn foo<G>(g: G) -> int
|
||||
where G : GetToInt
|
||||
{
|
||||
ToInt::to_int(&g.get())
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(foo(22i), 22i);
|
||||
assert_eq!(foo(22u), 22i);
|
||||
}
|
||||
28
src/test/run-pass/associated-types-cc.rs
Normal file
28
src/test/run-pass/associated-types-cc.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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:associated-types-cc-lib.rs
|
||||
|
||||
// Test that we are able to reference cross-crate traits that employ
|
||||
// associated types.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
extern crate "associated-types-cc-lib" as bar;
|
||||
|
||||
use bar::Bar;
|
||||
|
||||
fn foo<B:Bar>(b: B) -> <B as Bar>::T {
|
||||
Bar::get(None::<B>)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", foo(3i));
|
||||
}
|
||||
|
|
@ -8,25 +8,35 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we correctly infer that `E` must be `()` here. This is
|
||||
// known because there is just one impl that could apply where
|
||||
// `Self=()`.
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait FromError<E> {
|
||||
fn from_error(err: E) -> Self;
|
||||
trait SignedUnsigned {
|
||||
type Opposite;
|
||||
fn convert(self) -> Self::Opposite;
|
||||
}
|
||||
|
||||
impl<E> FromError<E> for E {
|
||||
fn from_error(err: E) -> E {
|
||||
err
|
||||
impl SignedUnsigned for int {
|
||||
type Opposite = uint;
|
||||
|
||||
fn convert(self) -> uint {
|
||||
self as uint
|
||||
}
|
||||
}
|
||||
|
||||
fn test() -> Result<(), ()> {
|
||||
Err(FromError::from_error(()))
|
||||
impl SignedUnsigned for uint {
|
||||
type Opposite = int;
|
||||
|
||||
fn convert(self) -> int {
|
||||
self as int
|
||||
}
|
||||
}
|
||||
|
||||
fn get(x: int) -> <int as SignedUnsigned>::Opposite {
|
||||
x.convert()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let result = (|| Err(FromError::from_error(())))();
|
||||
let foo: () = result.unwrap_or(());
|
||||
let x = get(22);
|
||||
assert_eq!(22u, x);
|
||||
}
|
||||
|
||||
34
src/test/run-pass/associated-types-eq-obj.rs
Normal file
34
src/test/run-pass/associated-types-eq-obj.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test equality constraints on associated types inside of an object type
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Foo {
|
||||
type A;
|
||||
fn boo(&self) -> <Self as Foo>::A;
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for char {
|
||||
type A = Bar;
|
||||
fn boo(&self) -> Bar { Bar }
|
||||
}
|
||||
|
||||
fn baz(x: &Foo<A=Bar>) -> Bar {
|
||||
x.boo()
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let a = 'a';
|
||||
baz(&a);
|
||||
}
|
||||
41
src/test/run-pass/associated-types-normalize-in-bounds.rs
Normal file
41
src/test/run-pass/associated-types-normalize-in-bounds.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Test that we normalize associated types that appear in bounds; if
|
||||
// we didn't, the call to `self.split2()` fails to type check.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
struct Splits<'a, T, P>;
|
||||
struct SplitsN<I>;
|
||||
|
||||
trait SliceExt2 for Sized? {
|
||||
type Item;
|
||||
|
||||
fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
|
||||
where P: FnMut(&Self::Item) -> bool;
|
||||
fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
|
||||
where P: FnMut(&Self::Item) -> bool;
|
||||
}
|
||||
|
||||
impl<T> SliceExt2 for [T] {
|
||||
type Item = T;
|
||||
|
||||
fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
|
||||
self.split2(pred);
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test equality constraints on associated types.
|
||||
// Test equality constraints on associated types in a where clause.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
|
|
@ -17,16 +17,19 @@ pub trait Foo {
|
|||
fn boo(&self) -> <Self as Foo>::A;
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct Bar;
|
||||
|
||||
impl Foo for int {
|
||||
type A = uint;
|
||||
fn boo(&self) -> uint { 42 }
|
||||
}
|
||||
|
||||
impl Foo for Bar {
|
||||
type A = int;
|
||||
fn boo(&self) -> int { 43 }
|
||||
}
|
||||
|
||||
impl Foo for char {
|
||||
type A = Bar;
|
||||
fn boo(&self) -> Bar { Bar }
|
||||
|
|
@ -35,12 +38,10 @@ impl Foo for char {
|
|||
fn foo1<I: Foo<A=Bar>>(x: I) -> Bar {
|
||||
x.boo()
|
||||
}
|
||||
|
||||
fn foo2<I: Foo>(x: I) -> <I as Foo>::A {
|
||||
x.boo()
|
||||
}
|
||||
fn baz(x: &Foo<A=Bar>) -> Bar {
|
||||
x.boo()
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let a = 42i;
|
||||
|
|
@ -51,5 +52,5 @@ pub fn main() {
|
|||
|
||||
let a = 'a';
|
||||
foo1(a);
|
||||
baz(&a);
|
||||
assert!(foo2(a) == Bar);
|
||||
}
|
||||
|
|
@ -8,17 +8,19 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-pretty -- FIXME(#17362) pretty prints as `Hash<<Self as Hasher...` which fails to parse
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
pub trait Hasher{
|
||||
pub trait Hasher {
|
||||
type State;
|
||||
|
||||
fn hash<T: Hash<
|
||||
<Self as Hasher>::State //~ ERROR no suitable bound on `Self`
|
||||
<Self as Hasher>::State
|
||||
>>(&self, value: &T) -> u64;
|
||||
}
|
||||
|
||||
trait Hash<S> {
|
||||
pub trait Hash<S> {
|
||||
fn hash(&self, state: &mut S);
|
||||
}
|
||||
|
||||
|
|
@ -17,6 +17,8 @@ trait Foo {
|
|||
type A;
|
||||
}
|
||||
|
||||
fn bar(x: &Foo) {} //~ERROR missing type for associated type `A`
|
||||
fn bar(x: &Foo) {}
|
||||
// FIXME(#19482) -- `Foo` should specify `A`, but this is not
|
||||
// currently enforced except at object creation
|
||||
|
||||
pub fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue