mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Account for arbitrary self types in E0599
This commit is contained in:
parent
392d853589
commit
01286408c1
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user