Check projections are well-formed when using projection candidates
This commit is contained in:
parent
87f2f42dc2
commit
b3057f4d5f
13 changed files with 278 additions and 30 deletions
|
|
@ -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>>()
|
||||
}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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>()
|
||||
}
|
||||
|
|
@ -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`.
|
||||
23
src/test/ui/specialization/issue-38091-2.rs
Normal file
23
src/test/ui/specialization/issue-38091-2.rs
Normal file
|
|
@ -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`
|
||||
}
|
||||
23
src/test/ui/specialization/issue-38091-2.stderr
Normal file
23
src/test/ui/specialization/issue-38091-2.stderr
Normal file
|
|
@ -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`.
|
||||
|
|
@ -18,4 +18,5 @@ trait Valid {}
|
|||
|
||||
fn main() {
|
||||
Iterate::iterate(0);
|
||||
//~^ ERROR overflow evaluating the requirement `{integer}: Check`
|
||||
}
|
||||
|
|
@ -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}`
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0275, E0277.
|
||||
For more information about an error, try `rustc --explain E0275`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue