Add comments and tests explaining the shallow substitution rule
This commit is contained in:
parent
5e9317a023
commit
ff5d11e043
3 changed files with 76 additions and 52 deletions
|
|
@ -66,28 +66,43 @@ trait D where
|
|||
type Assoc = NotClone;
|
||||
}
|
||||
|
||||
trait Foo2<T> where
|
||||
<Self as Foo2<T>>::Bar: Clone,
|
||||
// Test behavior of the check when defaults refer to other defaults:
|
||||
|
||||
// Shallow substitution rejects this trait since `Baz` isn't guaranteed to be
|
||||
// `Clone`.
|
||||
trait Foo2<T> {
|
||||
type Bar: Clone = Vec<Self::Baz>;
|
||||
//~^ ERROR the trait bound `<Self as Foo2<T>>::Baz: std::clone::Clone` is not satisfied
|
||||
{
|
||||
type Bar = Vec<Self::Baz>;
|
||||
type Baz = T;
|
||||
}
|
||||
|
||||
trait Foo3<T: Clone> where
|
||||
<Self as Foo3<T>>::Bar: Clone,
|
||||
//~^ ERROR the trait bound `<Self as Foo3<T>>::Baz: std::clone::Clone` is not satisfied
|
||||
{
|
||||
type Bar = Vec<Self::Baz>;
|
||||
// Adding a `T: Clone` bound doesn't help since the requirement doesn't see `T`
|
||||
// because of the shallow substitution. If we did a deep substitution instead,
|
||||
// this would be accepted.
|
||||
trait Foo25<T: Clone> {
|
||||
type Bar: Clone = Vec<Self::Baz>;
|
||||
//~^ ERROR the trait bound `<Self as Foo25<T>>::Baz: std::clone::Clone` is not satisfied
|
||||
type Baz = T;
|
||||
}
|
||||
|
||||
trait Foo4<T> where
|
||||
<Self as Foo4<T>>::Bar: Clone,
|
||||
{
|
||||
type Bar = Vec<Self::Baz>;
|
||||
type Baz: Clone = T;
|
||||
// Adding the `Baz: Clone` bound isn't enough since the default is type
|
||||
// parameter `T`, which also might not be `Clone`.
|
||||
trait Foo3<T> where
|
||||
Self::Bar: Clone,
|
||||
Self::Baz: Clone,
|
||||
//~^ ERROR the trait bound `T: std::clone::Clone` is not satisfied
|
||||
{
|
||||
type Bar = Vec<Self::Baz>;
|
||||
type Baz = T;
|
||||
}
|
||||
|
||||
// This one finally works, with `Clone` bounds on all assoc. types and the type
|
||||
// parameter.
|
||||
trait Foo4<T> where
|
||||
T: Clone,
|
||||
{
|
||||
type Bar: Clone = Vec<Self::Baz>;
|
||||
type Baz: Clone = T;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -104,61 +104,49 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: std::clone::Clone` is not satisfied
|
||||
--> $DIR/defaults-suitability.rs:70:29
|
||||
--> $DIR/defaults-suitability.rs:74:15
|
||||
|
|
||||
LL | <Self as Foo2<T>>::Bar: Clone,
|
||||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `<Self as Foo2<T>>::Baz`
|
||||
LL | type Bar: Clone = Vec<Self::Baz>;
|
||||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `<Self as Foo2<T>>::Baz`
|
||||
|
|
||||
= help: consider adding a `where <Self as Foo2<T>>::Baz: std::clone::Clone` bound
|
||||
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<<Self as Foo2<T>>::Baz>`
|
||||
note: required by `Foo2`
|
||||
--> $DIR/defaults-suitability.rs:69:1
|
||||
--> $DIR/defaults-suitability.rs:73:1
|
||||
|
|
||||
LL | / trait Foo2<T> where
|
||||
LL | | <Self as Foo2<T>>::Bar: Clone,
|
||||
LL | |
|
||||
LL | | {
|
||||
LL | | type Bar = Vec<Self::Baz>;
|
||||
LL | | type Baz = T;
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | trait Foo2<T> {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `<Self as Foo3<T>>::Baz: std::clone::Clone` is not satisfied
|
||||
--> $DIR/defaults-suitability.rs:78:29
|
||||
error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: std::clone::Clone` is not satisfied
|
||||
--> $DIR/defaults-suitability.rs:83:15
|
||||
|
|
||||
LL | <Self as Foo3<T>>::Bar: Clone,
|
||||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `<Self as Foo3<T>>::Baz`
|
||||
LL | type Bar: Clone = Vec<Self::Baz>;
|
||||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `<Self as Foo25<T>>::Baz`
|
||||
|
|
||||
= help: consider adding a `where <Self as Foo3<T>>::Baz: std::clone::Clone` bound
|
||||
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<<Self as Foo3<T>>::Baz>`
|
||||
note: required by `Foo3`
|
||||
--> $DIR/defaults-suitability.rs:77:1
|
||||
= help: consider adding a `where <Self as Foo25<T>>::Baz: std::clone::Clone` bound
|
||||
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<<Self as Foo25<T>>::Baz>`
|
||||
note: required by `Foo25`
|
||||
--> $DIR/defaults-suitability.rs:82:1
|
||||
|
|
||||
LL | / trait Foo3<T: Clone> where
|
||||
LL | | <Self as Foo3<T>>::Bar: Clone,
|
||||
LL | |
|
||||
LL | | {
|
||||
LL | | type Bar = Vec<Self::Baz>;
|
||||
LL | | type Baz = T;
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | trait Foo25<T: Clone> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `T: std::clone::Clone` is not satisfied
|
||||
--> $DIR/defaults-suitability.rs:89:15
|
||||
--> $DIR/defaults-suitability.rs:92:16
|
||||
|
|
||||
LL | type Baz: Clone = T;
|
||||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `T`
|
||||
LL | Self::Baz: Clone,
|
||||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `T`
|
||||
|
|
||||
= help: consider adding a `where T: std::clone::Clone` bound
|
||||
note: required by `Foo4`
|
||||
--> $DIR/defaults-suitability.rs:85:1
|
||||
note: required by `Foo3`
|
||||
--> $DIR/defaults-suitability.rs:90:1
|
||||
|
|
||||
LL | / trait Foo4<T> where
|
||||
LL | | <Self as Foo4<T>>::Bar: Clone,
|
||||
LL | | {
|
||||
LL | | type Bar = Vec<Self::Baz>;
|
||||
LL | | type Baz: Clone = T;
|
||||
LL | / trait Foo3<T> where
|
||||
LL | | Self::Bar: Clone,
|
||||
LL | | Self::Baz: Clone,
|
||||
LL | |
|
||||
... |
|
||||
LL | | type Baz = T;
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue