From b0fcb5f4408d59a0dcea4427394a04e72ab5aeff Mon Sep 17 00:00:00 2001 From: Tomas Gavenciak Date: Tue, 27 Mar 2018 19:45:44 +0200 Subject: [PATCH] Extend tests for RFC1598 (GAT) --- .../collections.rs | 85 +++++++++++++++++++ .../collections.stderr | 34 ++++++++ .../iterable.rs | 34 ++++++++ .../iterable.stderr | 26 +++++- .../shadowing.rs | 44 ++++++++++ .../shadowing.stdout | 0 .../streaming_iterator.rs | 44 ++++++++++ .../streaming_iterator.stderr | 14 ++- 8 files changed, 279 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/rfc1598-generic-associated-types/collections.rs create mode 100644 src/test/ui/rfc1598-generic-associated-types/collections.stderr create mode 100644 src/test/ui/rfc1598-generic-associated-types/shadowing.rs create mode 100644 src/test/ui/rfc1598-generic-associated-types/shadowing.stdout 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 0000000000000..4ea2c82883133 --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/collections.rs @@ -0,0 +1,85 @@ +// 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 or the MIT license +// , 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 { + 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] + type Iter<'iter>: Iterator; + type Family: CollectionFamily; + // Test associated type defaults with parameters + type Sibling: Collection = <>::Family as CollectionFamily>::Member; + //~^ ERROR type parameters are not allowed on this type [E0109] +} + +trait CollectionFamily { + type Member: Collection; +} + +struct VecFamily; + +impl CollectionFamily for VecFamily { + type Member = Vec; +} + +impl Collection for Vec { + 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() + } + type Iter<'iter> = std::slice::Iter<'iter, T>; + type Family = VecFamily; +} + +fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member + //~^ ERROR type parameters are not allowed on this type [E0109] + where C: Collection { + let mut res = C::Family::Member::::empty(); + for &v in ints.iterate() { + res.add(v as f32); + } + res +} + +fn floatify_sibling(ints: &C) -> >::Sibling + //~^ ERROR type parameters are not allowed on this type [E0109] + where C: Collection { + let mut res = C::Family::Member::::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() {} \ No newline at end of file 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 0000000000000..6aa7aa993fd25 --- /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:57:90 + | +LL | fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member + | ^^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/collections.rs:67:69 + | +LL | fn floatify_sibling(ints: &C) -> >::Sibling + | ^^^ type parameter not allowed + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/collections.rs:23:50 + | +LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; + | ^^^^^ lifetime parameter not allowed on this type + +error[E0109]: type parameters are not allowed on this type + --> $DIR/collections.rs:28:100 + | +LL | type Sibling: Collection = <>::Family as CollectionFamily>::Member; + | ^ type parameter not allowed + +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/collections.rs:49: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/iterable.rs b/src/test/ui/rfc1598-generic-associated-types/iterable.rs index 1287ddaf7f7fe..b79aa6179adfd 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.rs +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.rs @@ -29,4 +29,38 @@ trait Iterable { //~^ ERROR lifetime parameters are not allowed on this type [E0110] } +// Impl for struct type +impl Iterable for Vec { + type Item<'a> = &'a T; + type Iter<'a> = std::slice::Iter<'a, T>; + type Iter2<'a> = &'a T; + // gavento: ^^^ Not 100% sure about the intention here + 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 Iterable for [T] { + type Item<'a> = &'a T; + type Iter<'a> = std::slice::Iter<'a, T>; + type Iter2<'a> = &'a T; + // gavento: ^^^ Not 100% sure about the intention here + 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> { + //~^ 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 d33eebb42d607..34266dd3c512f 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr @@ -10,12 +10,36 @@ error[E0110]: lifetime parameters are not allowed on this type LL | type Iter2<'a>: Deref as Iterator>::Item>; | ^^ lifetime parameter not allowed on this type +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/iterable.rs:56:53 + | +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:61:60 + | +LL | fn get_first<'a, I: Iterable>(it: &'a I) -> Option> { + | ^^ lifetime parameter not allowed on this type + error[E0110]: lifetime parameters are not allowed on this type --> $DIR/iterable.rs:28: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:38: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:50:41 + | +LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { + | ^^ lifetime parameter not allowed on this type + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0110`. 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 0000000000000..6e77ce2b3dd0c --- /dev/null +++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs @@ -0,0 +1,44 @@ +// 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 or the MIT license +// , 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. This will be addressed by a future PR. +// For now this compiles: +// must-compile-successfully + +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 { + type Bar; // Error: shadowed type parameter +} + +trait NoShadowT { + type Bar; // OK +} + +impl NoShadowT for Option +{ + type Bar = 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 0000000000000..e69de29bb2d1d 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 f9e270ee92e22..522ddb5dc135e 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 { fn foo(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 { + iter: I, + count: usize, +} + +impl StreamingIterator for StreamEnumerate { + type Item<'a> = (usize, I::Item<'a>); + //~^ ERROR lifetime parameters are not allowed on this type [E0110] + fn next<'a>(&'a self) -> Option> { + //~^ 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 StreamEnumerate { + 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 9ab80151a7ed3..607a4b8d57996 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>; | ^^ 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> { + | ^^ lifetime parameter not allowed on this type + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0110`.