Skip to content

Commit

Permalink
Add some known GAT bugs as tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jackh726 committed Feb 8, 2022
1 parent f52c318 commit a38ff48
Show file tree
Hide file tree
Showing 20 changed files with 450 additions and 0 deletions.
17 changes: 17 additions & 0 deletions 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<T>;
}

enum LinkedList<A: Allocator> {
Head,
Next(A::Allocated<Self>)
//~^ overflow
}

fn main() {}
20 changes: 20 additions & 0 deletions src/test/ui/generic-associated-types/bugs/issue-80626.stderr
@@ -0,0 +1,20 @@
error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
--> $DIR/issue-80626.rs:13:10
|
LL | Next(A::Allocated<Self>)
| ^^^^^^^^^^^^^^^^^^
|
= 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<Self>)
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
LL | Next(Box<A::Allocated<Self>>)
| ++++ +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.
27 changes: 27 additions & 0 deletions 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<AdditionalValue> {
type InnerStream<'s>: Stream<Item = i32> + 's;
fn foo<'s>() -> Self::InnerStream<'s>;
}

impl<'a> Yay<&'a ()> for () {
type InnerStream<'s> = impl Stream<Item = i32> + 's;
//~^ the type
fn foo<'s>() -> Self::InnerStream<'s> { todo!() }
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/generic-associated-types/bugs/issue-86218.stderr
@@ -0,0 +1,15 @@
error[E0477]: the type `impl Stream<Item = i32>` does not fulfill the required lifetime
--> $DIR/issue-86218.rs:22:28
|
LL | type InnerStream<'s> = impl Stream<Item = i32> + '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<Item = i32> + 's;
| ^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0477`.
45 changes: 45 additions & 0 deletions 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<T> AsRef2 for Vec<T> {
type Output<'a> where Self: 'a = &'a [T];

fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
&self[..]
}
}

#[derive(Debug)]
struct Foo<T>(T);
#[derive(Debug)]
struct FooRef<'a, U>(&'a [U]);

impl<'b, T, U> AsRef2 for Foo<T> //~ the type parameter
where
// * `for<'b, 'c> T: AsRef2<Output<'b> = &'c [U]>>` does not work
//
// * `U` is unconstrained but should be allowed in this context because `Output` is
// an associated type
T: AsRef2<Output<'b> = &'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());
}
9 changes: 9 additions & 0 deletions 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<T>
| ^ unconstrained type parameter

error: aborting due to previous error

For more information about this error, try `rustc --explain E0207`.
22 changes: 22 additions & 0 deletions 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() {}
20 changes: 20 additions & 0 deletions 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`.
21 changes: 21 additions & 0 deletions 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() {}
9 changes: 9 additions & 0 deletions src/test/ui/generic-associated-types/bugs/issue-87755.stderr
@@ -0,0 +1,9 @@
error[E0275]: overflow evaluating the requirement `<Bar as Foo>::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`.
26 changes: 26 additions & 0 deletions 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() {}
12 changes: 12 additions & 0 deletions 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`.
31 changes: 31 additions & 0 deletions 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<usize>;
fn iter(&self) -> Self::Iterator<'_> {
std::iter::empty()
}
}

fn do_something<I: Iterable>(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>) {}
20 changes: 20 additions & 0 deletions 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 <SomeImplementation as Iterable>::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<usize>) -> _`
|
note: required by a bound in `do_something`
--> $DIR/issue-88382.rs:21:56
|
LL | fn do_something<I: Iterable>(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`.
31 changes: 31 additions & 0 deletions 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<T>(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
}
18 changes: 18 additions & 0 deletions 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<T>(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`.
34 changes: 34 additions & 0 deletions 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: F,
}

impl<F> A for TestA<F> {
type I<'a> = &'a F;
}

struct TestB<Q, F>
{
q: Q,
f: F,
}

impl<'q, Q, I, F> A for TestB<Q, F> //~ the type parameter
where
Q: A<I<'q> = &'q I>,
F: Fn(I),
{
type I<'a> = ();
}

fn main() {}

0 comments on commit a38ff48

Please sign in to comment.