From c64a2ed191f2a9137227b71d7005d0d93c376976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Thu, 15 Apr 2021 16:58:17 +0200 Subject: [PATCH 1/5] elision of generic argument in E0599 if the methode has not been found anywhere and sugetion of type with method when found. --- .../rustc_typeck/src/check/method/suggest.rs | 120 +++++++++++++++++- src/test/ui/auto-ref-slice-plus-ref.stderr | 4 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 12 +- .../no-method-suggested-traits.stderr | 24 ++-- src/test/ui/issues/issue-30123.stderr | 2 + src/test/ui/issues/issue-41880.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 90 +++++++++++++ ...ethod-not-found-generic-arg-elision.stderr | 75 +++++++++++ src/test/ui/object-pointer-types.stderr | 2 +- 11 files changed, 310 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/methods/method-not-found-generic-arg-elision.rs create mode 100644 src/test/ui/methods/method-not-found-generic-arg-elision.stderr diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 02fe8312c4c1f..54a1078383fcb 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -13,6 +13,7 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; +use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; @@ -383,6 +384,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } else { span = item_name.span; + + // issue #81576, elision of generic argument when no methode can be found in any implementation + 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() { + if let Some((path_string, _)) = ty_str.split_once('<') { + ty_str_reported = format!("{}<", path_string); + for (index, arg) in generics.iter().enumerate() { + let arg_replace = match arg.unpack() { + GenericArgKind::Lifetime(_) => "'_", + GenericArgKind::Type(_) + | GenericArgKind::Const(_) => "_", + }; + ty_str_reported = + format!("{}{}", ty_str_reported, arg_replace); + if index < generics.len() - 1 { + ty_str_reported = format!("{}, ", ty_str_reported); + } + } + ty_str_reported = format!("{}>", ty_str_reported); + } + } + } + } + let mut err = struct_span_err!( tcx.sess, span, @@ -391,7 +438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, actual.prefix_string(self.tcx), - ty_str, + ty_str_reported, ); if let Mode::MethodCall = mode { if let SelfSource::MethodCall(call) = source { @@ -449,6 +496,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut label_span_not_found = || { if unsatisfied_predicates.is_empty() { err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); + if let ty::Adt(ref adt, _) = rcvr_ty.kind() { + let mut inherent_impls_candidate = self + .tcx + .inherent_impls(adt.did) + .iter() + .copied() + .filter(|def_id| { + if let Some(assoc) = + self.associated_item(*def_id, item_name, Namespace::ValueNS) + { + // Check for both mode is the same so we avoid suggesting + // incorect associated item. + match (mode, assoc.fn_has_self_parameter) { + (Mode::MethodCall, true) => { + if let SelfSource::MethodCall(_) = source { + // We check that the suggest type is actually + // different from the received one + // So we avoid suggestion method with Box + // for instance + self.tcx.at(span).type_of(*def_id) != actual + && self.tcx.at(span).type_of(*def_id) + != rcvr_ty + } else { + false + } + } + (Mode::Path, false) => true, + _ => false, + } + } else { + false + } + }) + .collect::>(); + if inherent_impls_candidate.len() > 0 { + inherent_impls_candidate.sort(); + inherent_impls_candidate.dedup(); + // 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 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 + ); + } + err.note(&format!("{}.", note)); + } + } } else { err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds")); } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index eb8447ff0f3e7..be1b79e936d24 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec<_, _>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -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<{integer}>` in the current scope +error[E0599]: no method named `test` found for struct `Vec<_, _>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index 56d10d88d8b25..c01af6d7e2561 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -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<_, _>` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr index d6b399acb7330..2bf32975a6f45 100644 --- a/src/test/ui/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-18343.rs:6:28: 6:33]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index 051940bbe9660..f17a56eba2f7a 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -65,7 +65,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_closure.boxed_closure)(); | ^ ^ -error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj u32 + 'static)>>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 64ddcb81c0a9b..5c0f945140a01 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -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<&mut Box<&u32>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | 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 LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | 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 LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -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<&mut Box<&Foo>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | 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 LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | 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 LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` 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(); @@ -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<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` 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(); @@ -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<&mut Box<&Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -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<&mut Box<&Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | 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 LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | 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 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<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` 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(); @@ -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<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` 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(); diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index bc6731601f095..27b128372c0fe 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -3,6 +3,8 @@ error[E0599]: no function or associated item named `new_undirected` found for st | LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` + | + = note: The function or associated item was found for issue_30123_aux::Graph. error: aborting due to previous error diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index 09d5594f73f06..f9d11c47687b9 100644 --- a/src/test/ui/issues/issue-41880.stderr +++ b/src/test/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for struct `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate<_, _>` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs new file mode 100644 index 0000000000000..85ccb0bd0de2a --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -0,0 +1,90 @@ +// Test for issue 81576 +// Remove generic arguments if no method is found for all possible generic argument + + +struct Wrapper2<'a, T, const C: usize> { + x: &'a T, +} + +impl<'a, const C: usize> Wrapper2<'a, i8, C> { + fn method(&self) {} +} + +impl<'a, const C: usize> Wrapper2<'a, i16, C> { + fn method(&self) {} +} + +impl<'a, const C: usize> Wrapper2<'a, i32, C> { + fn method(&self) {} +} +struct Wrapper(T); + + + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +struct Point { + x: T, + y: T, +} + +impl Point { + fn distance(&self) -> f64 { + self.x.hypot(self.y) + } +} + +struct Other; + +impl Other { + fn other(&self) {} +} + +fn main() { + let point_f64 = Point{ x: 1_f64, y: 1_f64}; + let d = point_f64.distance(); + let point_i32 = Point{ x: 1_i32, y: 1_i32}; + let d = point_i32.distance(); + //~^ ERROR no method named `distance` found for struct `Point + let d = point_i32.other(); + //~^ ERROR no method named `other` found for struct `Point<_> + let v = vec![1_i32, 2, 3]; + v.iter().map(|x| x * x).extend(std::iter::once(100)); + //~^ ERROR no method named `extend` found for struct `Map<_, _> + let wrapper = Wrapper(true); + wrapper.method(); + //~^ ERROR no method named `method` found for struct `Wrapper + wrapper.other(); + //~^ ERROR no method named `other` found for struct `Wrapper<_> + let boolean = true; + let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; + wrapper.method(); + //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> + wrapper.other(); + //~^ ERROR no method named `other` found for struct `Wrapper2<'_, _, _> + let a = vec![1, 2, 3]; + a.not_found(); + //~^ ERROR no method named `not_found` found for struct `Vec<_, _> +} diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr new file mode 100644 index 0000000000000..80e111390c6ac --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -0,0 +1,75 @@ +error[E0599]: no method named `distance` found for struct `Point` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:69:23 + | +LL | struct Point { + | --------------- method `distance` not found for this +... +LL | let d = point_i32.distance(); + | ^^^^^^^^ method not found in `Point` + | + = note: The method was found for Point. + +error[E0599]: no method named `other` found for struct `Point<_>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:71:23 + | +LL | struct Point { + | --------------- method `other` not found for this +... +LL | let d = point_i32.other(); + | ^^^^^ method not found in `Point` + +error[E0599]: no method named `extend` found for struct `Map<_, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:74:29 + | +LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); + | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:74:18: 74:27]>` + +error[E0599]: no method named `method` found for struct `Wrapper` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:77:13 + | +LL | struct Wrapper(T); + | --------------------- method `method` not found for this +... +LL | wrapper.method(); + | ^^^^^^ method not found in `Wrapper` + | + = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. + +error[E0599]: no method named `other` found for struct `Wrapper<_>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:79:13 + | +LL | struct Wrapper(T); + | --------------------- method `other` not found for this +... +LL | wrapper.other(); + | ^^^^^ method not found in `Wrapper` + +error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:83:13 + | +LL | struct Wrapper2<'a, T, const C: usize> { + | -------------------------------------- method `method` not found for this +... +LL | wrapper.method(); + | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | + = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. + +error[E0599]: no method named `other` found for struct `Wrapper2<'_, _, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:85:13 + | +LL | struct Wrapper2<'a, T, const C: usize> { + | -------------------------------------- method `other` not found for this +... +LL | wrapper.other(); + | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + +error[E0599]: no method named `not_found` found for struct `Vec<_, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:88:7 + | +LL | a.not_found(); + | ^^^^^^^^^ method not found in `Vec<{integer}>` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index a477425edc81b..fb3462b2cabd4 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box<(dyn Foo + 'static)>` in the current scope +error[E0599]: no method named `managed` found for struct `Box<_, _>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); From 6efa14b3add08188c5322db8694a8cbbea7851e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Fri, 21 May 2021 14:01:38 +0200 Subject: [PATCH 2/5] remove generic argument insead of displaying "_" --- .../rustc_typeck/src/check/method/suggest.rs | 16 +------------ src/test/ui/auto-ref-slice-plus-ref.stderr | 4 ++-- src/test/ui/class-cast-to-trait.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 12 +++++----- .../no-method-suggested-traits.stderr | 24 +++++++++---------- src/test/ui/issues/issue-41880.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 10 ++++---- ...ethod-not-found-generic-arg-elision.stderr | 10 ++++---- src/test/ui/object-pointer-types.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 +- 11 files changed, 36 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 54a1078383fcb..f46d4205a6bd5 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -13,7 +13,6 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; @@ -411,20 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .sum(); if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { if let Some((path_string, _)) = ty_str.split_once('<') { - ty_str_reported = format!("{}<", path_string); - for (index, arg) in generics.iter().enumerate() { - let arg_replace = match arg.unpack() { - GenericArgKind::Lifetime(_) => "'_", - GenericArgKind::Type(_) - | GenericArgKind::Const(_) => "_", - }; - ty_str_reported = - format!("{}{}", ty_str_reported, arg_replace); - if index < generics.len() - 1 { - ty_str_reported = format!("{}, ", ty_str_reported); - } - } - ty_str_reported = format!("{}>", ty_str_reported); + ty_str_reported = path_string.to_string(); } } } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index be1b79e936d24..7203d3ed30e93 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -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` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -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` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index c01af6d7e2561..a1a3ead581265 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -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` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr index 2bf32975a6f45..fe6b12968c110 100644 --- a/src/test/ui/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index f17a56eba2f7a..0480958e99c05 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -65,7 +65,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_closure.boxed_closure)(); | ^ ^ -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 5c0f945140a01..5507406b0f502 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -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` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | 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 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` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | 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 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` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -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` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | 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 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` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | 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 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` 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(); @@ -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` 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(); @@ -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` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -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` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | 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 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` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | 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 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` 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(); @@ -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` 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(); diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index f9d11c47687b9..017dd831f712a 100644 --- a/src/test/ui/issues/issue-41880.stderr +++ b/src/test/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for struct `Iterate<_, _>` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 85ccb0bd0de2a..23f01fb861fdb 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -69,22 +69,22 @@ fn main() { let d = point_i32.distance(); //~^ ERROR no method named `distance` found for struct `Point let d = point_i32.other(); - //~^ ERROR no method named `other` found for struct `Point<_> + //~^ ERROR no method named `other` found for struct `Point let v = vec![1_i32, 2, 3]; v.iter().map(|x| x * x).extend(std::iter::once(100)); - //~^ ERROR no method named `extend` found for struct `Map<_, _> + //~^ ERROR no method named `extend` found for struct `Map let wrapper = Wrapper(true); wrapper.method(); //~^ ERROR no method named `method` found for struct `Wrapper wrapper.other(); - //~^ ERROR no method named `other` found for struct `Wrapper<_> + //~^ ERROR no method named `other` found for struct `Wrapper let boolean = true; let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; wrapper.method(); //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> wrapper.other(); - //~^ ERROR no method named `other` found for struct `Wrapper2<'_, _, _> + //~^ ERROR no method named `other` found for struct `Wrapper2 let a = vec![1, 2, 3]; a.not_found(); - //~^ ERROR no method named `not_found` found for struct `Vec<_, _> + //~^ ERROR no method named `not_found` found for struct `Vec } diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 80e111390c6ac..65dbabbc1430a 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -9,7 +9,7 @@ LL | let d = point_i32.distance(); | = note: The method was found for Point. -error[E0599]: no method named `other` found for struct `Point<_>` in the current scope +error[E0599]: no method named `other` found for struct `Point` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:71:23 | LL | struct Point { @@ -18,7 +18,7 @@ LL | struct Point { LL | let d = point_i32.other(); | ^^^^^ method not found in `Point` -error[E0599]: no method named `extend` found for struct `Map<_, _>` in the current scope +error[E0599]: no method named `extend` found for struct `Map` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:74:29 | LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); @@ -35,7 +35,7 @@ LL | wrapper.method(); | = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. -error[E0599]: no method named `other` found for struct `Wrapper<_>` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:79:13 | LL | struct Wrapper(T); @@ -55,7 +55,7 @@ LL | wrapper.method(); | = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. -error[E0599]: no method named `other` found for struct `Wrapper2<'_, _, _>` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:85:13 | LL | struct Wrapper2<'a, T, const C: usize> { @@ -64,7 +64,7 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.other(); | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` -error[E0599]: no method named `not_found` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `not_found` found for struct `Vec` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:88:7 | LL | a.not_found(); diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index fb3462b2cabd4..021899b3082cd 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box<_, _>` in the current scope +error[E0599]: no method named `managed` found for struct `Box` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr index 027d7a0e0e448..6b8ec47d98d81 100644 --- a/src/test/ui/resolve/issue-82865.stderr +++ b/src/test/ui/resolve/issue-82865.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: maybe a missing crate `x`? LL | use x::y::z; | ^ maybe a missing crate `x`? -error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope +error[E0599]: no function or associated item named `z` found for struct `Box` in the current scope --> $DIR/issue-82865.rs:8:10 | LL | Box::z From 5b802ed6c9fd23214f9201b8e05193c8a2240e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= <77335613+ABouttefeux@users.noreply.github.com> Date: Sat, 22 May 2021 08:59:04 +0200 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Esteban Kuber --- .../rustc_typeck/src/check/method/suggest.rs | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index f46d4205a6bd5..a36e0553c7add 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -384,7 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { span = item_name.span; - // issue #81576, elision of generic argument when no methode can be found in any implementation + // Don't show generic arguments when the method can't be found in any implementation (#81576). let mut ty_str_reported = ty_str.clone(); if let ty::Adt(_, ref generics) = actual.kind() { if generics.len() > 0 { @@ -493,22 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.associated_item(*def_id, item_name, Namespace::ValueNS) { // Check for both mode is the same so we avoid suggesting - // incorect associated item. - match (mode, assoc.fn_has_self_parameter) { - (Mode::MethodCall, true) => { - if let SelfSource::MethodCall(_) = source { - // We check that the suggest type is actually - // different from the received one - // So we avoid suggestion method with Box - // for instance - self.tcx.at(span).type_of(*def_id) != actual - && self.tcx.at(span).type_of(*def_id) - != rcvr_ty - } else { - false - } + // incorrect associated item. + match (mode, assoc.fn_has_self_parameter, source) { + (Mode::MethodCall, true, SelfSource::MethodCall(_)) => { + // We check that the suggest type is actually + // different from the received one + // So we avoid suggestion method with Box + // for instance + self.tcx.at(span).type_of(*def_id) != actual + && self.tcx.at(span).type_of(*def_id) + != rcvr_ty } - (Mode::Path, false) => true, + (Mode::Path, false, _) => true, _ => false, } } else { @@ -521,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inherent_impls_candidate.dedup(); // number of type to shows at most. const LIMIT: usize = 3; - let mut note = format!("The {item_kind} was found for"); + 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) { From 120691c590c4309fda31994931b9a561b4249c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Sat, 22 May 2021 12:03:37 +0200 Subject: [PATCH 4/5] change from review and show full type if it can be deref --- .../rustc_typeck/src/check/method/suggest.rs | 89 ++++++++----------- src/test/ui/auto-ref-slice-plus-ref.stderr | 4 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../no-method-suggested-traits.stderr | 24 ++--- src/test/ui/issues/issue-30123.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 20 ++++- ...ethod-not-found-generic-arg-elision.stderr | 46 +++++++--- src/test/ui/object-pointer-types.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 +- 9 files changed, 105 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index a36e0553c7add..109cd3e4bc86a 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -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(); } @@ -501,8 +504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // So we avoid suggestion method with Box // 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, @@ -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::>(); // 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 { diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index 7203d3ed30e93..eb8447ff0f3e7 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -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(); @@ -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(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index a1a3ead581265..56d10d88d8b25 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -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` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 5507406b0f502..64ddcb81c0a9b 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); @@ -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(); diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 27b128372c0fe..76a6b447ac100 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -4,7 +4,7 @@ error[E0599]: no function or associated item named `new_undirected` found for st LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` | - = note: The function or associated item was found for issue_30123_aux::Graph. + = note: the function or associated item was found for issue_30123_aux::Graph error: aborting due to previous error diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 23f01fb861fdb..3df928b5d804d 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -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, @@ -19,8 +20,6 @@ impl<'a, const C: usize> Wrapper2<'a, i32, C> { } struct Wrapper(T); - - impl Wrapper { fn method(&self) {} } @@ -62,6 +61,20 @@ impl Other { fn other(&self) {} } +struct Struct{ + _phatom: PhantomData +} + +impl Default for Struct { + fn default() -> Self { + Self{ _phatom: PhantomData } + } +} + +impl Struct { + fn method(&self) {} +} + fn main() { let point_f64 = Point{ x: 1_f64, y: 1_f64}; let d = point_f64.distance(); @@ -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::::default(); + s.method(); + //~^ ERROR the method `method` exists for struct `Struct`, but its trait bounds were not satisfied } diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 65dbabbc1430a..4a9cfb4fc804e 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `distance` found for struct `Point` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:69:23 + --> $DIR/method-not-found-generic-arg-elision.rs:82:23 | LL | struct Point { | --------------- method `distance` not found for this @@ -7,10 +7,10 @@ LL | struct Point { LL | let d = point_i32.distance(); | ^^^^^^^^ method not found in `Point` | - = note: The method was found for Point. + = note: the method was found for Point error[E0599]: no method named `other` found for struct `Point` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:71:23 + --> $DIR/method-not-found-generic-arg-elision.rs:84:23 | LL | struct Point { | --------------- method `other` not found for this @@ -19,13 +19,13 @@ LL | let d = point_i32.other(); | ^^^^^ method not found in `Point` error[E0599]: no method named `extend` found for struct `Map` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:74:29 + --> $DIR/method-not-found-generic-arg-elision.rs:87:29 | LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); - | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:74:18: 74:27]>` + | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:87:18: 87:27]>` error[E0599]: no method named `method` found for struct `Wrapper` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:77:13 + --> $DIR/method-not-found-generic-arg-elision.rs:90:13 | LL | struct Wrapper(T); | --------------------- method `method` not found for this @@ -33,10 +33,13 @@ LL | struct Wrapper(T); LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | - = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. + = note: the method was found for Wrapper + = note: the method was found for Wrapper + = note: the method was found for Wrapper + = note: the method was found for 3 more types error[E0599]: no method named `other` found for struct `Wrapper` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:79:13 + --> $DIR/method-not-found-generic-arg-elision.rs:92:13 | LL | struct Wrapper(T); | --------------------- method `other` not found for this @@ -45,7 +48,7 @@ LL | wrapper.other(); | ^^^^^ method not found in `Wrapper` error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:83:13 + --> $DIR/method-not-found-generic-arg-elision.rs:96:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `method` not found for this @@ -53,10 +56,12 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` | - = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. + = note: the method was found for Wrapper2<'a, i8, C> + = note: the method was found for Wrapper2<'a, i16, C> + = note: the method was found for Wrapper2<'a, i32, C> error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:85:13 + --> $DIR/method-not-found-generic-arg-elision.rs:98:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `other` not found for this @@ -64,12 +69,25 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.other(); | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` -error[E0599]: no method named `not_found` found for struct `Vec` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:88:7 +error[E0599]: no method named `not_found` found for struct `Vec<{integer}>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:101:7 | LL | a.not_found(); | ^^^^^^^^^ method not found in `Vec<{integer}>` -error: aborting due to 8 previous errors +error[E0599]: the method `method` exists for struct `Struct`, but its trait bounds were not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:104:7 + | +LL | struct Struct{ + | ---------------- method `method` not found for this +... +LL | s.method(); + | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `f64: Eq` + `f64: Ord` + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index 021899b3082cd..a477425edc81b 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box` in the current scope +error[E0599]: no method named `managed` found for struct `Box<(dyn Foo + 'static)>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr index 6b8ec47d98d81..027d7a0e0e448 100644 --- a/src/test/ui/resolve/issue-82865.stderr +++ b/src/test/ui/resolve/issue-82865.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: maybe a missing crate `x`? LL | use x::y::z; | ^ maybe a missing crate `x`? -error[E0599]: no function or associated item named `z` found for struct `Box` in the current scope +error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope --> $DIR/issue-82865.rs:8:10 | LL | Box::z From 5d8e6ea7b9e668578917940d2ab1ba1a51b291b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Tue, 25 May 2021 16:55:30 +0200 Subject: [PATCH 5/5] show list of candidates --- .../rustc_typeck/src/check/method/suggest.rs | 34 ++++++++++++------- src/test/ui/issues/issue-30123.stderr | 3 +- ...ethod-not-found-generic-arg-elision.stderr | 20 ++++++----- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 109cd3e4bc86a..569e871922732 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -517,21 +517,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if inherent_impls_candidate.len() > 0 { inherent_impls_candidate.sort(); inherent_impls_candidate.dedup(); + + // number of type to shows at most. + let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 }; let type_candidates = inherent_impls_candidate .iter() - .map(|impl_item| self.tcx.at(span).type_of(*impl_item)) - .collect::>(); - // number of type to shows at most. - 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)); - } - if type_candidates.len() > limit { - err.note(&format!( - "the {item_kind} was found for {} more types", - type_candidates.len() - limit - )); - } + .take(limit) + .map(|impl_item| { + format!("- `{}`", self.tcx.at(span).type_of(*impl_item)) + }) + .collect::>() + .join("\n"); + let additional_types = if inherent_impls_candidate.len() > limit { + format!( + "\nand {} more types", + inherent_impls_candidate.len() - limit + ) + } else { + "".to_string() + }; + err.note(&format!( + "the {item_kind} was found for\n{}{}", + type_candidates, additional_types + )); } } } else { diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 76a6b447ac100..e9d934332f171 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -4,7 +4,8 @@ error[E0599]: no function or associated item named `new_undirected` found for st LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` | - = note: the function or associated item was found for issue_30123_aux::Graph + = note: the function or associated item was found for + - `issue_30123_aux::Graph` error: aborting due to previous error diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 4a9cfb4fc804e..1671e5e5e64c8 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -7,7 +7,8 @@ LL | struct Point { LL | let d = point_i32.distance(); | ^^^^^^^^ method not found in `Point` | - = note: the method was found for Point + = note: the method was found for + - `Point` error[E0599]: no method named `other` found for struct `Point` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:84:23 @@ -33,10 +34,12 @@ LL | struct Wrapper(T); LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | - = note: the method was found for Wrapper - = note: the method was found for Wrapper - = note: the method was found for Wrapper - = note: the method was found for 3 more types + = note: the method was found for + - `Wrapper` + - `Wrapper` + - `Wrapper` + - `Wrapper` + and 2 more types error[E0599]: no method named `other` found for struct `Wrapper` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:92:13 @@ -56,9 +59,10 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` | - = note: the method was found for Wrapper2<'a, i8, C> - = note: the method was found for Wrapper2<'a, i16, C> - = note: the method was found for Wrapper2<'a, i32, C> + = note: the method was found for + - `Wrapper2<'a, i8, C>` + - `Wrapper2<'a, i16, C>` + - `Wrapper2<'a, i32, C>` error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:98:13