Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/callee.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/callee.rs | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/crates/hir-ty/src/infer/callee.rs b/crates/hir-ty/src/infer/callee.rs index 9fe566b8fe..9c134cb75f 100644 --- a/crates/hir-ty/src/infer/callee.rs +++ b/crates/hir-ty/src/infer/callee.rs @@ -43,9 +43,11 @@ impl<'db> InferenceContext<'_, 'db> { ) -> Ty<'db> { let original_callee_ty = self.infer_expr_no_expect(callee_expr, ExprIsRead::Yes); - let expr_ty = self.table.try_structurally_resolve_type(original_callee_ty); + let expr_ty = + self.table.try_structurally_resolve_type(callee_expr.into(), original_callee_ty); - let mut autoderef = GeneralAutoderef::new_from_inference_context(self, expr_ty); + let mut autoderef = + GeneralAutoderef::new_from_inference_context(self, expr_ty, callee_expr.into()); let mut result = None; let mut error_reported = false; while result.is_none() && autoderef.next().is_some() { @@ -95,7 +97,7 @@ impl<'db> InferenceContext<'_, 'db> { }; // we must check that return type of called functions is WF: - self.table.register_wf_obligation(output.into(), ObligationCause::new()); + self.table.register_wf_obligation(output.into(), ObligationCause::new(call_expr)); output } @@ -108,7 +110,8 @@ impl<'db> InferenceContext<'_, 'db> { error_reported: &mut bool, ) -> Option<CallStep<'db>> { let final_ty = autoderef.final_ty(); - let adjusted_ty = autoderef.ctx().table.try_structurally_resolve_type(final_ty); + let adjusted_ty = + autoderef.ctx().table.try_structurally_resolve_type(callee_expr.into(), final_ty); // If the callee is a function pointer or a closure, then we're all set. match adjusted_ty.kind() { @@ -242,8 +245,8 @@ impl<'db> InferenceContext<'_, 'db> { // is implemented, and use this information for diagnostic. autoderef .ctx() - .try_overloaded_call_traits(adjusted_ty, Some(arg_exprs)) - .or_else(|| autoderef.ctx().try_overloaded_call_traits(adjusted_ty, None)) + .try_overloaded_call_traits(call_expr, adjusted_ty, Some(arg_exprs)) + .or_else(|| autoderef.ctx().try_overloaded_call_traits(call_expr, adjusted_ty, None)) .map(|(autoref, method)| { let adjustments = autoderef.adjust_steps_as_infer_ok(); let mut adjustments = autoderef.ctx().table.register_infer_ok(adjustments); @@ -255,6 +258,7 @@ impl<'db> InferenceContext<'_, 'db> { fn try_overloaded_call_traits( &mut self, + call_expr: ExprId, adjusted_ty: Ty<'db>, opt_arg_exprs: Option<&[ExprId]>, ) -> Option<(Option<Adjustment>, MethodCallee<'db>)> { @@ -311,7 +315,7 @@ impl<'db> InferenceContext<'_, 'db> { // one which may apply. So if we treat opaques as inference variables // `Box<impl FnOnce()>: Fn` is considered ambiguous and chosen. if let Some(ok) = self.table.lookup_method_for_operator( - ObligationCause::new(), + ObligationCause::new(call_expr), method_name, trait_def_id, adjusted_ty, @@ -464,8 +468,9 @@ impl<'db> InferenceContext<'_, 'db> { && let Some(ty) = fn_sig.inputs().last().copied() && let Some(tuple_trait) = self.lang_items.Tuple { - self.table.register_bound(ty, tuple_trait, ObligationCause::new()); - self.require_type_is_sized(ty); + let span = arg_exprs.last().copied().unwrap_or(call_expr); + self.table.register_bound(ty, tuple_trait, ObligationCause::new(span)); + self.require_type_is_sized(ty, span.into()); } fn_sig.output() @@ -538,7 +543,7 @@ impl<'a, 'db> DeferredCallResolution<'db> { assert!(ctx.infcx().closure_kind(self.closure_ty).is_some()); // We may now know enough to figure out fn vs fnmut etc. - match ctx.try_overloaded_call_traits(self.closure_ty, None) { + match ctx.try_overloaded_call_traits(self.call_expr, self.closure_ty, None) { Some((autoref, method_callee)) => { // One problem is that when we get here, we are going // to have a newly instantiated function signature |