From a38ff481ed74e31a1508f989012805bd9c3a4deb Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Mon, 7 Feb 2022 21:37:37 -0500 Subject: [PATCH 1/2] Add some known GAT bugs as tests --- .../bugs/issue-80626.rs | 17 +++++++ .../bugs/issue-80626.stderr | 20 +++++++++ .../bugs/issue-86218.rs | 27 +++++++++++ .../bugs/issue-86218.stderr | 15 +++++++ .../bugs/issue-87735.rs | 45 +++++++++++++++++++ .../bugs/issue-87735.stderr | 9 ++++ .../bugs/issue-87748.rs | 22 +++++++++ .../bugs/issue-87748.stderr | 20 +++++++++ .../bugs/issue-87755.rs | 21 +++++++++ .../bugs/issue-87755.stderr | 9 ++++ .../bugs/issue-87803.rs | 26 +++++++++++ .../bugs/issue-87803.stderr | 12 +++++ .../bugs/issue-88382.rs | 31 +++++++++++++ .../bugs/issue-88382.stderr | 20 +++++++++ .../bugs/issue-88460.rs | 31 +++++++++++++ .../bugs/issue-88460.stderr | 18 ++++++++ .../bugs/issue-88526.rs | 34 ++++++++++++++ .../bugs/issue-88526.stderr | 9 ++++ .../bugs/issue-89008.rs | 43 ++++++++++++++++++ .../bugs/issue-89008.stderr | 21 +++++++++ 20 files changed, 450 insertions(+) create mode 100644 src/test/ui/generic-associated-types/bugs/issue-80626.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-80626.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-86218.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-86218.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87735.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87735.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87748.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87748.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87755.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87755.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87803.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-87803.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-88382.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-88382.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-88460.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-88460.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-88526.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-88526.stderr create mode 100644 src/test/ui/generic-associated-types/bugs/issue-89008.rs create mode 100644 src/test/ui/generic-associated-types/bugs/issue-89008.stderr diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs new file mode 100644 index 0000000000000..aea8aaf4bb393 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs @@ -0,0 +1,17 @@ +// check-fail + +// This should pass, but it requires `Sized` to be coinductive. + +#![feature(generic_associated_types)] + +trait Allocator { + type Allocated; +} + +enum LinkedList { + Head, + Next(A::Allocated) + //~^ overflow +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr new file mode 100644 index 0000000000000..e18af9c257f7f --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr @@ -0,0 +1,20 @@ +error[E0275]: overflow evaluating the requirement `LinkedList: Sized` + --> $DIR/issue-80626.rs:13:10 + | +LL | Next(A::Allocated) + | ^^^^^^^^^^^^^^^^^^ + | + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | Next(&A::Allocated) + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +LL | Next(Box>) + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.rs b/src/test/ui/generic-associated-types/bugs/issue-86218.rs new file mode 100644 index 0000000000000..3f8776a363770 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-86218.rs @@ -0,0 +1,27 @@ +// check-fail + +// This should pass, but seems to run into a TAIT issue. + +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +pub trait Stream { + type Item; +} + +impl Stream for () { + type Item = i32; +} + +trait Yay { + type InnerStream<'s>: Stream + 's; + fn foo<'s>() -> Self::InnerStream<'s>; +} + +impl<'a> Yay<&'a ()> for () { + type InnerStream<'s> = impl Stream + 's; + //~^ the type + fn foo<'s>() -> Self::InnerStream<'s> { todo!() } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr new file mode 100644 index 0000000000000..9f4efc0addb73 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr @@ -0,0 +1,15 @@ +error[E0477]: the type `impl Stream` does not fulfill the required lifetime + --> $DIR/issue-86218.rs:22:28 + | +LL | type InnerStream<'s> = impl Stream + 's; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type must outlive the lifetime `'s` as defined here as required by this binding + --> $DIR/issue-86218.rs:22:22 + | +LL | type InnerStream<'s> = impl Stream + 's; + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0477`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.rs b/src/test/ui/generic-associated-types/bugs/issue-87735.rs new file mode 100644 index 0000000000000..5f7a42a740df6 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87735.rs @@ -0,0 +1,45 @@ +// check-fail + +// This should pass, but we need an extension of implied bounds (probably). + +#![feature(generic_associated_types)] + +pub trait AsRef2 { + type Output<'a> where Self: 'a; + + fn as_ref2<'a>(&'a self) -> Self::Output<'a>; +} + +impl AsRef2 for Vec { + type Output<'a> where Self: 'a = &'a [T]; + + fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + &self[..] + } +} + +#[derive(Debug)] +struct Foo(T); +#[derive(Debug)] +struct FooRef<'a, U>(&'a [U]); + +impl<'b, T, U> AsRef2 for Foo //~ the type parameter +where + // * `for<'b, 'c> T: AsRef2 = &'c [U]>>` does not work + // + // * `U` is unconstrained but should be allowed in this context because `Output` is + // an associated type + T: AsRef2 = &'b [U]>, + U: 'b +{ + type Output<'a> where Self: 'a = FooRef<'a, U>; + + fn as_ref2<'a>(&'a self) -> Self::Output<'a> { + FooRef(self.0.as_ref2()) + } +} + +fn main() { + let foo = Foo(vec![1, 2, 3]); + dbg!(foo.as_ref2()); +} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.stderr b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr new file mode 100644 index 0000000000000..31b3a9619b6af --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-87735.rs:26:13 + | +LL | impl<'b, T, U> AsRef2 for Foo + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.rs b/src/test/ui/generic-associated-types/bugs/issue-87748.rs new file mode 100644 index 0000000000000..4dbaf429ead26 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87748.rs @@ -0,0 +1,22 @@ +// check-fail + +// This should pass, but unnormalized input args aren't treated as implied. + +#![feature(generic_associated_types)] + +trait MyTrait { + type Assoc<'a, 'b> where 'b: 'a; + fn do_sth(arg: Self::Assoc<'_, '_>); +} + +struct Foo; + +impl MyTrait for Foo { + type Assoc<'a, 'b> where 'b: 'a = u32; + + fn do_sth(_: u32) {} //~ lifetime bound + // fn do_sth(_: Self::Assoc<'static, 'static>) {} + // fn do_sth(_: Self::Assoc<'_, '_>) {} +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr new file mode 100644 index 0000000000000..c38d447859233 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr @@ -0,0 +1,20 @@ +error[E0478]: lifetime bound not satisfied + --> $DIR/issue-87748.rs:17:5 + | +LL | fn do_sth(_: u32) {} + | ^^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the anonymous lifetime #2 defined here + --> $DIR/issue-87748.rs:17:5 + | +LL | fn do_sth(_: u32) {} + | ^^^^^^^^^^^^^^^^^ +note: but lifetime parameter must outlive the anonymous lifetime #1 defined here + --> $DIR/issue-87748.rs:17:5 + | +LL | fn do_sth(_: u32) {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0478`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs new file mode 100644 index 0000000000000..1cd3534ba77a0 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs @@ -0,0 +1,21 @@ +// check-fail + +// This should pass. + +#![feature(generic_associated_types)] + +use std::fmt::Debug; + +trait Foo { + type Ass where Self::Ass: Debug; +} + +#[derive(Debug)] +struct Bar; + +impl Foo for Bar { + type Ass = Bar; + //~^ overflow +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr new file mode 100644 index 0000000000000..d2dc991a2b640 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `::Ass == _` + --> $DIR/issue-87755.rs:17:16 + | +LL | type Ass = Bar; + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.rs b/src/test/ui/generic-associated-types/bugs/issue-87803.rs new file mode 100644 index 0000000000000..3d2ff38ab049e --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87803.rs @@ -0,0 +1,26 @@ +// check-fail + +// This should pass, but using a type alias vs a reference directly +// changes late-bound -> early-bound. + +#![feature(generic_associated_types)] + +trait Scanner { + type Input<'a>; + type Token<'a>; + + fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>; +} + +struct IdScanner(); + +impl Scanner for IdScanner { + type Input<'a> = &'a str; + type Token<'a> = &'a str; + + fn scan<'a>(&mut self, s : &'a str) -> &'a str { //~ lifetime parameters + s + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr new file mode 100644 index 0000000000000..fe2abdedbf37c --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr @@ -0,0 +1,12 @@ +error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration + --> $DIR/issue-87803.rs:20:12 + | +LL | fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>; + | ---- lifetimes in impl do not match this method in trait +... +LL | fn scan<'a>(&mut self, s : &'a str) -> &'a str { + | ^^^^ lifetimes do not match method in trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0195`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.rs b/src/test/ui/generic-associated-types/bugs/issue-88382.rs new file mode 100644 index 0000000000000..f4633ca516999 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88382.rs @@ -0,0 +1,31 @@ +// check-fail + +// This should pass, but has a missed normalization due to HRTB. + +#![feature(generic_associated_types)] + +trait Iterable { + type Iterator<'a> where Self: 'a; + fn iter(&self) -> Self::Iterator<'_>; +} + +struct SomeImplementation(); + +impl Iterable for SomeImplementation { + type Iterator<'a> = std::iter::Empty; + fn iter(&self) -> Self::Iterator<'_> { + std::iter::empty() + } +} + +fn do_something(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { + f(&mut i.iter()); +} + +fn main() { + do_something(SomeImplementation(), |_| ()); + do_something(SomeImplementation(), test); + //~^ type mismatch +} + +fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr new file mode 100644 index 0000000000000..05bc58cbba4e6 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr @@ -0,0 +1,20 @@ +error[E0631]: type mismatch in function arguments + --> $DIR/issue-88382.rs:27:40 + | +LL | do_something(SomeImplementation(), test); + | ------------ ^^^^ expected signature of `for<'a> fn(&mut ::Iterator<'a>) -> _` + | | + | required by a bound introduced by this call +... +LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} + | ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty) -> _` + | +note: required by a bound in `do_something` + --> $DIR/issue-88382.rs:21:56 + | +LL | fn do_something(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.rs b/src/test/ui/generic-associated-types/bugs/issue-88460.rs new file mode 100644 index 0000000000000..7e62790cc50c3 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88460.rs @@ -0,0 +1,31 @@ +// check-fail + +// This should pass, but has a missed normalization due to HRTB. + +#![feature(generic_associated_types)] + +pub trait Marker {} + +pub trait Trait { + type Assoc<'a>; +} + +fn test(value: T) +where + T: Trait, + for<'a> T::Assoc<'a>: Marker, +{ +} + +impl Marker for () {} + +struct Foo; + +impl Trait for Foo { + type Assoc<'a> = (); +} + +fn main() { + test(Foo); + //~^ the trait bound +} diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr new file mode 100644 index 0000000000000..604658da7d2c2 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied + --> $DIR/issue-88460.rs:29:5 + | +LL | test(Foo); + | ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>` + | +note: required by a bound in `test` + --> $DIR/issue-88460.rs:16:27 + | +LL | fn test(value: T) + | ---- required by a bound in this +... +LL | for<'a> T::Assoc<'a>: Marker, + | ^^^^^^ required by this bound in `test` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.rs b/src/test/ui/generic-associated-types/bugs/issue-88526.rs new file mode 100644 index 0000000000000..90568fcb40125 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88526.rs @@ -0,0 +1,34 @@ +// check-fail + +// This should pass, but requires more logic. + +#![feature(generic_associated_types)] + +trait A { + type I<'a>; +} + +pub struct TestA +{ + f: F, +} + +impl A for TestA { + type I<'a> = &'a F; +} + +struct TestB +{ + q: Q, + f: F, +} + +impl<'q, Q, I, F> A for TestB //~ the type parameter +where + Q: A = &'q I>, + F: Fn(I), +{ + type I<'a> = (); +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.stderr b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr new file mode 100644 index 0000000000000..ccc5ae0b621a1 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-88526.rs:26:13 + | +LL | impl<'q, Q, I, F> A for TestB + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.rs b/src/test/ui/generic-associated-types/bugs/issue-89008.rs new file mode 100644 index 0000000000000..5d850849fd21c --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-89008.rs @@ -0,0 +1,43 @@ +// check-fail +// edition:2021 + +// This should pass, but seems to run into a TAIT bug. + +#![feature(type_alias_impl_trait)] +#![feature(generic_associated_types)] + +use std::future::Future; + +trait Stream { + type Item; +} + +struct Empty(T); +impl Stream for Empty { + type Item = (); +} +fn empty() -> Empty { + todo!() +} + +trait X { + type LineStream<'a, Repr>: Stream where Self: 'a; + + type LineStreamFut<'a,Repr>: Future> where Self: 'a; + + fn line_stream<'a,Repr>(&'a self) -> Self::LineStreamFut<'a,Repr>; +} + +struct Y; + +impl X for Y { + type LineStream<'a, Repr> = impl Stream; //~ could not find + + type LineStreamFut<'a, Repr> = impl Future> ; + + fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> { //~ type mismatch + async {empty()} + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr new file mode 100644 index 0000000000000..48745fe0fbd96 --- /dev/null +++ b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr @@ -0,0 +1,21 @@ +error[E0271]: type mismatch resolving ` as Future>::Output == impl Stream` + --> $DIR/issue-89008.rs:38:43 + | +LL | type LineStream<'a, Repr> = impl Stream; + | ------------------------ the expected opaque type +... +LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found struct `Empty` + | + = note: expected opaque type `impl Stream` + found struct `Empty<_>` + +error: could not find defining uses + --> $DIR/issue-89008.rs:34:33 + | +LL | type LineStream<'a, Repr> = impl Stream; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. From ba4221567b432d01d499475d9d5b39cfeb70071a Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sat, 12 Feb 2022 00:57:16 -0500 Subject: [PATCH 2/2] Fix line number Co-authored-by: David Tolnay --- src/test/ui/generic-associated-types/bugs/issue-87803.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr index fe2abdedbf37c..759c0440d07ba 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr @@ -1,5 +1,5 @@ error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration - --> $DIR/issue-87803.rs:20:12 + --> $DIR/issue-87803.rs:21:12 | LL | fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>; | ---- lifetimes in impl do not match this method in trait