diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2020-06-28 12:41:46 +0100 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-10-06 11:19:29 +0100 |
| commit | b3057f4d5fe7156aa85e1844d3638fa14ba48b79 (patch) | |
| tree | 3dcb6de03084fe3bdd14ba25d09009c6b427b5cf /src | |
| parent | 87f2f42dc2c81dd842451e6c68d12abdc5fe3ecf (diff) | |
| download | rust-b3057f4d5fe7156aa85e1844d3638fa14ba48b79.tar.gz rust-b3057f4d5fe7156aa85e1844d3638fa14ba48b79.zip | |
Check projections are well-formed when using projection candidates
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs | 62 | ||||
| -rw-r--r-- | src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr | 21 | ||||
| -rw-r--r-- | src/test/ui/generic-associated-types/projection-bound-cycle.rs | 64 | ||||
| -rw-r--r-- | src/test/ui/generic-associated-types/projection-bound-cycle.stderr | 21 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-38091-2.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-38091-2.stderr | 23 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-38091.rs (renamed from src/test/ui/issues/issue-38091.rs) | 1 | ||||
| -rw-r--r-- | src/test/ui/specialization/issue-38091.stderr (renamed from src/test/ui/issues/issue-38091.stderr) | 16 |
8 files changed, 229 insertions, 2 deletions
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs new file mode 100644 index 00000000000..c88fb8ad96e --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs @@ -0,0 +1,62 @@ +// Like `projection-bound-cycle.rs` but this avoids using +// `feature(trivial_bounds)`. + +#![feature(generic_associated_types)] +//~^ WARNING the feature `generic_associated_types` is incomplete + +trait Print { + fn print(); +} + +trait Foo { + type Item: Sized where <Self as Foo>::Item: Sized; +} + +struct Number<T> { t: T } + +impl<T> Foo for Number<T> { + // Well-formedness checks require that the following + // goal is true: + // ``` + // if ([T]: Sized) { # if the where clauses hold + // [T]: Sized # then the bound on the associated type hold + // } + // ``` + // which it is :) + type Item where [T]: Sized = [T]; +} + +struct OnlySized<T> where T: Sized { f: T } +impl<T> Print for OnlySized<T> { + fn print() { + println!("{}", std::mem::size_of::<T>()); + } +} + +trait Bar { + type Assoc: Print; +} + +impl<T> Bar for T where T: Foo { + // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires + // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We + // can use the bound on `Foo::Item` for this, but that requires + // `wf(<T as Foo>::Item)`, which is an invalid cycle. + type Assoc = OnlySized<<T as Foo>::Item>; + //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: std::marker::Sized` +} + +fn foo<T: Print>() { + T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed +} + +fn bar<T: Bar>() { + // we have `FromEnv(T: Bar)` hence + // `<T as Bar>::Assoc` is well-formed and + // `Implemented(<T as Bar>::Assoc: Print)` hold + foo::<<T as Bar>::Assoc>() +} + +fn main() { + bar::<Number<u8>>() +} diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr new file mode 100644 index 00000000000..5967752ef79 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr @@ -0,0 +1,21 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/projection-bound-cycle-generic.rs:4:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information + +error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: std::marker::Sized` + --> $DIR/projection-bound-cycle-generic.rs:45:5 + | +LL | struct OnlySized<T> where T: Sized { f: T } + | - required by this bound in `OnlySized` +... +LL | type Assoc = OnlySized<<T as Foo>::Item>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.rs b/src/test/ui/generic-associated-types/projection-bound-cycle.rs new file mode 100644 index 00000000000..0728dc1bcbc --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-bound-cycle.rs @@ -0,0 +1,64 @@ +// Test case from Chalk. +// Make sure that we make sure that we don't allow arbitrary bounds to be +// proven when a bound and a where clause of an associated type are the same. + +#![feature(generic_associated_types)] +//~^ WARNING the feature `generic_associated_types` is incomplete +#![feature(trivial_bounds)] + +trait Print { + fn print(); +} + +trait Foo { + type Item: Sized where <Self as Foo>::Item: Sized; +} + +struct Number { } + +impl Foo for Number { + // Well-formedness checks require that the following + // goal is true: + // ``` + // if (str: Sized) { # if the where clauses hold + // str: Sized # then the bound on the associated type hold + // } + // ``` + // which it is :) + type Item where str: Sized = str; +} + +struct OnlySized<T> where T: Sized { f: T } +impl<T> Print for OnlySized<T> { + fn print() { + println!("{}", std::mem::size_of::<T>()); + } +} + +trait Bar { + type Assoc: Print; +} + +impl<T> Bar for T where T: Foo { + // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires + // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We + // can use the bound on `Foo::Item` for this, but that requires + // `wf(<T as Foo>::Item)`, which is an invalid cycle. + type Assoc = OnlySized<<T as Foo>::Item>; + //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: std::marker::Sized` +} + +fn foo<T: Print>() { + T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed +} + +fn bar<T: Bar>() { + // we have `FromEnv(T: Bar)` hence + // `<T as Bar>::Assoc` is well-formed and + // `Implemented(<T as Bar>::Assoc: Print)` hold + foo::<<T as Bar>::Assoc>() +} + +fn main() { + bar::<Number>() +} diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr new file mode 100644 index 00000000000..80d102013a7 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr @@ -0,0 +1,21 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/projection-bound-cycle.rs:5:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information + +error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: std::marker::Sized` + --> $DIR/projection-bound-cycle.rs:47:5 + | +LL | struct OnlySized<T> where T: Sized { f: T } + | - required by this bound in `OnlySized` +... +LL | type Assoc = OnlySized<<T as Foo>::Item>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/specialization/issue-38091-2.rs b/src/test/ui/specialization/issue-38091-2.rs new file mode 100644 index 00000000000..da7f6737733 --- /dev/null +++ b/src/test/ui/specialization/issue-38091-2.rs @@ -0,0 +1,23 @@ +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +trait Iterate<'a> { + type Ty: Valid; + fn iterate(self); +} +impl<'a, T> Iterate<'a> for T where T: Check { + default type Ty = (); + default fn iterate(self) {} +} + +trait Check {} +impl<'a, T> Check for T where <T as Iterate<'a>>::Ty: Valid {} + +trait Valid {} + +impl Valid for () {} + +fn main() { + Iterate::iterate(0); + //~^ ERROR overflow evaluating the requirement `{integer}: Check` +} diff --git a/src/test/ui/specialization/issue-38091-2.stderr b/src/test/ui/specialization/issue-38091-2.stderr new file mode 100644 index 00000000000..e776ff0fafb --- /dev/null +++ b/src/test/ui/specialization/issue-38091-2.stderr @@ -0,0 +1,23 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-38091-2.rs:1:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + +error[E0275]: overflow evaluating the requirement `{integer}: Check` + --> $DIR/issue-38091-2.rs:21:5 + | +LL | fn iterate(self); + | ----------------- required by `Iterate::iterate` +... +LL | Iterate::iterate(0); + | ^^^^^^^^^^^^^^^^ + | + = note: required because of the requirements on the impl of `Iterate<'_>` for `{integer}` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/issues/issue-38091.rs b/src/test/ui/specialization/issue-38091.rs index a84391b94d1..cc0eeb53687 100644 --- a/src/test/ui/issues/issue-38091.rs +++ b/src/test/ui/specialization/issue-38091.rs @@ -18,4 +18,5 @@ trait Valid {} fn main() { Iterate::iterate(0); + //~^ ERROR overflow evaluating the requirement `{integer}: Check` } diff --git a/src/test/ui/issues/issue-38091.stderr b/src/test/ui/specialization/issue-38091.stderr index f47fd8d1b0d..beec702b89e 100644 --- a/src/test/ui/issues/issue-38091.stderr +++ b/src/test/ui/specialization/issue-38091.stderr @@ -16,6 +16,18 @@ LL | type Ty: Valid; LL | default type Ty = (); | ^^^^^^^^^^^^^^^^^^^^^ the trait `Valid` is not implemented for `()` -error: aborting due to previous error; 1 warning emitted +error[E0275]: overflow evaluating the requirement `{integer}: Check` + --> $DIR/issue-38091.rs:20:5 + | +LL | fn iterate(self); + | ----------------- required by `Iterate::iterate` +... +LL | Iterate::iterate(0); + | ^^^^^^^^^^^^^^^^ + | + = note: required because of the requirements on the impl of `Iterate<'_>` for `{integer}` + +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0275, E0277. +For more information about an error, try `rustc --explain E0275`. |
