Skip to content

Commit 120691c

Browse files
committed
change from review and show full type if it can be deref
1 parent 5b802ed commit 120691c

9 files changed

+105
-86
lines changed

compiler/rustc_typeck/src/check/method/suggest.rs

+37-52
Original file line numberDiff line numberDiff line change
@@ -388,27 +388,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
388388
let mut ty_str_reported = ty_str.clone();
389389
if let ty::Adt(_, ref generics) = actual.kind() {
390390
if generics.len() > 0 {
391-
let candidate_numbers: usize = self
392-
.autoderef(span, actual)
393-
.map(|(ty, _)| {
394-
if let ty::Adt(ref adt_deref, _) = ty.kind() {
395-
self.tcx
396-
.inherent_impls(adt_deref.did)
397-
.iter()
398-
.filter_map(|def_id| {
399-
self.associated_item(
400-
*def_id,
401-
item_name,
402-
Namespace::ValueNS,
403-
)
404-
})
405-
.count()
406-
} else {
407-
0
408-
}
409-
})
410-
.sum();
411-
if candidate_numbers == 0 && unsatisfied_predicates.is_empty() {
391+
let mut autoderef = self.autoderef(span, actual);
392+
let candidate_found = autoderef.any(|(ty, _)| {
393+
if let ty::Adt(ref adt_deref, _) = ty.kind() {
394+
self.tcx
395+
.inherent_impls(adt_deref.did)
396+
.iter()
397+
.filter_map(|def_id| {
398+
self.associated_item(
399+
*def_id,
400+
item_name,
401+
Namespace::ValueNS,
402+
)
403+
})
404+
.count()
405+
>= 1
406+
} else {
407+
false
408+
}
409+
});
410+
let has_deref = autoderef.step_count() > 0;
411+
if !candidate_found
412+
&& !has_deref
413+
&& unsatisfied_predicates.is_empty()
414+
{
412415
if let Some((path_string, _)) = ty_str.split_once('<') {
413416
ty_str_reported = path_string.to_string();
414417
}
@@ -501,8 +504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
501504
// So we avoid suggestion method with Box<Self>
502505
// for instance
503506
self.tcx.at(span).type_of(*def_id) != actual
504-
&& self.tcx.at(span).type_of(*def_id)
505-
!= rcvr_ty
507+
&& self.tcx.at(span).type_of(*def_id) != rcvr_ty
506508
}
507509
(Mode::Path, false, _) => true,
508510
_ => false,
@@ -515,38 +517,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
515517
if inherent_impls_candidate.len() > 0 {
516518
inherent_impls_candidate.sort();
517519
inherent_impls_candidate.dedup();
520+
let type_candidates = inherent_impls_candidate
521+
.iter()
522+
.map(|impl_item| self.tcx.at(span).type_of(*impl_item))
523+
.collect::<Vec<_>>();
518524
// number of type to shows at most.
519-
const LIMIT: usize = 3;
520-
let mut note = format!("the {item_kind} was found for");
521-
if inherent_impls_candidate.len() > 1 {
522-
for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2)
523-
{
524-
let impl_ty = self.tcx.at(span).type_of(*impl_item);
525-
note = format!("{} {},", note, impl_ty);
526-
}
527-
let impl_ty = self.tcx.at(span).type_of(
528-
inherent_impls_candidate
529-
[inherent_impls_candidate.len() - 1],
530-
);
531-
if inherent_impls_candidate.len() > LIMIT {
532-
note = format!("{} {},", note, impl_ty);
533-
} else {
534-
note = format!("{} {} and", note, impl_ty);
535-
}
525+
let limit = if type_candidates.len() == 4 { 4 } else { 3 };
526+
for ty in type_candidates.iter().take(limit) {
527+
err.note(&format!("the {item_kind} was found for {}", ty));
536528
}
537-
let impl_ty = self
538-
.tcx
539-
.at(span)
540-
.type_of(*inherent_impls_candidate.last().unwrap());
541-
note = format!("{} {}", note, impl_ty);
542-
if inherent_impls_candidate.len() > LIMIT {
543-
note = format!(
544-
"{} and {} more",
545-
note,
546-
inherent_impls_candidate.len() - LIMIT
547-
);
529+
if type_candidates.len() > limit {
530+
err.note(&format!(
531+
"the {item_kind} was found for {} more types",
532+
type_candidates.len() - limit
533+
));
548534
}
549-
err.note(&format!("{}.", note));
550535
}
551536
}
552537
} else {

src/test/ui/auto-ref-slice-plus-ref.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `test_mut` found for struct `Vec` in the current scope
1+
error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope
22
--> $DIR/auto-ref-slice-plus-ref.rs:7:7
33
|
44
LL | a.test_mut();
@@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it
1111
LL | trait MyIter {
1212
| ^^^^^^^^^^^^
1313

14-
error[E0599]: no method named `test` found for struct `Vec` in the current scope
14+
error[E0599]: no method named `test` found for struct `Vec<{integer}>` in the current scope
1515
--> $DIR/auto-ref-slice-plus-ref.rs:8:7
1616
|
1717
LL | a.test();

src/test/ui/class-cast-to-trait.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `eat` found for struct `Box` in the current scope
1+
error[E0599]: no method named `eat` found for struct `Box<dyn Noisy>` in the current scope
22
--> $DIR/class-cast-to-trait.rs:53:8
33
|
44
LL | nyan.eat();

src/test/ui/impl-trait/no-method-suggested-traits.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub;
1616
LL | use no_method_suggested_traits::Reexported;
1717
|
1818

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

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

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

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

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

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

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

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

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

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

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

268-
error[E0599]: no method named `method3` found for struct `Rc` in the current scope
268+
error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope
269269
--> $DIR/no-method-suggested-traits.rs:75:74
270270
|
271271
LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3();

src/test/ui/issues/issue-30123.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0599]: no function or associated item named `new_undirected` found for st
44
LL | let ug = Graph::<i32, i32>::new_undirected();
55
| ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph<i32, i32>`
66
|
7-
= note: The function or associated item was found for issue_30123_aux::Graph<N, E, Undirected>.
7+
= note: the function or associated item was found for issue_30123_aux::Graph<N, E, Undirected>
88

99
error: aborting due to previous error
1010

src/test/ui/methods/method-not-found-generic-arg-elision.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Test for issue 81576
22
// Remove generic arguments if no method is found for all possible generic argument
33

4+
use std::marker::PhantomData;
45

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

22-
23-
2423
impl Wrapper<i8> {
2524
fn method(&self) {}
2625
}
@@ -62,6 +61,20 @@ impl Other {
6261
fn other(&self) {}
6362
}
6463

64+
struct Struct<T>{
65+
_phatom: PhantomData<T>
66+
}
67+
68+
impl<T> Default for Struct<T> {
69+
fn default() -> Self {
70+
Self{ _phatom: PhantomData }
71+
}
72+
}
73+
74+
impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord> Struct<T> {
75+
fn method(&self) {}
76+
}
77+
6578
fn main() {
6679
let point_f64 = Point{ x: 1_f64, y: 1_f64};
6780
let d = point_f64.distance();
@@ -87,4 +100,7 @@ fn main() {
87100
let a = vec![1, 2, 3];
88101
a.not_found();
89102
//~^ ERROR no method named `not_found` found for struct `Vec
103+
let s = Struct::<f64>::default();
104+
s.method();
105+
//~^ ERROR the method `method` exists for struct `Struct<f64>`, but its trait bounds were not satisfied
90106
}

0 commit comments

Comments
 (0)