diff options
| author | Young-Flash <dongyang@apache.org> | 2024-01-14 18:44:55 +0800 |
|---|---|---|
| committer | Young-Flash <dongyang@apache.org> | 2024-01-14 18:44:55 +0800 |
| commit | f1b508cff7c735286fbf8204e4ea43503d5a3663 (patch) | |
| tree | d8f7c411196541bbfa68246d1f879b6b7455801d | |
| parent | 139fb2214675fed8143a12f6287a3a1e6e2e866d (diff) | |
| download | rust-f1b508cff7c735286fbf8204e4ea43503d5a3663.tar.gz rust-f1b508cff7c735286fbf8204e4ea43503d5a3663.zip | |
fix: correct suggestion arg for impl trait
| -rw-r--r-- | compiler/rustc_hir_typeck/src/method/suggest.rs | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 47fdd64796e..bbebc475279 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1587,23 +1587,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.ty_to_value_string(rcvr_ty.peel_refs()) }; if let SelfSource::MethodCall(_) = source { - let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0) - && let Some(assoc) = self.associated_value(*impl_did, item_name) - && assoc.kind == ty::AssocKind::Fn - { + let first_arg = static_candidates.get(0).and_then(|candidate_source| { + let (assoc_did, impl_ty) = match candidate_source { + CandidateSource::Impl(impl_did) => { + (*impl_did, self.tcx.type_of(*impl_did).instantiate_identity()) + } + CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty), + }; + + let assoc = self.associated_value(assoc_did, item_name)?; + if assoc.kind != ty::AssocKind::Fn { + return None; + } + + // for CandidateSource::Impl, `Self` will be instantiated to a concrete type + // but for CandidateSource::Trait, `Self` is still `Self` let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity(); sig.inputs().skip_binder().get(0).and_then(|first| { - let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity(); // if the type of first arg is the same as the current impl type, we should take the first arg into assoc function - if first.peel_refs() == impl_ty { + let first_ty = first.peel_refs(); + if first_ty == impl_ty || first_ty == self.tcx.types.self_param { Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str())) } else { None } }) - } else { - None - }; + }); + let mut applicability = Applicability::MachineApplicable; let args = if let SelfSource::MethodCall(receiver) = source && let Some(args) = args |
