From 87de9bd1088ec0f1a2e8893a517cde2005a546a0 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sun, 18 Sep 2022 18:45:36 +0100 Subject: [PATCH 1/9] Prevent auto-application of associated functions with placeholders --- .../rustc_hir_typeck/src/method/suggest.rs | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 04ecd2757b427..613acd3d705c5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -18,7 +18,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, DefIdTree, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; @@ -392,28 +392,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { custom_span_label = true; } if static_candidates.len() == 1 { - let ty_str = - if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { - // When the "method" is resolved through dereferencing, we really want the - // original type that has the associated function for accurate suggestions. - // (#61411) - let ty = tcx.at(span).type_of(*impl_did); - match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) { - (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => { - // Use `actual` as it will have more `substs` filled in. - self.ty_to_value_string(actual.peel_refs()) - } - _ => self.ty_to_value_string(ty.peel_refs()), + let (ty_str, placeholders) = if let Some(CandidateSource::Impl(impl_did)) = + static_candidates.get(0) + { + // When the "method" is resolved through dereferencing, we really want the + // original type that has the associated function for accurate suggestions. + // (#61411) + let ty = tcx.at(span).type_of(*impl_did); + match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) { + (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => { + // If there are any inferred arguments, (`{integer}`), we shouldn't mark + // this as machine-applicable. + let placeholders = substs + .iter() + .filter_map(|arg| { + if let GenericArgKind::Type(ty) = arg.unpack() { + Some(ty) + } else { + None + } + }) + .any(|ty| matches!(ty.kind(), ty::Infer(_))); + // Use `actual` as it will have more `substs` filled in. + (self.ty_to_value_string(actual.peel_refs()), placeholders) } - } else { - self.ty_to_value_string(actual.peel_refs()) - }; + _ => (self.ty_to_value_string(ty.peel_refs()), true), + } + } else { + (self.ty_to_value_string(actual.peel_refs()), true) + }; + let applicability = match placeholders { + true => Applicability::HasPlaceholders, + false => Applicability::MachineApplicable, + }; if let SelfSource::MethodCall(expr) = source { err.span_suggestion( expr.span.to(span), "use associated function syntax instead", format!("{}::{}", ty_str, item_name), - Applicability::MachineApplicable, + applicability, ); } else { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); From a3b5ca7b6d8a1aa42544f5bb1b854f357678e612 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 19 Sep 2022 00:53:41 +0100 Subject: [PATCH 2/9] Allow inferring generic arguments for associated methods --- .../rustc_hir_typeck/src/method/suggest.rs | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 613acd3d705c5..85c003ff605c3 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -14,7 +14,11 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, Node, QPath}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::{ + type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, + RegionVariableOrigin, +}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; @@ -392,7 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { custom_span_label = true; } if static_candidates.len() == 1 { - let (ty_str, placeholders) = if let Some(CandidateSource::Impl(impl_did)) = + let ty_str = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { // When the "method" is resolved through dereferencing, we really want the @@ -401,36 +405,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = tcx.at(span).type_of(*impl_did); match (&ty.peel_refs().kind(), &actual.peel_refs().kind()) { (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => { - // If there are any inferred arguments, (`{integer}`), we shouldn't mark - // this as machine-applicable. - let placeholders = substs - .iter() - .filter_map(|arg| { - if let GenericArgKind::Type(ty) = arg.unpack() { - Some(ty) - } else { - None - } + // If there are any inferred arguments, (`{integer}`), we should replace + // them with underscores to allow the compiler to infer them + let substs = substs + .into_iter() + .filter(|arg| !arg.is_suggestable(tcx, true)) + .map(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => self + .next_region_var(RegionVariableOrigin::MiscVariable( + rustc_span::DUMMY_SP, + )) + .into(), + GenericArgKind::Type(_) => self + .next_ty_var(TypeVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: TypeVariableOriginKind::MiscVariable, + }) + .into(), + GenericArgKind::Const(arg) => self + .next_const_var( + arg.ty(), + ConstVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: ConstVariableOriginKind::MiscVariable, + }, + ) + .into(), }) - .any(|ty| matches!(ty.kind(), ty::Infer(_))); - // Use `actual` as it will have more `substs` filled in. - (self.ty_to_value_string(actual.peel_refs()), placeholders) + .collect::>(); + format!( + "{}", + ty::Instance::new(def_actual.did(), tcx.intern_substs(&substs)) + ) } - _ => (self.ty_to_value_string(ty.peel_refs()), true), + _ => self.ty_to_value_string(ty.peel_refs()), } } else { - (self.ty_to_value_string(actual.peel_refs()), true) - }; - let applicability = match placeholders { - true => Applicability::HasPlaceholders, - false => Applicability::MachineApplicable, + self.ty_to_value_string(actual.peel_refs()) }; if let SelfSource::MethodCall(expr) = source { err.span_suggestion( expr.span.to(span), "use associated function syntax instead", format!("{}::{}", ty_str, item_name), - applicability, + Applicability::MachineApplicable, ); } else { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); From d1ec75da7cc466bb4fa61896489e5709ac12c0f5 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 19 Sep 2022 01:54:11 +0100 Subject: [PATCH 3/9] Update UI test --- .../ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 3fb418b1c0aac..199454ee228e8 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -8,7 +8,7 @@ LL | x.default_hello(); | --^^^^^^^^^^^^^ | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::default_hello` + | help: use associated function syntax instead: `GenericAssocMethod::default_hello` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` From 02025b54eade665d32ab9b507bb5a0376d639785 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 23 Sep 2022 12:40:20 +0100 Subject: [PATCH 4/9] Use `FmtPrinter` instead of creating `Instance` --- .../rustc_hir_typeck/src/method/suggest.rs | 63 ++++++----- compiler/rustc_middle/src/ty/print/pretty.rs | 6 + .../suggest-assoc-fn-call-with-turbofish.rs | 17 ++- ...uggest-assoc-fn-call-with-turbofish.stderr | 103 +++++++++++++++++- 4 files changed, 156 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 85c003ff605c3..52099102dc20a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -22,7 +22,9 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{self, DefIdTree, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{ + self, DefIdTree, GenericArg, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable, +}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; @@ -283,7 +285,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { return None; } - span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). @@ -407,35 +408,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (ty::Adt(def, _), ty::Adt(def_actual, substs)) if def == def_actual => { // If there are any inferred arguments, (`{integer}`), we should replace // them with underscores to allow the compiler to infer them - let substs = substs + let infer_substs: Vec> = substs .into_iter() - .filter(|arg| !arg.is_suggestable(tcx, true)) - .map(|arg| match arg.unpack() { - GenericArgKind::Lifetime(_) => self - .next_region_var(RegionVariableOrigin::MiscVariable( - rustc_span::DUMMY_SP, - )) - .into(), - GenericArgKind::Type(_) => self - .next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }) - .into(), - GenericArgKind::Const(arg) => self - .next_const_var( - arg.ty(), - ConstVariableOrigin { + .map(|arg| { + if !arg.is_suggestable(tcx, true) { + match arg.unpack() { + GenericArgKind::Lifetime(_) => self + .next_region_var(RegionVariableOrigin::MiscVariable( + rustc_span::DUMMY_SP, + )) + .into(), + GenericArgKind::Type(_) => self + .next_ty_var(TypeVariableOrigin { span: rustc_span::DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, - }, - ) - .into(), + kind: TypeVariableOriginKind::MiscVariable, + }) + .into(), + GenericArgKind::Const(arg) => self + .next_const_var( + arg.ty(), + ConstVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: ConstVariableOriginKind::MiscVariable, + }, + ) + .into(), + } + } else { + arg + } }) .collect::>(); - format!( - "{}", - ty::Instance::new(def_actual.did(), tcx.intern_substs(&substs)) + + tcx.value_path_str_with_substs( + def_actual.did(), + tcx.intern_substs(&infer_substs), ) } _ => self.ty_to_value_string(ty.peel_refs()), @@ -1861,7 +1868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Print out the type for use in value namespace. fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String { match ty.kind() { - ty::Adt(def, substs) => format!("{}", ty::Instance::new(def.did(), substs)), + ty::Adt(def, substs) => self.tcx.def_path_str_with_substs(def.did(), substs), _ => self.ty_to_string(ty), } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fab85c39d2535..a0efff14f1c8b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1659,6 +1659,12 @@ impl<'t> TyCtxt<'t> { debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_def_path(def_id, substs).unwrap().into_buffer() } + + pub fn value_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + let ns = guess_def_namespace(self, def_id); + debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns); + FmtPrinter::new(self, ns).print_value_path(def_id, substs).unwrap().into_buffer() + } } impl fmt::Write for FmtPrinter<'_, '_> { diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index 2a829db538390..213d1c72f9ae8 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -2,10 +2,25 @@ struct GenericAssocMethod(T); impl GenericAssocMethod { fn default_hello() {} + fn self_ty_hello(_: T) {} + fn self_ty_ref_hello(_: &T) {} } fn main() { - let x = GenericAssocMethod(33i32); + // Test for inferred types + let x = GenericAssocMethod(33); x.default_hello(); //~^ ERROR no method named `default_hello` found + x.self_ty_ref_hello(); + //~^ ERROR no method named `self_ty_ref_hello` found + x.self_ty_hello(); + //~^ ERROR no method named `self_ty_hello` found + // Test for known types + let y = GenericAssocMethod(33i32); + y.default_hello(); + //~^ ERROR no method named `default_hello` found + y.self_ty_ref_hello(); + //~^ ERROR no method named `self_ty_ref_hello` found + y.self_ty_hello(); + //~^ ERROR no method named `self_ty_hello` found } diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 199454ee228e8..c6d9122228acc 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,5 +1,5 @@ -error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7 +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:12:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct @@ -8,7 +8,7 @@ LL | x.default_hello(); | --^^^^^^^^^^^^^ | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::default_hello` + | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -17,6 +17,101 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_ref_hello` not found for this struct +... +LL | x.self_ty_ref_hello(); + | --^^^^^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + | +LL | fn self_ty_ref_hello(_: &T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_hello` not found for this struct +... +LL | x.self_ty_hello(); + | --^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + | +LL | fn self_ty_hello(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `default_hello` not found for this struct +... +LL | y.default_hello(); + | --^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::::default_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 + | +LL | fn default_hello() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_ref_hello` not found for this struct +... +LL | y.self_ty_ref_hello(); + | --^^^^^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + | +LL | fn self_ty_ref_hello(_: &T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `self_ty_hello` not found for this struct +... +LL | y.self_ty_hello(); + | --^^^^^^^^^^^^^ + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + | +LL | fn self_ty_hello(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0599`. From da588e6df7afb80e210e62dea7e43c5687f088a5 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 23 Sep 2022 17:09:32 +0100 Subject: [PATCH 5/9] Attempt to fix arguments of associated functions --- .../rustc_hir_typeck/src/method/suggest.rs | 62 +++++++++++++-- src/test/ui/issues/issue-3707.stderr | 4 +- ...n-call-with-turbofish-through-deref.stderr | 4 +- ...suggest-assoc-fn-call-with-turbofish.fixed | 29 +++++++ .../suggest-assoc-fn-call-with-turbofish.rs | 11 ++- ...uggest-assoc-fn-call-with-turbofish.stderr | 77 +++++++------------ 6 files changed, 126 insertions(+), 61 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 52099102dc20a..7ec3d45366061 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ExprKind, Node, QPath}; +use rustc_hir::{Expr, ExprKind, Node, QPath}; use rustc_infer::infer::{ type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, RegionVariableOrigin, @@ -397,6 +397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { custom_span_label = true; } if static_candidates.len() == 1 { + let mut has_unsuggestable_args = false; let ty_str = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) { @@ -412,6 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .map(|arg| { if !arg.is_suggestable(tcx, true) { + has_unsuggestable_args = true; match arg.unpack() { GenericArgKind::Lifetime(_) => self .next_region_var(RegionVariableOrigin::MiscVariable( @@ -450,12 +452,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { self.ty_to_value_string(actual.peel_refs()) }; - if let SelfSource::MethodCall(expr) = source { + if let SelfSource::MethodCall(_) = source { + let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) && + let Some(assoc) = self.associated_value(*impl_did, item_name) { + let sig = self.tcx.fn_sig(assoc.def_id); + if let Some(first) = sig.inputs().skip_binder().get(0) { + if first.peel_refs() == rcvr_ty.peel_refs() { + None + } else { + Some(if first.is_region_ptr() { + if first.is_mutable_ptr() { "&mut " } else { "&" } + } else { + "" + }) + } + } else { + None + } + } else { + None + }; + let mut applicability = Applicability::MachineApplicable; + let args = if let Some((receiver, args)) = args { + // The first arg is the same kind as the receiver + let it = if first_arg.is_some() { + Box::new(std::iter::once(receiver).chain(args.iter())) + as Box>> + } else { + // There is no `Self` kind to infer the arguments from + if has_unsuggestable_args { + applicability = Applicability::HasPlaceholders; + } + Box::new(args.iter()) as _ + }; + format!( + "({}{})", + first_arg.unwrap_or(""), + it.map(|arg| tcx + .sess + .source_map() + .span_to_snippet(arg.span) + .unwrap_or_else(|_| { + applicability = Applicability::HasPlaceholders; + "_".to_owned() + })) + .collect::>() + .join(", "), + ) + } else { + applicability = Applicability::HasPlaceholders; + "(...)".to_owned() + }; err.span_suggestion( - expr.span.to(span), + sugg_span, "use associated function syntax instead", - format!("{}::{}", ty_str, item_name), - Applicability::MachineApplicable, + format!("{}::{}{}", ty_str, item_name, args), + applicability, ); } else { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); diff --git a/src/test/ui/issues/issue-3707.stderr b/src/test/ui/issues/issue-3707.stderr index 6ca2deee377a3..07c8101cbc68b 100644 --- a/src/test/ui/issues/issue-3707.stderr +++ b/src/test/ui/issues/issue-3707.stderr @@ -2,10 +2,10 @@ error[E0599]: no method named `boom` found for reference `&Obj` in the current s --> $DIR/issue-3707.rs:10:14 | LL | self.boom(); - | -----^^^^ + | -----^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `Obj::boom` + | help: use associated function syntax instead: `Obj::boom()` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Obj` diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr index 996d57731187d..7c9f0b6c212e1 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr @@ -2,10 +2,10 @@ error[E0599]: no method named `hello` found for struct `RefMut<'_, HasAssocMetho --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11 | LL | state.hello(); - | ------^^^^^ + | ------^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `HasAssocMethod::hello` + | help: use associated function syntax instead: `HasAssocMethod::hello()` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `HasAssocMethod` diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed new file mode 100644 index 0000000000000..0398c510feac3 --- /dev/null +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed @@ -0,0 +1,29 @@ +// run-rustfix + +struct GenericAssocMethod(T); + +impl GenericAssocMethod { + fn default_hello() {} + fn self_ty_hello(_: Self) {} + fn self_ty_ref_hello(_: &Self) {} +} + +fn main() { + // Test for inferred types + let x = GenericAssocMethod(33); + // This particular case is unfixable without more information by the user, + // but `cargo fix --broken-code` reports a bug if + // x.default_hello(); + GenericAssocMethod::<_>::self_ty_ref_hello(&x); + //~^ ERROR no method named `self_ty_ref_hello` found + GenericAssocMethod::<_>::self_ty_hello(x); + //~^ ERROR no method named `self_ty_hello` found + // Test for known types + let y = GenericAssocMethod(33i32); + GenericAssocMethod::::default_hello(); + //~^ ERROR no method named `default_hello` found + GenericAssocMethod::::self_ty_ref_hello(&y); + //~^ ERROR no method named `self_ty_ref_hello` found + GenericAssocMethod::::self_ty_hello(y); + //~^ ERROR no method named `self_ty_hello` found +} diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index 213d1c72f9ae8..8bafc83bdd0b3 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -1,16 +1,19 @@ +// run-rustfix + struct GenericAssocMethod(T); impl GenericAssocMethod { fn default_hello() {} - fn self_ty_hello(_: T) {} - fn self_ty_ref_hello(_: &T) {} + fn self_ty_hello(_: Self) {} + fn self_ty_ref_hello(_: &Self) {} } fn main() { // Test for inferred types let x = GenericAssocMethod(33); - x.default_hello(); - //~^ ERROR no method named `default_hello` found + // This particular case is unfixable without more information by the user, + // but `cargo fix --broken-code` reports a bug if + // x.default_hello(); x.self_ty_ref_hello(); //~^ ERROR no method named `self_ty_ref_hello` found x.self_ty_hello(); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index c6d9122228acc..e2f2d46b9e8b8 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,117 +1,98 @@ -error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:12:7 - | -LL | struct GenericAssocMethod(T); - | ---------------------------- method `default_hello` not found for this struct -... -LL | x.default_hello(); - | --^^^^^^^^^^^^^ - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello` - | - = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 - | -LL | fn default_hello() {} - | ^^^^^^^^^^^^^^^^^^ - error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:17:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | x.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello` + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello(&x)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:8:5 | -LL | fn self_ty_ref_hello(_: &T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_ref_hello(_: &Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:19:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | x.self_ty_hello(); - | --^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello` + | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello(x)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:7:5 | -LL | fn self_ty_hello(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_hello(_: Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:23:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct ... LL | y.default_hello(); - | --^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::default_hello` + | help: use associated function syntax instead: `GenericAssocMethod::::default_hello()` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 | LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:25:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | y.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello` + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello(&y)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:8:5 | -LL | fn self_ty_ref_hello(_: &T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_ref_hello(_: &Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:27:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | y.self_ty_hello(); - | --^^^^^^^^^^^^^ + | --^^^^^^^^^^^^^-- | | | | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello` + | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello(y)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:5:5 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:7:5 | -LL | fn self_ty_hello(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn self_ty_hello(_: Self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0599`. From cef19b80f7145f99d2f91818c687781a0dc4004d Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 26 Sep 2022 00:33:08 +0100 Subject: [PATCH 6/9] Split non-fixable case to different test --- ...ssoc-fn-call-with-turbofish-placeholder.rs | 11 ++++++++++ ...-fn-call-with-turbofish-placeholder.stderr | 22 +++++++++++++++++++ ...suggest-assoc-fn-call-with-turbofish.fixed | 3 --- .../suggest-assoc-fn-call-with-turbofish.rs | 3 --- ...uggest-assoc-fn-call-with-turbofish.stderr | 10 ++++----- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs create mode 100644 src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs new file mode 100644 index 0000000000000..a39b8711dd874 --- /dev/null +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs @@ -0,0 +1,11 @@ +struct GenericAssocMethod(T); + +impl GenericAssocMethod { + fn default_hello() {} +} + +fn main() { + let x = GenericAssocMethod(33); + x.default_hello(); + //~^ ERROR no method named `default_hello` found +} diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr new file mode 100644 index 0000000000000..c247e73b39cb6 --- /dev/null +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr @@ -0,0 +1,22 @@ +error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope + --> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:9:7 + | +LL | struct GenericAssocMethod(T); + | ---------------------------- method `default_hello` not found for this struct +... +LL | x.default_hello(); + | --^^^^^^^^^^^^^-- + | | | + | | this is an associated function, not a method + | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello()` + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `GenericAssocMethod` + --> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:4:5 + | +LL | fn default_hello() {} + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed index 0398c510feac3..02dd0715c8011 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed @@ -11,9 +11,6 @@ impl GenericAssocMethod { fn main() { // Test for inferred types let x = GenericAssocMethod(33); - // This particular case is unfixable without more information by the user, - // but `cargo fix --broken-code` reports a bug if - // x.default_hello(); GenericAssocMethod::<_>::self_ty_ref_hello(&x); //~^ ERROR no method named `self_ty_ref_hello` found GenericAssocMethod::<_>::self_ty_hello(x); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs index 8bafc83bdd0b3..1d0ca8e780abf 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -11,9 +11,6 @@ impl GenericAssocMethod { fn main() { // Test for inferred types let x = GenericAssocMethod(33); - // This particular case is unfixable without more information by the user, - // but `cargo fix --broken-code` reports a bug if - // x.default_hello(); x.self_ty_ref_hello(); //~^ ERROR no method named `self_ty_ref_hello` found x.self_ty_hello(); diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index e2f2d46b9e8b8..92b03fc77142c 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:17:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct @@ -18,7 +18,7 @@ LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:19:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct @@ -37,7 +37,7 @@ LL | fn self_ty_hello(_: Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:23:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct @@ -56,7 +56,7 @@ LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:25:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct @@ -75,7 +75,7 @@ LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope - --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:27:7 + --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 | LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct From 2553a9590c5980a0013789209f928ec065e44ca6 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 26 Sep 2022 00:43:52 +0100 Subject: [PATCH 7/9] Replace boxed iterator with vec collect --- .../rustc_hir_typeck/src/method/suggest.rs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7ec3d45366061..237701b5e6fea 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{Expr, ExprKind, Node, QPath}; +use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::{ type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, RegionVariableOrigin, @@ -475,29 +475,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut applicability = Applicability::MachineApplicable; let args = if let Some((receiver, args)) = args { // The first arg is the same kind as the receiver - let it = if first_arg.is_some() { - Box::new(std::iter::once(receiver).chain(args.iter())) - as Box>> + let explicit_args = if first_arg.is_some() { + std::iter::once(receiver).chain(args.iter()).collect::>() } else { // There is no `Self` kind to infer the arguments from if has_unsuggestable_args { applicability = Applicability::HasPlaceholders; } - Box::new(args.iter()) as _ + args.iter().collect() }; format!( "({}{})", first_arg.unwrap_or(""), - it.map(|arg| tcx - .sess - .source_map() - .span_to_snippet(arg.span) - .unwrap_or_else(|_| { - applicability = Applicability::HasPlaceholders; - "_".to_owned() - })) - .collect::>() - .join(", "), + explicit_args + .iter() + .map(|arg| tcx + .sess + .source_map() + .span_to_snippet(arg.span) + .unwrap_or_else(|_| { + applicability = Applicability::HasPlaceholders; + "_".to_owned() + })) + .collect::>() + .join(", "), ) } else { applicability = Applicability::HasPlaceholders; From 7e38c8a750de95f66a6792c0cfe6fb25b8c5260a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 10 Oct 2022 15:08:40 +0100 Subject: [PATCH 8/9] Update UI test --- src/test/ui/suggestions/inner_type2.rs | 2 +- src/test/ui/suggestions/inner_type2.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/suggestions/inner_type2.rs b/src/test/ui/suggestions/inner_type2.rs index c56ea7c030d8e..fac68c053eb4f 100644 --- a/src/test/ui/suggestions/inner_type2.rs +++ b/src/test/ui/suggestions/inner_type2.rs @@ -22,5 +22,5 @@ fn main() { let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 }); item.method(); //~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599] - //~| HELP if this `MaybeUninit::>` has been initialized, use one of the `assume_init` methods to access the inner value + //~| HELP if this `MaybeUninit>` has been initialized, use one of the `assume_init` methods to access the inner value } diff --git a/src/test/ui/suggestions/inner_type2.stderr b/src/test/ui/suggestions/inner_type2.stderr index eddfd9d63409d..984366123c827 100644 --- a/src/test/ui/suggestions/inner_type2.stderr +++ b/src/test/ui/suggestions/inner_type2.stderr @@ -17,7 +17,7 @@ error[E0599]: no method named `method` found for union `MaybeUninit` in the curr LL | item.method(); | ^^^^^^ method not found in `MaybeUninit>` | - = help: if this `MaybeUninit::>` has been initialized, use one of the `assume_init` methods to access the inner value + = help: if this `MaybeUninit>` has been initialized, use one of the `assume_init` methods to access the inner value note: the method `method` exists on the type `Struct` --> $DIR/inner_type2.rs:6:5 | From 7df4b0b66252748108b5d7edee27ee5776222f64 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 5 Nov 2022 23:06:58 +0000 Subject: [PATCH 9/9] Rebase and update test --- compiler/rustc_hir_typeck/src/method/suggest.rs | 4 ++-- src/test/ui/suggestions/issue-102354.stderr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 237701b5e6fea..22007d5eb6834 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -399,7 +399,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if static_candidates.len() == 1 { let mut has_unsuggestable_args = false; let ty_str = if let Some(CandidateSource::Impl(impl_did)) = - static_candidates.get(0) + static_candidates.get(0) { // When the "method" is resolved through dereferencing, we really want the // original type that has the associated function for accurate suggestions. @@ -453,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.ty_to_value_string(actual.peel_refs()) }; if let SelfSource::MethodCall(_) = source { - let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_sources.get(0) && + let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) && let Some(assoc) = self.associated_value(*impl_did, item_name) { let sig = self.tcx.fn_sig(assoc.def_id); if let Some(first) = sig.inputs().skip_binder().get(0) { diff --git a/src/test/ui/suggestions/issue-102354.stderr b/src/test/ui/suggestions/issue-102354.stderr index 4f76c5f2e75b2..b17c4dc5dfb50 100644 --- a/src/test/ui/suggestions/issue-102354.stderr +++ b/src/test/ui/suggestions/issue-102354.stderr @@ -13,7 +13,7 @@ LL | fn func() {} help: use associated function syntax instead | LL | i32::func(); - | ~~~~~~~~~ + | ~~~~~~~~~~~ help: disambiguate the associated function for the candidate | LL | ::func(x);