diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-10-09 15:54:23 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-10-15 13:55:44 -0700 |
| commit | bc744bca9063cd9145fceed4ba7ef14cab0ecdd6 (patch) | |
| tree | f1d4115c2884417e23b667ddeed976e4942000ef /src | |
| parent | 5cc99eed04005108797fbba82eaf8ef7918051db (diff) | |
| download | rust-bc744bca9063cd9145fceed4ba7ef14cab0ecdd6.tar.gz rust-bc744bca9063cd9145fceed4ba7ef14cab0ecdd6.zip | |
Suggest associated bound restrictions in `impl`s
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/hir/mod.rs | 6 | ||||
| -rw-r--r-- | src/librustc/traits/error_reporting.rs | 18 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-38821.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/suggestions/missing-assoc-type-bound-restriction.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr | 43 |
5 files changed, 95 insertions, 2 deletions
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7350f89018b..fa0f620530d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -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. diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 2ac691b47ac..91106d35a7e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -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, .. }) | diff --git a/src/test/ui/issues/issue-38821.stderr b/src/test/ui/issues/issue-38821.stderr index dbd204ec299..3e2af7c44e4 100644 --- a/src/test/ui/issues/issue-38821.stderr +++ b/src/test/ui/issues/issue-38821.stderr @@ -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 diff --git a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.rs b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.rs new file mode 100644 index 00000000000..265ccb3125c --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.rs @@ -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() {} diff --git a/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr new file mode 100644 index 00000000000..bdea8ab97e5 --- /dev/null +++ b/src/test/ui/suggestions/missing-assoc-type-bound-restriction.stderr @@ -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`. |
