Suggest associated bound restrictions in impls

This commit is contained in:
Esteban Küber 2019-10-09 15:54:23 -07:00
parent 5cc99eed04
commit bc744bca90
5 changed files with 95 additions and 2 deletions

View file

@ -669,6 +669,12 @@ impl WhereClause {
Some(self.span)
}
}
/// The `WhereClause` under normal circumstances points at either the predicates or the empty
/// space where the `where` clause should be. Only of use for diagnostic suggestions.
pub fn span_for_predicates_or_empty_place(&self) -> Span {
self.span
}
}
/// A single predicate in a where-clause.

View file

@ -1044,6 +1044,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
return;
}
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(_, _, _, generics, ..), ..
}) if projection.is_some() => {
err.span_suggestion(
generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi(),
"consider further restricting the associated type",
format!(
"{} {}", if generics.where_clause.predicates.is_empty() {
" where"
} else {
" ,"
},
trait_ref.to_predicate(),
),
Applicability::MachineApplicable,
);
return;
}
hir::Node::Item(hir::Item { kind: hir::ItemKind::Struct(_, generics), span, .. }) |
hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, generics), span, .. }) |
hir::Node::Item(hir::Item { kind: hir::ItemKind::Union(_, generics), span, .. }) |

View file

@ -2,9 +2,10 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
--> $DIR/issue-38821.rs:23:17
|
LL | #[derive(Debug, Copy, Clone)]
| ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
| ^^^^- help: consider further restricting the associated type: `, <Col as Expression>::SqlType: NotNull`
| |
| the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
|
= help: consider adding a `where <Col as Expression>::SqlType: NotNull` bound
= note: required because of the requirements on the impl of `IntoNullable` for `<Col as Expression>::SqlType`
error: aborting due to previous error

View file

@ -0,0 +1,25 @@
// Running rustfix would cause the same suggestion to be applied multiple times, which results in
// invalid code.
trait Parent {
type Ty;
type Assoc: Child<Self::Ty>;
}
trait Child<T> {}
struct ChildWrapper<T>(T);
impl<A, T> Child<A> for ChildWrapper<T> where T: Child<A> {}
struct ParentWrapper<T>(T);
impl<A, T: Parent<Ty = A>> Parent for ParentWrapper<T> {
//~^ ERROR the trait bound `<T as Parent>::Assoc: Child<A>` is not satisfied
//~| ERROR the trait bound `<T as Parent>::Assoc: Child<A>` is not satisfied
type Ty = A;
type Assoc = ChildWrapper<T::Assoc>;
//~^ ERROR the trait bound `<T as Parent>::Assoc: Child<A>` is not satisfied
}
fn main() {}

View file

@ -0,0 +1,43 @@
error[E0277]: the trait bound `<T as Parent>::Assoc: Child<A>` is not satisfied
--> $DIR/missing-assoc-type-bound-restriction.rs:17:1
|
LL | trait Parent {
| ------------ required by `Parent`
...
LL | impl<A, T: Parent<Ty = A>> Parent for ParentWrapper<T> {
| ^ - help: consider further restricting the associated type: `where <T as Parent>::Assoc: Child<A>`
| _|
| |
LL | |
LL | |
LL | | type Ty = A;
LL | | type Assoc = ChildWrapper<T::Assoc>;
LL | |
LL | | }
| |_^ the trait `Child<A>` is not implemented for `<T as Parent>::Assoc`
error[E0277]: the trait bound `<T as Parent>::Assoc: Child<A>` is not satisfied
--> $DIR/missing-assoc-type-bound-restriction.rs:17:28
|
LL | impl<A, T: Parent<Ty = A>> Parent for ParentWrapper<T> {
| ^^^^^^ - help: consider further restricting the associated type: `where <T as Parent>::Assoc: Child<A>`
| |
| the trait `Child<A>` is not implemented for `<T as Parent>::Assoc`
|
= note: required because of the requirements on the impl of `Child<A>` for `ChildWrapper<<T as Parent>::Assoc>`
error[E0277]: the trait bound `<T as Parent>::Assoc: Child<A>` is not satisfied
--> $DIR/missing-assoc-type-bound-restriction.rs:21:5
|
LL | trait Parent {
| ------------ required by `Parent`
...
LL | impl<A, T: Parent<Ty = A>> Parent for ParentWrapper<T> {
| - help: consider further restricting the associated type: `where <T as Parent>::Assoc: Child<A>`
...
LL | type Assoc = ChildWrapper<T::Assoc>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Child<A>` is not implemented for `<T as Parent>::Assoc`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.