X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_hir_typeck%2Fsrc%2Fmethod%2Fmod.rs;h=146d5e60c2f388c2bfd7257c66af6b91414ed12f;hb=445e3841da22aa4c2ca5b206c2f3dea7423f9a9b;hp=d276bcdb81e3e68e726397420be8d55b0b77d5c5;hpb=70f1566b2bbdf92dffb40fa122986a58b2c4ee86;p=rust.git diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index d276bcdb81e..146d5e60c2f 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -97,10 +97,12 @@ pub fn method_exists( self_ty: Ty<'tcx>, call_expr_id: hir::HirId, allow_private: bool, + return_type: Option>, ) -> bool { match self.probe_for_name( probe::Mode::MethodCall, method_name, + return_type, IsSuggestion(false), self_ty, call_expr_id, @@ -118,7 +120,7 @@ pub fn method_exists( Err(Ambiguity(..)) => true, Err(PrivateMatch(..)) => allow_private, Err(IllegalSizedBound { .. }) => true, - Err(BadReturnType) => bug!("no return type expectations but got BadReturnType"), + Err(BadReturnType) => false, } } @@ -130,17 +132,16 @@ pub(crate) fn suggest_method_call( msg: &str, method_name: Ident, self_ty: Ty<'tcx>, - call_expr: &hir::Expr<'_>, + call_expr: &hir::Expr<'tcx>, span: Option, ) { let params = self - .probe_for_name( - probe::Mode::MethodCall, + .lookup_probe_for_diagnostic( method_name, - IsSuggestion(true), self_ty, - call_expr.hir_id, + call_expr, ProbeScope::TraitsInScope, + None, ) .map(|pick| { let sig = self.tcx.fn_sig(pick.item.def_id); @@ -221,25 +222,30 @@ pub fn lookup_method( } // We probe again, taking all traits into account (not only those in scope). - let candidates = - match self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::AllTraits) { - // If we find a different result the caller probably forgot to import a trait. - Ok(ref new_pick) if pick.differs_from(new_pick) => { - vec![new_pick.item.container_id(self.tcx)] - } - Err(Ambiguity(ref sources)) => sources - .iter() - .filter_map(|source| { - match *source { - // Note: this cannot come from an inherent impl, - // because the first probing succeeded. - CandidateSource::Impl(def) => self.tcx.trait_id_of_impl(def), - CandidateSource::Trait(_) => None, - } - }) - .collect(), - _ => Vec::new(), - }; + let candidates = match self.lookup_probe_for_diagnostic( + segment.ident, + self_ty, + call_expr, + ProbeScope::AllTraits, + None, + ) { + // If we find a different result the caller probably forgot to import a trait. + Ok(ref new_pick) if pick.differs_from(new_pick) => { + vec![new_pick.item.container_id(self.tcx)] + } + Err(Ambiguity(ref sources)) => sources + .iter() + .filter_map(|source| { + match *source { + // Note: this cannot come from an inherent impl, + // because the first probing succeeded. + CandidateSource::Impl(def) => self.tcx.trait_id_of_impl(def), + CandidateSource::Trait(_) => None, + } + }) + .collect(), + _ => Vec::new(), + }; return Err(IllegalSizedBound { candidates, needs_mut, bound_span: span, self_expr }); } @@ -252,12 +258,13 @@ pub fn lookup_probe( &self, method_name: Ident, self_ty: Ty<'tcx>, - call_expr: &'tcx hir::Expr<'tcx>, + call_expr: &hir::Expr<'_>, scope: ProbeScope, ) -> probe::PickResult<'tcx> { let pick = self.probe_for_name( probe::Mode::MethodCall, method_name, + None, IsSuggestion(false), self_ty, call_expr.hir_id, @@ -267,6 +274,26 @@ pub fn lookup_probe( Ok(pick) } + pub fn lookup_probe_for_diagnostic( + &self, + method_name: Ident, + self_ty: Ty<'tcx>, + call_expr: &hir::Expr<'_>, + scope: ProbeScope, + return_type: Option>, + ) -> probe::PickResult<'tcx> { + let pick = self.probe_for_name( + probe::Mode::MethodCall, + method_name, + return_type, + IsSuggestion(true), + self_ty, + call_expr.hir_id, + scope, + )?; + Ok(pick) + } + pub(super) fn obligation_for_method( &self, cause: ObligationCause<'tcx>, @@ -484,6 +511,7 @@ pub fn resolve_fully_qualified_call( let pick = self.probe_for_name( probe::Mode::Path, method_name, + None, IsSuggestion(false), self_ty, expr_id,