From eeb82e45fe42ec77efd99b706f96b3e66bcfb524 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 12 Feb 2021 22:45:54 +0000 Subject: [PATCH] Add more tests for generic associated type bounds --- .../generic-associated-type-bounds.rs | 35 +++++++++++++ .../generic-associated-types/issue-76535.rs | 6 +-- .../issue-76535.stderr | 39 +-------------- .../generic-associated-types/issue-79422.rs | 5 +- .../issue-79422.stderr | 40 +++------------ .../projection-type-lifetime-mismatch.rs | 36 +++++++++++++ .../projection-type-lifetime-mismatch.stderr | 27 ++++++++++ .../unsatified-item-lifetime-bound.rs | 28 +++++++++++ .../unsatified-item-lifetime-bound.stderr | 50 +++++++++++++++++++ 9 files changed, 190 insertions(+), 76 deletions(-) create mode 100644 src/test/ui/generic-associated-types/generic-associated-type-bounds.rs create mode 100644 src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs create mode 100644 src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr create mode 100644 src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs create mode 100644 src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr diff --git a/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs new file mode 100644 index 000000000000..8094450e5e13 --- /dev/null +++ b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs @@ -0,0 +1,35 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +pub trait X { + type Y<'a>; + fn m(&self) -> Self::Y<'_>; +} + +impl X for () { + type Y<'a> = &'a (); + + fn m(&self) -> Self::Y<'_> { + self + } +} + +fn f(x: &impl for<'a> X = &'a ()>) -> &() { + x.m() +} + +fn g X = &'a ()>>(x: &T) -> &() { + x.m() +} + +fn h(x: &()) -> &() { + x.m() +} + +fn main() { + f(&()); + g(&()); + h(&()); +} diff --git a/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs index 2b4757d8d15e..5e73a8829862 100644 --- a/src/test/ui/generic-associated-types/issue-76535.rs +++ b/src/test/ui/generic-associated-types/issue-76535.rs @@ -1,11 +1,11 @@ #![feature(generic_associated_types)] - //~^ WARNING the feature +//~^ WARNING the feature pub trait SubTrait {} pub trait SuperTrait { type SubType<'a>: SubTrait; - //~^ ERROR missing generics for associated + //~^ ERROR missing generics for associated fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; } @@ -36,6 +36,4 @@ impl SuperTrait for SuperStruct { fn main() { let sub: Box> = Box::new(SuperStruct::new(0)); - //~^ ERROR the trait - //~| ERROR the trait } diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.stderr index ce4875af9c01..17661e0d90a4 100644 --- a/src/test/ui/generic-associated-types/issue-76535.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.stderr @@ -23,41 +23,6 @@ help: use angle brackets to add missing lifetime argument LL | type SubType<'a><'a>: SubTrait; | ^^^^ -error[E0038]: the trait `SuperTrait` cannot be made into an object - --> $DIR/issue-76535.rs:38:14 - | -LL | let sub: Box> = Box::new(SuperStruct::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object - | - = help: consider moving `get_sub` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-76535.rs:10:37 - | -LL | pub trait SuperTrait { - | ---------- this trait cannot be made into an object... -... -LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; - | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type +error: aborting due to previous error; 1 warning emitted -error[E0038]: the trait `SuperTrait` cannot be made into an object - --> $DIR/issue-76535.rs:38:57 - | -LL | let sub: Box> = Box::new(SuperStruct::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object - | - = help: consider moving `get_sub` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-76535.rs:10:37 - | -LL | pub trait SuperTrait { - | ---------- this trait cannot be made into an object... -... -LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; - | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type - = note: required because of the requirements on the impl of `CoerceUnsized>>>` for `Box` - = note: required by cast to type `Box>>` - -error: aborting due to 3 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs index 26b38430dd9a..aeb33ca54641 100644 --- a/src/test/ui/generic-associated-types/issue-79422.rs +++ b/src/test/ui/generic-associated-types/issue-79422.rs @@ -19,7 +19,7 @@ impl<'a, T> RefCont<'a, T> for Box { trait MapLike { type VRefCont<'a>: RefCont<'a, V>; - //~^ ERROR missing generics + //~^ ERROR missing generics fn get<'a>(&'a self, key: &K) -> Option>; } @@ -42,6 +42,5 @@ impl MapLike for Source { fn main() { let m = Box::new(std::collections::BTreeMap::::new()) as Box>>; - //~^ ERROR the trait - //~^^^ ERROR the trait + //~^^ ERROR type mismatch resolving } diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.stderr index d2e12962715f..a119bff03e29 100644 --- a/src/test/ui/generic-associated-types/issue-79422.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.stderr @@ -14,41 +14,17 @@ help: use angle brackets to add missing lifetime argument LL | type VRefCont<'a><'a>: RefCont<'a, V>; | ^^^^ -error[E0038]: the trait `MapLike` cannot be made into an object - --> $DIR/issue-79422.rs:44:12 - | -LL | as Box>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object - | - = help: consider moving `get` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-79422.rs:23:38 - | -LL | trait MapLike { - | ------- this trait cannot be made into an object... -... -LL | fn get<'a>(&'a self, key: &K) -> Option>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type - -error[E0038]: the trait `MapLike` cannot be made into an object +error[E0271]: type mismatch resolving ` as MapLike>::VRefCont<'static> == (dyn RefCont<'_, u8> + 'static)` --> $DIR/issue-79422.rs:43:13 | LL | let m = Box::new(std::collections::BTreeMap::::new()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn RefCont`, found reference | - = help: consider moving `get` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-79422.rs:23:38 - | -LL | trait MapLike { - | ------- this trait cannot be made into an object... -... -LL | fn get<'a>(&'a self, key: &K) -> Option>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type - = note: required because of the requirements on the impl of `CoerceUnsized + 'static)>>>` for `Box>` - = note: required by cast to type `Box + 'static)>>` + = note: expected trait object `(dyn RefCont<'_, u8> + 'static)` + found reference `&'static u8` + = note: required for the cast to the object type `dyn MapLike + 'static)>` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0107, E0271. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs new file mode 100644 index 000000000000..0024e127a982 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs @@ -0,0 +1,36 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +pub trait X { + type Y<'a>; + fn m(&self) -> Self::Y<'_>; +} + +impl X for () { + type Y<'a> = &'a (); + + fn m(&self) -> Self::Y<'_> { + self + } +} + +fn f(x: &impl for<'a> X = &'a ()>) -> &'static () { + x.m() + //~^ ERROR explicit lifetime required +} + +fn g X = &'a ()>>(x: &T) -> &'static () { + x.m() + //~^ ERROR explicit lifetime required +} + +fn h(x: &()) -> &'static () { + x.m() + //~^ ERROR explicit lifetime required +} + +fn main() { + f(&()); + g(&()); + h(&()); +} diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr new file mode 100644 index 000000000000..13b765dfa571 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr @@ -0,0 +1,27 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/projection-type-lifetime-mismatch.rs:18:5 + | +LL | fn f(x: &impl for<'a> X = &'a ()>) -> &'static () { + | ------------------------------- help: add explicit lifetime `'static` to the type of `x`: `&'static impl for<'a> X = &'a ()>` +LL | x.m() + | ^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/projection-type-lifetime-mismatch.rs:23:5 + | +LL | fn g X = &'a ()>>(x: &T) -> &'static () { + | -- help: add explicit lifetime `'static` to the type of `x`: `&'static T` +LL | x.m() + | ^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/projection-type-lifetime-mismatch.rs:28:5 + | +LL | fn h(x: &()) -> &'static () { + | --- help: add explicit lifetime `'static` to the type of `x`: `&'static ()` +LL | x.m() + | ^^^^^ lifetime `'static` required + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs new file mode 100644 index 000000000000..7bcc7ba752ad --- /dev/null +++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs @@ -0,0 +1,28 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +pub trait X { + type Y<'a: 'static>; + //~^ WARNING unnecessary lifetime parameter +} + +impl X for () { + type Y<'a> = &'a (); +} + +struct B<'a, T: for<'r> X = &'r ()>> { + f: ::Y<'a>, + //~^ ERROR lifetime bound not satisfied +} + +struct C<'a, T: X> { + f: ::Y<'a>, + //~^ ERROR lifetime bound not satisfied +} + +struct D<'a> { + f: <() as X>::Y<'a>, + //~^ ERROR lifetime bound not satisfied +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr new file mode 100644 index 000000000000..1c81d33ccfe7 --- /dev/null +++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr @@ -0,0 +1,50 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/unsatified-item-lifetime-bound.rs:5:12 + | +LL | type Y<'a: 'static>; + | ^^^^^^^^^^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +error[E0478]: lifetime bound not satisfied + --> $DIR/unsatified-item-lifetime-bound.rs:14:8 + | +LL | f: ::Y<'a>, + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined on the struct at 13:10 + --> $DIR/unsatified-item-lifetime-bound.rs:13:10 + | +LL | struct B<'a, T: for<'r> X = &'r ()>> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error[E0478]: lifetime bound not satisfied + --> $DIR/unsatified-item-lifetime-bound.rs:19:8 + | +LL | f: ::Y<'a>, + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined on the struct at 18:10 + --> $DIR/unsatified-item-lifetime-bound.rs:18:10 + | +LL | struct C<'a, T: X> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error[E0478]: lifetime bound not satisfied + --> $DIR/unsatified-item-lifetime-bound.rs:24:8 + | +LL | f: <() as X>::Y<'a>, + | ^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined on the struct at 23:10 + --> $DIR/unsatified-item-lifetime-bound.rs:23:10 + | +LL | struct D<'a> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0478`.