diff options
| author | bors <bors@rust-lang.org> | 2015-03-26 13:38:41 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-26 13:38:41 +0000 |
| commit | 557d4346a26266d2eb13f6b0adf106b8873b0da1 (patch) | |
| tree | d090541009a2400121f5bac3bca1002598eade28 /src/test | |
| parent | 1501f33e76f6f9621aa08fb0cbbc5f85a5ac7f0f (diff) | |
| parent | 9cabe273d3adb06a19f63460deda96ae224b28bf (diff) | |
Auto merge of #21237 - erickt:derive-assoc-types, r=erickt
This PR adds support for associated types to the `#[derive(...)]` syntax extension. In order to do this, it switches over to using where predicates to apply the type constraints. So now this:
```rust
type Trait {
type Type;
}
#[derive(Clone)]
struct Foo<A> where A: Trait {
a: A,
b: <A as Trait>::Type,
}
```
Gets expended into this impl:
```rust
impl<A: Clone> Clone for Foo<A> where
A: Trait,
<A as Trait>::Type: Clone,
{
fn clone(&self) -> Foo<T> {
Foo {
a: self.a.clone(),
b: self.b.clone(),
}
}
}
```
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/auxiliary/struct_variant_xc_aux.rs | 1 | ||||
| -rw-r--r-- | src/test/compile-fail/derive-assoc-type-not-impl.rs | 29 | ||||
| -rw-r--r-- | src/test/run-pass/deriving-associated-types.rs | 210 |
3 files changed, 240 insertions, 0 deletions
diff --git a/src/test/auxiliary/struct_variant_xc_aux.rs b/src/test/auxiliary/struct_variant_xc_aux.rs index 76fd619f689..8670cd96fc6 100644 --- a/src/test/auxiliary/struct_variant_xc_aux.rs +++ b/src/test/auxiliary/struct_variant_xc_aux.rs @@ -11,6 +11,7 @@ #![crate_name="struct_variant_xc_aux"] #![crate_type = "lib"] +#[derive(Copy)] pub enum Enum { Variant(u8), StructVariant { arg: u8 } diff --git a/src/test/compile-fail/derive-assoc-type-not-impl.rs b/src/test/compile-fail/derive-assoc-type-not-impl.rs new file mode 100644 index 00000000000..3799f2ffba4 --- /dev/null +++ b/src/test/compile-fail/derive-assoc-type-not-impl.rs @@ -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. + +trait Foo { + type X; + fn method(&self) {} +} + +#[derive(Clone)] +struct Bar<T: Foo> { + x: T::X, +} + +struct NotClone; + +impl Foo for NotClone { + type X = i8; +} + +fn main() { + Bar::<NotClone> { x: 1 }.clone(); //~ ERROR +} diff --git a/src/test/run-pass/deriving-associated-types.rs b/src/test/run-pass/deriving-associated-types.rs new file mode 100644 index 00000000000..59eb5506c45 --- /dev/null +++ b/src/test/run-pass/deriving-associated-types.rs @@ -0,0 +1,210 @@ +// 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(core, debug_builders)] + +pub trait DeclaredTrait { + type Type; +} + +impl DeclaredTrait for i32 { + type Type = i32; +} + +pub trait WhereTrait { + type Type; +} + +impl WhereTrait for i32 { + type Type = i32; +} + +// Make sure we don't add a bound that just shares a name with an associated +// type. +pub mod module { + pub type Type = i32; +} + +#[derive(PartialEq, Debug)] +struct PrivateStruct<T>(T); + +#[derive(PartialEq, Debug)] +struct TupleStruct<A, B: DeclaredTrait, C>( + module::Type, + Option<module::Type>, + A, + PrivateStruct<A>, + B, + B::Type, + Option<B::Type>, + <B as DeclaredTrait>::Type, + Option<<B as DeclaredTrait>::Type>, + C, + C::Type, + Option<C::Type>, + <C as WhereTrait>::Type, + Option<<C as WhereTrait>::Type>, + <i32 as DeclaredTrait>::Type, +) where C: WhereTrait; + +#[derive(PartialEq, Debug)] +pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait { + m1: module::Type, + m2: Option<module::Type>, + a1: A, + a2: PrivateStruct<A>, + b: B, + b1: B::Type, + b2: Option<B::Type>, + b3: <B as DeclaredTrait>::Type, + b4: Option<<B as DeclaredTrait>::Type>, + c: C, + c1: C::Type, + c2: Option<C::Type>, + c3: <C as WhereTrait>::Type, + c4: Option<<C as WhereTrait>::Type>, + d: <i32 as DeclaredTrait>::Type, +} + +#[derive(PartialEq, Debug)] +enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait { + Unit, + Seq( + module::Type, + Option<module::Type>, + A, + PrivateStruct<A>, + B, + B::Type, + Option<B::Type>, + <B as DeclaredTrait>::Type, + Option<<B as DeclaredTrait>::Type>, + C, + C::Type, + Option<C::Type>, + <C as WhereTrait>::Type, + Option<<C as WhereTrait>::Type>, + <i32 as DeclaredTrait>::Type, + ), + Map { + m1: module::Type, + m2: Option<module::Type>, + a1: A, + a2: PrivateStruct<A>, + b: B, + b1: B::Type, + b2: Option<B::Type>, + b3: <B as DeclaredTrait>::Type, + b4: Option<<B as DeclaredTrait>::Type>, + c: C, + c1: C::Type, + c2: Option<C::Type>, + c3: <C as WhereTrait>::Type, + c4: Option<<C as WhereTrait>::Type>, + d: <i32 as DeclaredTrait>::Type, + }, +} + +fn main() { + let e: TupleStruct< + i32, + i32, + i32, + > = TupleStruct( + 0, + None, + 0, + PrivateStruct(0), + 0, + 0, + None, + 0, + None, + 0, + 0, + None, + 0, + None, + 0, + ); + assert_eq!(e, e); + + let e: Struct< + i32, + i32, + i32, + > = Struct { + m1: 0, + m2: None, + a1: 0, + a2: PrivateStruct(0), + b: 0, + b1: 0, + b2: None, + b3: 0, + b4: None, + c: 0, + c1: 0, + c2: None, + c3: 0, + c4: None, + d: 0, + }; + assert_eq!(e, e); + + let e = Enum::Unit::<i32, i32, i32>; + assert_eq!(e, e); + + let e: Enum< + i32, + i32, + i32, + > = Enum::Seq( + 0, + None, + 0, + PrivateStruct(0), + 0, + 0, + None, + 0, + None, + 0, + 0, + None, + 0, + None, + 0, + ); + assert_eq!(e, e); + + let e: Enum< + i32, + i32, + i32, + > = Enum::Map { + m1: 0, + m2: None, + a1: 0, + a2: PrivateStruct(0), + b: 0, + b1: 0, + b2: None, + b3: 0, + b4: None, + c: 0, + c1: 0, + c2: None, + c3: 0, + c4: None, + d: 0, + }; + assert_eq!(e, e); +} |
