Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more context to E0599 errors #69255

Merged
merged 17 commits into from
Feb 29, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/librustc_typeck/check/method/suggest.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ use rustc_hir::intravisit;
use rustc_hir::{ExprKind, Node, QPath};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::Obligation;
use rustc_span::symbol::kw;
use rustc_span::{source_map, FileName, Span};
use syntax::ast;
use syntax::util::lev_distance;
@@ -893,6 +894,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source);

let mut arbitrary_rcvr = vec![];
// There are no traits implemented, so lets suggest some traits to
// implement, by finding ones that have the item name, and are
// legal to implement.
@@ -909,12 +911,61 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& self
.associated_item(info.def_id, item_name, Namespace::ValueNS)
.filter(|item| {
if let ty::AssocKind::Method = item.kind {
let id = self.tcx.hir().as_local_hir_id(item.def_id);
if let Some(hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Method(fn_sig, method),
..
})) = id.map(|id| self.tcx.hir().get(id))
{
let self_first_arg = match method {
hir::TraitMethod::Required([ident, ..]) => {
ident.name == kw::SelfLower
}
hir::TraitMethod::Provided(body_id) => {
match &self.tcx.hir().body(*body_id).params[..] {
[hir::Param {
pat:
hir::Pat {
kind:
hir::PatKind::Binding(
_,
_,
ident,
..,
),
..
},
..
}, ..] => ident.name == kw::SelfLower,
_ => false,
}
}
_ => false,
};

if !fn_sig.decl.implicit_self.has_implicit_self()
&& self_first_arg
{
if let Some(ty) = fn_sig.decl.inputs.get(0) {
arbitrary_rcvr.push(ty.span);
}
return false;
}
}
}
// We only want to suggest public or local traits (#45781).
item.vis == ty::Visibility::Public || info.def_id.is_local()
})
.is_some()
})
.collect::<Vec<_>>();
for span in &arbitrary_rcvr {
err.span_label(
*span,
"the method might not be found because of this arbitrary self type",
);
}

if !candidates.is_empty() {
// Sort from most relevant to least relevant.
6 changes: 2 additions & 4 deletions src/test/ui/issues/issue-5153.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
error[E0599]: no method named `foo` found for reference `&dyn Foo` in the current scope
--> $DIR/issue-5153.rs:10:27
|
LL | trait Foo {
| --------- `Foo` defines an item `foo`, perhaps you need to implement it
LL | fn foo(self: Box<Self>);
| --------- the method might not be found because of this arbitrary self type
...
LL | (&5isize as &dyn Foo).foo();
| ^^^ method not found in `&dyn Foo`
|
= help: items from traits can only be used if the trait is implemented and in scope

error: aborting due to previous error

12 changes: 4 additions & 8 deletions src/test/ui/object-pointer-types.stderr
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
error[E0599]: no method named `owned` found for reference `&dyn Foo` in the current scope
--> $DIR/object-pointer-types.rs:11:7
|
LL | trait Foo {
| --------- `Foo` defines an item `owned`, perhaps you need to implement it
LL | fn owned(self: Box<Self>);
| --------- the method might not be found because of this arbitrary self type
...
LL | x.owned();
| ^^^^^ method not found in `&dyn Foo`
|
= help: items from traits can only be used if the trait is implemented and in scope

error[E0599]: no method named `owned` found for mutable reference `&mut dyn Foo` in the current scope
--> $DIR/object-pointer-types.rs:17:7
|
LL | trait Foo {
| --------- `Foo` defines an item `owned`, perhaps you need to implement it
LL | fn owned(self: Box<Self>);
| --------- the method might not be found because of this arbitrary self type
...
LL | x.owned();
| ^^^^^ method not found in `&mut dyn Foo`
|
= help: items from traits can only be used if the trait is implemented and in scope

error[E0599]: no method named `managed` found for struct `std::boxed::Box<(dyn Foo + 'static)>` in the current scope
--> $DIR/object-pointer-types.rs:23:7
Original file line number Diff line number Diff line change
@@ -2,16 +2,14 @@ error[E0599]: no method named `foo` found for struct `A` in the current scope
--> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7
|
LL | trait B { fn foo(self: Box<Self>); }
| ------- --- the method is available for `std::boxed::Box<A>` here
| |
| `B` defines an item `foo`, perhaps you need to implement it
| --- --------- the method might not be found because of this arbitrary self type
| |
| the method is available for `std::boxed::Box<A>` here
LL | struct A;
| --------- method `foo` not found for this
...
LL | A.foo()
| ^^^ method not found in `A`
|
= help: items from traits can only be used if the trait is implemented and in scope

error: aborting due to previous error