Handle Self restriction needed

This commit is contained in:
Esteban Küber 2019-10-08 16:03:38 -07:00
parent dbd75c8c40
commit 99ab45b91d
14 changed files with 76 additions and 37 deletions

View file

@ -986,6 +986,34 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
while let Some(node) = self.tcx.hir().find(hir_id) {
debug!("suggest_restricting_param_bound node={:?}", node);
match node {
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(decl, _, generics, _), ..
}) |
hir::Node::TraitItem(hir::TraitItem {
generics,
kind: hir::TraitItemKind::Method(hir::MethodSig { decl, .. }, _), ..
}) |
hir::Node::ImplItem(hir::ImplItem {
generics,
kind: hir::ImplItemKind::Method(hir::MethodSig { decl, .. }, _), ..
}) if param_ty.name.as_str() == "Self" => {
if !generics.where_clause.predicates.is_empty() {
err.span_suggestion(
generics.where_clause.span().unwrap().shrink_to_hi(),
"consider further restricting `Self`",
format!(", {}", trait_ref.to_predicate()),
Applicability::MachineApplicable,
);
} else {
err.span_suggestion(
decl.output.span().shrink_to_hi(),
"consider further restricting `Self`",
format!(" where {}", 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 `Self: Get` is not satisfied
--> $DIR/associated-types-for-unimpl-trait.rs:7:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
= help: consider adding a `where Self: Get` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^
| | |
| | help: consider further restricting `Self`: `where Self: Get`
| the trait `Get` is not implemented for `Self`
error: aborting due to previous error

View file

@ -2,9 +2,10 @@ error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
= help: consider adding a `where Self: Get` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^
| | |
| | help: consider further restricting `Self`: `where Self: Get`
| the trait `Get` is not implemented for `Self`
error: aborting due to previous error

View file

@ -2,9 +2,10 @@ error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:17:5
|
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
= help: consider adding a `where Self: Get` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^
| | |
| | help: consider further restricting `Self`: `where Self: Get`
| the trait `Get` is not implemented for `Self`
error[E0277]: the trait bound `(T, U): Get` is not satisfied
--> $DIR/associated-types-no-suitable-supertrait.rs:22:5

View file

@ -2,9 +2,10 @@ error[E0277]: the trait bound `Self: Get` is not satisfied
--> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:9:5
|
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
= help: consider adding a `where Self: Get` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | |
| | help: consider further restricting `Self`: `where Self: Get`
| the trait `Get` is not implemented for `Self`
error: aborting due to previous error

View file

@ -7,13 +7,13 @@ LL | trait From<Src> {
LL | / fn to<Dst>(
LL | | self
LL | | ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
| | - help: consider further restricting `Self`: `, Self: std::marker::Sized`
LL | | From::from(self)
LL | | }
| |_____^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Self`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where Self: std::marker::Sized` bound
error: aborting due to previous error

View file

@ -2,11 +2,12 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation
--> $DIR/issue-27078.rs:5:12
|
LL | fn foo(self) -> &'static i32 {
| ^^^^ doesn't have a size known at compile-time
| ^^^^ - help: consider further restricting `Self`: `where Self: std::marker::Sized`
| |
| doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `Self`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where Self: std::marker::Sized` bound
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature

View file

@ -4,10 +4,10 @@ error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
LL | fn op(_: T) -> Self;
| -------------------- required by `Tr::op`
...
LL | fn test<U>(u: U) -> Self {
| - help: consider further restricting `Self`: `where Self: Tr<U>`
LL | Tr::op(u)
| ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
|
= help: consider adding a `where Self: Tr<U>` bound
error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
--> $DIR/type-params-in-different-spaces-2.rs:16:9
@ -15,10 +15,10 @@ error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
LL | fn op(_: T) -> Self;
| -------------------- required by `Tr::op`
...
LL | fn test<U>(u: U) -> Self {
| - help: consider further restricting `Self`: `where Self: Tr<U>`
LL | Tr::op(u)
| ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
|
= help: consider adding a `where Self: Tr<U>` bound
error: aborting due to 2 previous errors

View file

@ -4,14 +4,15 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| ----------------------- required by `Bar`
...
LL | / fn bar(&self, x: &Bar<Self>) {
LL | fn bar(&self, x: &Bar<Self>) {
| ^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq`
| _____|
| |
LL | |
LL | | //
LL | | // Here, Eq ought to be implemented.
LL | | }
| |_____^ the trait `std::cmp::Eq` is not implemented for `Self`
|
= help: consider adding a `where Self: std::cmp::Eq` bound
error: aborting due to previous error

View file

@ -4,15 +4,16 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| ----------------------- required by `Bar`
...
LL | / fn bar(&self) -> Bar<Self> {
LL | fn bar(&self) -> Bar<Self> {
| ^ - help: consider further restricting `Self`: `where Self: std::cmp::Eq`
| _____|
| |
LL | |
LL | | //
LL | | // Here, Eq ought to be implemented.
LL | | loop { }
LL | | }
| |_____^ the trait `std::cmp::Eq` is not implemented for `Self`
|
= help: consider adding a `where Self: std::cmp::Eq` bound
error: aborting due to previous error

View file

@ -4,14 +4,15 @@ error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
LL | trait Bar<T:Eq+?Sized> { }
| ---------------------- required by `Bar`
...
LL | / fn bar<A>(&self) where A: Bar<Self> {
LL | fn bar<A>(&self) where A: Bar<Self> {
| ^ - help: consider further restricting `Self`: `, Self: std::cmp::Eq`
| _____|
| |
LL | |
LL | | //
LL | | // Here, Eq ought to be implemented.
LL | | }
| |_____^ the trait `std::cmp::Eq` is not implemented for `Self`
|
= help: consider adding a `where Self: std::cmp::Eq` bound
error: aborting due to previous error

View file

@ -5,9 +5,10 @@ LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| ----------------------- required by `Bar`
...
LL | fn bar(&self, x: &Bar<Self>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self`
|
= help: consider adding a `where Self: std::cmp::Eq` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | |
| | help: consider further restricting `Self`: `where Self: std::cmp::Eq`
| the trait `std::cmp::Eq` is not implemented for `Self`
error: aborting due to previous error

View file

@ -5,9 +5,10 @@ LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| ----------------------- required by `Bar`
...
LL | fn bar(&self) -> &Bar<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self`
|
= help: consider adding a `where Self: std::cmp::Eq` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | |
| | help: consider further restricting `Self`: `where Self: std::cmp::Eq`
| the trait `std::cmp::Eq` is not implemented for `Self`
error: aborting due to previous error

View file

@ -5,9 +5,10 @@ LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| ----------------------- required by `Bar`
...
LL | fn bar(&self) where Self: Sized, Bar<Self>: Copy;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self`
|
= help: consider adding a `where Self: std::cmp::Eq` bound
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | |
| | help: consider further restricting `Self`: `, Self: std::cmp::Eq`
| the trait `std::cmp::Eq` is not implemented for `Self`
error: aborting due to previous error