diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2018-05-10 11:35:16 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-10 11:35:16 -0500 |
| commit | ecd9898b60b601f69113c64b77650a09d7678edf (patch) | |
| tree | 3ff346fc4d396efdc036e10b5b6fa4a0b14e8530 | |
| parent | 0a223d139cd26e5bfab23a478a5cad845eaab131 (diff) | |
| parent | 9073c897459a8582fa61d87f41654e18f9869b46 (diff) | |
| download | rust-ecd9898b60b601f69113c64b77650a09d7678edf.tar.gz rust-ecd9898b60b601f69113c64b77650a09d7678edf.zip | |
Rollup merge of #49423 - gavento:gavento-dev, r=nikomatsakis
Extend tests for RFC1598 (GAT) More GAT tests, namely some usage for `Iterable` and `StreamingIterator`, shadowing (lifetimes and type params), `Collection<T>` and `CollectionFamily` from [the series](http://smallcultfollowing.com/babysteps/blog/2016/11/03/associated-type-constructors-part-2-family-traits/) with default associated types. Tracking issue: #44265 r? @nikomatsakis Wrong GAT argument numbers / kinds and default values are next.
12 files changed, 401 insertions, 16 deletions
diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.rs b/src/test/ui/rfc1598-generic-associated-types/collections.rs new file mode 100644 index 00000000000..e71166ed65b --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/collections.rs @@ -0,0 +1,97 @@ +// 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. + +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +//FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +//follow-up PR + +// A Collection trait and collection families. Based on +// http://smallcultfollowing.com/babysteps/blog/2016/11/03/ +// associated-type-constructors-part-2-family-traits/ + +trait Collection<T> { + type Iter<'iter>: Iterator<Item=&'iter T>; + type Family: CollectionFamily; + // Test associated type defaults with parameters + type Sibling<U>: Collection<U> = + <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>; + //~^ ERROR type parameters are not allowed on this type [E0109] + + fn empty() -> Self; + + fn add(&mut self, value: T); + + fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; + //~^ ERROR lifetime parameters are not allowed on this type [E0110] +} + +trait CollectionFamily { + type Member<T>: Collection<T, Family = Self>; +} + +struct VecFamily; + +impl CollectionFamily for VecFamily { + type Member<T> = Vec<T>; +} + +impl<T> Collection<T> for Vec<T> { + type Iter<'iter> = std::slice::Iter<'iter, T>; + type Family = VecFamily; + + fn empty() -> Self { + Vec::new() + } + + fn add(&mut self, value: T) { + self.push(value) + } + + fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + self.iter() + } +} + +fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32> +//~^ ERROR type parameters are not allowed on this type [E0109] +where + C: Collection<i32>, +{ + let mut res = C::Family::Member::<f32>::empty(); + for &v in ints.iterate() { + res.add(v as f32); + } + res +} + +fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32> +//~^ ERROR type parameters are not allowed on this type [E0109] +where + C: Collection<i32>, +{ + let mut res = C::Family::Member::<f32>::empty(); + for &v in ints.iterate() { + res.add(v as f32); + } + res +} + +fn use_floatify() { + let a = vec![1i32, 2, 3]; + let b = floatify(a); + println!("{}", b.iterate().next()); + let c = floatify_sibling(a); + println!("{}", c.iterate().next()); +} + +fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.stderr b/src/test/ui/rfc1598-generic-associated-types/collections.stderr new file mode 100644 index 00000000000..ed96570583f --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/collections.stderr @@ -0,0 +1,34 @@ +error[E0109]: type parameters are not allowed on this type + --> $DIR/collections.rs:65:90 + | +LL | fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32> + | ^^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/collections.rs:77:69 + | +LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32> + | ^^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/collections.rs:26:71 + | +LL | <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>; + | ^ type parameter not allowed + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/collections.rs:33:50 + | +LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; + | ^^^^^ lifetime parameter not allowed on this type + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/collections.rs:59:50 + | +LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { + | ^^^^^ lifetime parameter not allowed on this type + +error: aborting due to 5 previous errors + +Some errors occurred: E0109, E0110. +For more information about an error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs index 0d9b487876e..04294100315 100644 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs +++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs @@ -10,6 +10,8 @@ #![feature(generic_associated_types)] +use std::ops::Deref; + //FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a //follow-up PR @@ -18,11 +20,18 @@ trait Foo { } trait Baz { - type Quux<'a>; + type Quux<'a>: Foo; + + // This weird type tests that we can use universal function call syntax to access the Item on + type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>; + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~| ERROR lifetime parameters are not allowed on this type [E0110] } impl<T> Baz for T where T: Foo { - type Quux<'a> = <T as Foo>::Bar<'a, 'static>; + type Quux<'a> = T; + + type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static>; //~^ ERROR lifetime parameters are not allowed on this type [E0110] } diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr index 054530e24bd..764a0db2478 100644 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr @@ -1,9 +1,21 @@ error[E0110]: lifetime parameters are not allowed on this type - --> $DIR/construct_with_other_type.rs:25:37 + --> $DIR/construct_with_other_type.rs:26:46 | -LL | type Quux<'a> = <T as Foo>::Bar<'a, 'static>; - | ^^ lifetime parameter not allowed on this type +LL | type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>; + | ^^ lifetime parameter not allowed on this type -error: aborting due to previous error +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/construct_with_other_type.rs:26:63 + | +LL | type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>; + | ^^ lifetime parameter not allowed on this type + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/construct_with_other_type.rs:34:40 + | +LL | type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static>; + | ^^ lifetime parameter not allowed on this type + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0110`. diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.rs b/src/test/ui/rfc1598-generic-associated-types/iterable.rs index 1287ddaf7f7..38967dbbe45 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.rs +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.rs @@ -20,13 +20,40 @@ trait Iterable { type Iter<'a>: Iterator<Item = Self::Item<'a>>; //~^ ERROR lifetime parameters are not allowed on this type [E0110] - // This weird type tests that we can use universal function call syntax to access the Item on - // Self::Iter which we have declared to be an Iterator - type Iter2<'a>: Deref<Target = <Self::Iter<'a> as Iterator>::Item>; + fn iter<'a>(&'a self) -> Self::Iter<'a>; //~^ ERROR lifetime parameters are not allowed on this type [E0110] +} - fn iter<'a>(&'a self) -> Self::Iter<'a>; +// Impl for struct type +impl<T> Iterable for Vec<T> { + type Item<'a> = &'a T; + type Iter<'a> = std::slice::Iter<'a, T>; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + self.iter() + } +} + +// Impl for a primitive type +impl<T> Iterable for [T] { + type Item<'a> = &'a T; + type Iter<'a> = std::slice::Iter<'a, T>; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + self.iter() + } +} + +fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + it.iter() +} + +fn get_first<'a, I: Iterable>(it: &'a I) -> Option<I::Item<'a>> { //~^ ERROR lifetime parameters are not allowed on this type [E0110] + it.iter().next() } fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr index d33eebb42d6..0e251300e45 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr @@ -5,17 +5,35 @@ LL | type Iter<'a>: Iterator<Item = Self::Item<'a>>; | ^^ lifetime parameter not allowed on this type error[E0110]: lifetime parameters are not allowed on this type - --> $DIR/iterable.rs:25:48 + --> $DIR/iterable.rs:49:53 | -LL | type Iter2<'a>: Deref<Target = <Self::Iter<'a> as Iterator>::Item>; - | ^^ lifetime parameter not allowed on this type +LL | fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { + | ^^ lifetime parameter not allowed on this type error[E0110]: lifetime parameters are not allowed on this type - --> $DIR/iterable.rs:28:41 + --> $DIR/iterable.rs:54:60 + | +LL | fn get_first<'a, I: Iterable>(it: &'a I) -> Option<I::Item<'a>> { + | ^^ lifetime parameter not allowed on this type + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/iterable.rs:23:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'a>; | ^^ lifetime parameter not allowed on this type -error: aborting due to 3 previous errors +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/iterable.rs:32:41 + | +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^ lifetime parameter not allowed on this type + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/iterable.rs:43:41 + | +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^ lifetime parameter not allowed on this type + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0110`. diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs new file mode 100644 index 00000000000..51527d4117c --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs @@ -0,0 +1,56 @@ +// 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. + +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +//FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +//follow-up PR + +//FIXME(#44265): Update expected errors once E110 is resolved, now does not get past `trait Foo` + +trait Foo { + type A<'a>; + type B<'a, 'b>; + type C; + type D<T>; + type E<'a, T>; + // Test parameters in default values + type FOk<T> = Self::E<'static, T>; + //~^ ERROR type parameters are not allowed on this type [E0109] + //~| ERROR lifetime parameters are not allowed on this type [E0110] + type FErr1 = Self::E<'static, 'static>; // Error + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + type FErr2<T> = Self::E<'static, T, u32>; // Error + //~^ ERROR type parameters are not allowed on this type [E0109] + //~| ERROR lifetime parameters are not allowed on this type [E0110] +} + +struct Fooy; + +impl Foo for Fooy { + type A = u32; // Error: parameter expected + type B<'a, T> = Vec<T>; // Error: lifetime param expected + type C<'a> = u32; // Error: no param expected + type D<'a> = u32; // Error: type param expected + type E<T, U> = u32; // Error: lifetime expected as the first param +} + +struct Fooer; + +impl Foo for Fooer { + type A<T> = u32; // Error: lifetime parameter expected + type B<'a> = u32; // Error: another lifetime param expected + type C<T> = T; // Error: no param expected + type D<'b, T> = u32; // Error: unexpected lifetime param + type E<'a, 'b> = u32; // Error: type expected as the second param +} + +fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr new file mode 100644 index 00000000000..df83fdaad5b --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr @@ -0,0 +1,34 @@ +error[E0109]: type parameters are not allowed on this type + --> $DIR/parameter_number_and_kind.rs:26:36 + | +LL | type FOk<T> = Self::E<'static, T>; + | ^ type parameter not allowed + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/parameter_number_and_kind.rs:26:27 + | +LL | type FOk<T> = Self::E<'static, T>; + | ^^^^^^^ lifetime parameter not allowed on this type + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/parameter_number_and_kind.rs:29:26 + | +LL | type FErr1 = Self::E<'static, 'static>; // Error + | ^^^^^^^ lifetime parameter not allowed on this type + +error[E0109]: type parameters are not allowed on this type + --> $DIR/parameter_number_and_kind.rs:31:38 + | +LL | type FErr2<T> = Self::E<'static, T, u32>; // Error + | ^ type parameter not allowed + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/parameter_number_and_kind.rs:31:29 + | +LL | type FErr2<T> = Self::E<'static, T, u32>; // Error + | ^^^^^^^ lifetime parameter not allowed on this type + +error: aborting due to 5 previous errors + +Some errors occurred: E0109, E0110. +For more information about an error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs new file mode 100644 index 00000000000..6cdcaf25683 --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs @@ -0,0 +1,42 @@ +// 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. + +#![feature(generic_associated_types)] + +//FIXME(#44265): The lifetime shadowing and type parameter shadowing +// should cause an error. Now it compiles (errorneously) and this will be addressed +// by a future PR. Then remove the following: +// compile-pass + +trait Shadow<'a> { + type Bar<'a>; // Error: shadowed lifetime +} + +trait NoShadow<'a> { + type Bar<'b>; // OK +} + +impl<'a> NoShadow<'a> for &'a u32 { + type Bar<'a> = i32; // Error: shadowed lifetime +} + +trait ShadowT<T> { + type Bar<T>; // Error: shadowed type parameter +} + +trait NoShadowT<T> { + type Bar<U>; // OK +} + +impl<T> NoShadowT<T> for Option<T> { + type Bar<T> = i32; // Error: shadowed type parameter +} + +fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.stdout b/src/test/ui/rfc1598-generic-associated-types/shadowing.stdout new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.stdout diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs index f9e270ee92e..522ddb5dc13 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs +++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs @@ -35,4 +35,48 @@ struct Foo<T: StreamingIterator> { fn foo<T>(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } //~^ ERROR lifetime parameters are not allowed on this type [E0110] +// Full example of enumerate iterator + +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +struct StreamEnumerate<I> { + iter: I, + count: usize, +} + +impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> { + type Item<'a> = (usize, I::Item<'a>); + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + fn next<'a>(&'a self) -> Option<Self::Item<'a>> { + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + match self.iter.next() { + None => None, + Some(val) => { + let r = Some((self.count, val)); + self.count += 1; + r + } + } + } +} + +impl<I> StreamEnumerate<I> { + pub fn new(iter: I) -> Self { + StreamEnumerate { + count: 0, + iter: iter, + } + } +} + +fn test_stream_enumerate() { + let v = vec!["a", "b", "c"]; + let se = StreamEnumerate::new(v.iter()); + let a: &str = se.next().unwrap().1; + for (i, s) in se { + println!("{} {}", i, s); + } + println!("{}", a); +} + + fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr index 9ab80151a7e..607a4b8d579 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr @@ -16,6 +16,18 @@ error[E0110]: lifetime parameters are not allowed on this type LL | fn next<'a>(&'a self) -> Option<Self::Item<'a>>; | ^^ lifetime parameter not allowed on this type -error: aborting due to 3 previous errors +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/streaming_iterator.rs:47:37 + | +LL | type Item<'a> = (usize, I::Item<'a>); + | ^^ lifetime parameter not allowed on this type + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/streaming_iterator.rs:49:48 + | +LL | fn next<'a>(&'a self) -> Option<Self::Item<'a>> { + | ^^ lifetime parameter not allowed on this type + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0110`. |
