Skip to content

Commit

Permalink
change from review and show full type if it can be deref
Browse files Browse the repository at this point in the history
  • Loading branch information
ABouttefeux committed May 22, 2021
1 parent 5b802ed commit 120691c
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 86 deletions.
89 changes: 37 additions & 52 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,27 +388,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut ty_str_reported = ty_str.clone();
if let ty::Adt(_, ref generics) = actual.kind() {
if generics.len() > 0 {
let candidate_numbers: usize = self
.autoderef(span, actual)
.map(|(ty, _)| {
if let ty::Adt(ref adt_deref, _) = ty.kind() {
self.tcx
.inherent_impls(adt_deref.did)
.iter()
.filter_map(|def_id| {
self.associated_item(
*def_id,
item_name,
Namespace::ValueNS,
)
})
.count()
} else {
0
}
})
.sum();
if candidate_numbers == 0 && unsatisfied_predicates.is_empty() {
let mut autoderef = self.autoderef(span, actual);
let candidate_found = autoderef.any(|(ty, _)| {
if let ty::Adt(ref adt_deref, _) = ty.kind() {
self.tcx
.inherent_impls(adt_deref.did)
.iter()
.filter_map(|def_id| {
self.associated_item(
*def_id,
item_name,
Namespace::ValueNS,
)
})
.count()
>= 1
} else {
false
}
});
let has_deref = autoderef.step_count() > 0;
if !candidate_found
&& !has_deref
&& unsatisfied_predicates.is_empty()
{
if let Some((path_string, _)) = ty_str.split_once('<') {
ty_str_reported = path_string.to_string();
}
Expand Down Expand Up @@ -501,8 +504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// So we avoid suggestion method with Box<Self>
// for instance
self.tcx.at(span).type_of(*def_id) != actual
&& self.tcx.at(span).type_of(*def_id)
!= rcvr_ty
&& self.tcx.at(span).type_of(*def_id) != rcvr_ty
}
(Mode::Path, false, _) => true,
_ => false,
Expand All @@ -515,38 +517,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if inherent_impls_candidate.len() > 0 {
inherent_impls_candidate.sort();
inherent_impls_candidate.dedup();
let type_candidates = inherent_impls_candidate
.iter()
.map(|impl_item| self.tcx.at(span).type_of(*impl_item))
.collect::<Vec<_>>();
// number of type to shows at most.
const LIMIT: usize = 3;
let mut note = format!("the {item_kind} was found for");
if inherent_impls_candidate.len() > 1 {
for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2)
{
let impl_ty = self.tcx.at(span).type_of(*impl_item);
note = format!("{} {},", note, impl_ty);
}
let impl_ty = self.tcx.at(span).type_of(
inherent_impls_candidate
[inherent_impls_candidate.len() - 1],
);
if inherent_impls_candidate.len() > LIMIT {
note = format!("{} {},", note, impl_ty);
} else {
note = format!("{} {} and", note, impl_ty);
}
let limit = if type_candidates.len() == 4 { 4 } else { 3 };
for ty in type_candidates.iter().take(limit) {
err.note(&format!("the {item_kind} was found for {}", ty));
}
let impl_ty = self
.tcx
.at(span)
.type_of(*inherent_impls_candidate.last().unwrap());
note = format!("{} {}", note, impl_ty);
if inherent_impls_candidate.len() > LIMIT {
note = format!(
"{} and {} more",
note,
inherent_impls_candidate.len() - LIMIT
);
if type_candidates.len() > limit {
err.note(&format!(
"the {item_kind} was found for {} more types",
type_candidates.len() - limit
));
}
err.note(&format!("{}.", note));
}
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/auto-ref-slice-plus-ref.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0599]: no method named `test_mut` found for struct `Vec` in the current scope
error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope
--> $DIR/auto-ref-slice-plus-ref.rs:7:7
|
LL | a.test_mut();
Expand All @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it
LL | trait MyIter {
| ^^^^^^^^^^^^

error[E0599]: no method named `test` found for struct `Vec` in the current scope
error[E0599]: no method named `test` found for struct `Vec<{integer}>` in the current scope
--> $DIR/auto-ref-slice-plus-ref.rs:8:7
|
LL | a.test();
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/class-cast-to-trait.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0599]: no method named `eat` found for struct `Box` in the current scope
error[E0599]: no method named `eat` found for struct `Box<dyn Noisy>` in the current scope
--> $DIR/class-cast-to-trait.rs:53:8
|
LL | nyan.eat();
Expand Down
24 changes: 12 additions & 12 deletions src/test/ui/impl-trait/no-method-suggested-traits.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub;
LL | use no_method_suggested_traits::Reexported;
|

error[E0599]: no method named `method` found for struct `Rc` in the current scope
error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:26:44
|
LL | std::rc::Rc::new(&mut Box::new(&1u32)).method();
Expand Down Expand Up @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
LL | use foo::Bar;
|

error[E0599]: no method named `method` found for struct `Rc` in the current scope
error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:32:43
|
LL | std::rc::Rc::new(&mut Box::new(&'a')).method();
Expand All @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
LL | use no_method_suggested_traits::foo::PubPub;
|

error[E0599]: no method named `method` found for struct `Rc` in the current scope
error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:37:44
|
LL | std::rc::Rc::new(&mut Box::new(&1i32)).method();
Expand Down Expand Up @@ -98,7 +98,7 @@ LL | Foo.method();
candidate #3: `no_method_suggested_traits::qux::PrivPub`
candidate #4: `Reexported`

error[E0599]: no method named `method` found for struct `Rc` in the current scope
error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:42:43
|
LL | std::rc::Rc::new(&mut Box::new(&Foo)).method();
Expand All @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it
LL | pub trait Bar {
| ^^^^^^^^^^^^^

error[E0599]: no method named `method2` found for struct `Rc` in the current scope
error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:47:44
|
LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2();
Expand All @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it
LL | pub trait Bar {
| ^^^^^^^^^^^^^

error[E0599]: no method named `method2` found for struct `Rc` in the current scope
error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:52:71
|
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2();
Expand All @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it
LL | pub trait Bar {
| ^^^^^^^^^^^^^

error[E0599]: no method named `method2` found for struct `Rc` in the current scope
error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:56:74
|
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2();
Expand All @@ -202,7 +202,7 @@ LL | Foo.method3();
= note: the following trait defines an item `method3`, perhaps you need to implement it:
candidate #1: `PubPub`

error[E0599]: no method named `method3` found for struct `Rc` in the current scope
error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Foo>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:61:43
|
LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3();
Expand All @@ -225,7 +225,7 @@ LL | Bar::X.method3();
= note: the following trait defines an item `method3`, perhaps you need to implement it:
candidate #1: `PubPub`

error[E0599]: no method named `method3` found for struct `Rc` in the current scope
error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Bar>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:65:46
|
LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3();
Expand All @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc
LL | 1_usize.method3();
| ^^^^^^^ method not found in `usize`

error[E0599]: no method named `method3` found for struct `Rc` in the current scope
error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:70:47
|
LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3();
Expand All @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr
LL | no_method_suggested_traits::Foo.method3();
| ^^^^^^^ method not found in `no_method_suggested_traits::Foo`

error[E0599]: no method named `method3` found for struct `Rc` in the current scope
error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:72:71
|
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3();
Expand All @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai
LL | no_method_suggested_traits::Bar::X.method3();
| ^^^^^^^ method not found in `no_method_suggested_traits::Bar`

error[E0599]: no method named `method3` found for struct `Rc` in the current scope
error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:75:74
|
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3();
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-30123.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0599]: no function or associated item named `new_undirected` found for st
LL | let ug = Graph::<i32, i32>::new_undirected();
| ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph<i32, i32>`
|
= note: The function or associated item was found for issue_30123_aux::Graph<N, E, Undirected>.
= note: the function or associated item was found for issue_30123_aux::Graph<N, E, Undirected>

error: aborting due to previous error

Expand Down
20 changes: 18 additions & 2 deletions src/test/ui/methods/method-not-found-generic-arg-elision.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Test for issue 81576
// Remove generic arguments if no method is found for all possible generic argument

use std::marker::PhantomData;

struct Wrapper2<'a, T, const C: usize> {
x: &'a T,
Expand All @@ -19,8 +20,6 @@ impl<'a, const C: usize> Wrapper2<'a, i32, C> {
}
struct Wrapper<T>(T);



impl Wrapper<i8> {
fn method(&self) {}
}
Expand Down Expand Up @@ -62,6 +61,20 @@ impl Other {
fn other(&self) {}
}

struct Struct<T>{
_phatom: PhantomData<T>
}

impl<T> Default for Struct<T> {
fn default() -> Self {
Self{ _phatom: PhantomData }
}
}

impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord> Struct<T> {
fn method(&self) {}
}

fn main() {
let point_f64 = Point{ x: 1_f64, y: 1_f64};
let d = point_f64.distance();
Expand All @@ -87,4 +100,7 @@ fn main() {
let a = vec![1, 2, 3];
a.not_found();
//~^ ERROR no method named `not_found` found for struct `Vec
let s = Struct::<f64>::default();
s.method();
//~^ ERROR the method `method` exists for struct `Struct<f64>`, but its trait bounds were not satisfied
}
Loading

0 comments on commit 120691c

Please sign in to comment.