rustc_hir_typeck/
demand.rs

1use rustc_errors::{Applicability, Diag, MultiSpan, listify};
2use rustc_hir as hir;
3use rustc_hir::def::Res;
4use rustc_hir::intravisit::Visitor;
5use rustc_infer::infer::DefineOpaqueTypes;
6use rustc_middle::bug;
7use rustc_middle::ty::adjustment::AllowTwoPhase;
8use rustc_middle::ty::error::{ExpectedFound, TypeError};
9use rustc_middle::ty::print::with_no_trimmed_paths;
10use rustc_middle::ty::{self, AssocItem, BottomUpFolder, Ty, TypeFoldable, TypeVisitableExt};
11use rustc_span::{DUMMY_SP, Ident, Span, sym};
12use rustc_trait_selection::infer::InferCtxtExt;
13use rustc_trait_selection::traits::ObligationCause;
14use tracing::instrument;
15
16use super::method::probe;
17use crate::FnCtxt;
18
19impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20    pub(crate) fn emit_type_mismatch_suggestions(
21        &self,
22        err: &mut Diag<'_>,
23        expr: &hir::Expr<'tcx>,
24        expr_ty: Ty<'tcx>,
25        expected: Ty<'tcx>,
26        expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
27        error: Option<TypeError<'tcx>>,
28    ) {
29        if expr_ty == expected {
30            return;
31        }
32        self.annotate_alternative_method_deref(err, expr, error);
33        self.explain_self_literal(err, expr, expected, expr_ty);
34
35        // Use `||` to give these suggestions a precedence
36        let suggested = self.suggest_missing_parentheses(err, expr)
37            || self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty)
38            || self.suggest_remove_last_method_call(err, expr, expected)
39            || self.suggest_associated_const(err, expr, expected)
40            || self.suggest_semicolon_in_repeat_expr(err, expr, expr_ty)
41            || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
42            || self.suggest_option_to_bool(err, expr, expr_ty, expected)
43            || self.suggest_compatible_variants(err, expr, expected, expr_ty)
44            || self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty)
45            || self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty)
46            || self.suggest_no_capture_closure(err, expected, expr_ty)
47            || self.suggest_boxing_when_appropriate(
48                err,
49                expr.peel_blocks().span,
50                expr.hir_id,
51                expected,
52                expr_ty,
53            )
54            || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
55            || self.suggest_copied_cloned_or_as_ref(err, expr, expr_ty, expected)
56            || self.suggest_clone_for_ref(err, expr, expr_ty, expected)
57            || self.suggest_into(err, expr, expr_ty, expected)
58            || self.suggest_floating_point_literal(err, expr, expected)
59            || self.suggest_null_ptr_for_literal_zero_given_to_ptr_arg(err, expr, expected)
60            || self.suggest_coercing_result_via_try_operator(err, expr, expected, expr_ty)
61            || self.suggest_returning_value_after_loop(err, expr, expected);
62
63        if !suggested {
64            self.note_source_of_type_mismatch_constraint(
65                err,
66                expr,
67                TypeMismatchSource::Ty(expected),
68            );
69        }
70    }
71
72    pub(crate) fn emit_coerce_suggestions(
73        &self,
74        err: &mut Diag<'_>,
75        expr: &hir::Expr<'tcx>,
76        expr_ty: Ty<'tcx>,
77        expected: Ty<'tcx>,
78        expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
79        error: Option<TypeError<'tcx>>,
80    ) {
81        if expr_ty == expected {
82            return;
83        }
84
85        self.annotate_expected_due_to_let_ty(err, expr, error);
86        self.annotate_loop_expected_due_to_inference(err, expr, error);
87        if self.annotate_mut_binding_to_immutable_binding(err, expr, expr_ty, expected, error) {
88            return;
89        }
90
91        // FIXME(#73154): For now, we do leak check when coercing function
92        // pointers in typeck, instead of only during borrowck. This can lead
93        // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
94        if matches!(error, Some(TypeError::RegionsInsufficientlyPolymorphic(..))) {
95            return;
96        }
97
98        if self.is_destruct_assignment_desugaring(expr) {
99            return;
100        }
101        self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
102        self.note_type_is_not_clone(err, expected, expr_ty, expr);
103        self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
104        self.suggest_method_call_on_range_literal(err, expr, expr_ty, expected);
105        self.suggest_return_binding_for_missing_tail_expr(err, expr, expr_ty, expected);
106        self.note_wrong_return_ty_due_to_generic_arg(err, expr, expr_ty);
107    }
108
109    /// Really hacky heuristic to remap an `assert_eq!` error to the user
110    /// expressions provided to the macro.
111    fn adjust_expr_for_assert_eq_macro(
112        &self,
113        found_expr: &mut &'tcx hir::Expr<'tcx>,
114        expected_expr: &mut Option<&'tcx hir::Expr<'tcx>>,
115    ) {
116        let Some(expected_expr) = expected_expr else {
117            return;
118        };
119
120        if !found_expr.span.eq_ctxt(expected_expr.span) {
121            return;
122        }
123
124        if !found_expr
125            .span
126            .ctxt()
127            .outer_expn_data()
128            .macro_def_id
129            .is_some_and(|def_id| self.tcx.is_diagnostic_item(sym::assert_eq_macro, def_id))
130        {
131            return;
132        }
133
134        let hir::ExprKind::Unary(
135            hir::UnOp::Deref,
136            hir::Expr { kind: hir::ExprKind::Path(found_path), .. },
137        ) = found_expr.kind
138        else {
139            return;
140        };
141        let hir::ExprKind::Unary(
142            hir::UnOp::Deref,
143            hir::Expr { kind: hir::ExprKind::Path(expected_path), .. },
144        ) = expected_expr.kind
145        else {
146            return;
147        };
148
149        for (path, name, idx, var) in [
150            (expected_path, "left_val", 0, expected_expr),
151            (found_path, "right_val", 1, found_expr),
152        ] {
153            if let hir::QPath::Resolved(_, path) = path
154                && let [segment] = path.segments
155                && segment.ident.name.as_str() == name
156                && let Res::Local(hir_id) = path.res
157                && let Some((_, hir::Node::Expr(match_expr))) =
158                    self.tcx.hir_parent_iter(hir_id).nth(2)
159                && let hir::ExprKind::Match(scrutinee, _, _) = match_expr.kind
160                && let hir::ExprKind::Tup(exprs) = scrutinee.kind
161                && let hir::ExprKind::AddrOf(_, _, macro_arg) = exprs[idx].kind
162            {
163                *var = macro_arg;
164            }
165        }
166    }
167
168    /// Requires that the two types unify, and prints an error message if
169    /// they don't.
170    pub(crate) fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
171        if let Err(e) = self.demand_suptype_diag(sp, expected, actual) {
172            e.emit();
173        }
174    }
175
176    pub(crate) fn demand_suptype_diag(
177        &'a self,
178        sp: Span,
179        expected: Ty<'tcx>,
180        actual: Ty<'tcx>,
181    ) -> Result<(), Diag<'a>> {
182        self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
183    }
184
185    #[instrument(skip(self), level = "debug")]
186    pub(crate) fn demand_suptype_with_origin(
187        &'a self,
188        cause: &ObligationCause<'tcx>,
189        expected: Ty<'tcx>,
190        actual: Ty<'tcx>,
191    ) -> Result<(), Diag<'a>> {
192        self.at(cause, self.param_env)
193            .sup(DefineOpaqueTypes::Yes, expected, actual)
194            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
195            .map_err(|e| {
196                self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e)
197            })
198    }
199
200    pub(crate) fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
201        if let Err(err) = self.demand_eqtype_diag(sp, expected, actual) {
202            err.emit();
203        }
204    }
205
206    pub(crate) fn demand_eqtype_diag(
207        &'a self,
208        sp: Span,
209        expected: Ty<'tcx>,
210        actual: Ty<'tcx>,
211    ) -> Result<(), Diag<'a>> {
212        self.demand_eqtype_with_origin(&self.misc(sp), expected, actual)
213    }
214
215    pub(crate) fn demand_eqtype_with_origin(
216        &'a self,
217        cause: &ObligationCause<'tcx>,
218        expected: Ty<'tcx>,
219        actual: Ty<'tcx>,
220    ) -> Result<(), Diag<'a>> {
221        self.at(cause, self.param_env)
222            .eq(DefineOpaqueTypes::Yes, expected, actual)
223            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
224            .map_err(|e| {
225                self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e)
226            })
227    }
228
229    pub(crate) fn demand_coerce(
230        &self,
231        expr: &'tcx hir::Expr<'tcx>,
232        checked_ty: Ty<'tcx>,
233        expected: Ty<'tcx>,
234        expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
235        allow_two_phase: AllowTwoPhase,
236    ) -> Ty<'tcx> {
237        match self.demand_coerce_diag(expr, checked_ty, expected, expected_ty_expr, allow_two_phase)
238        {
239            Ok(ty) => ty,
240            Err(err) => {
241                err.emit();
242                // Return the original type instead of an error type here, otherwise the type of `x` in
243                // `let x: u32 = ();` will be a type error, causing all subsequent usages of `x` to not
244                // report errors, even though `x` is definitely `u32`.
245                expected
246            }
247        }
248    }
249
250    /// Checks that the type of `expr` can be coerced to `expected`.
251    ///
252    /// N.B., this code relies on `self.diverges` to be accurate. In particular, assignments to `!`
253    /// will be permitted if the diverges flag is currently "always".
254    #[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))]
255    pub(crate) fn demand_coerce_diag(
256        &'a self,
257        mut expr: &'tcx hir::Expr<'tcx>,
258        checked_ty: Ty<'tcx>,
259        expected: Ty<'tcx>,
260        mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
261        allow_two_phase: AllowTwoPhase,
262    ) -> Result<Ty<'tcx>, Diag<'a>> {
263        let expected = if self.next_trait_solver() {
264            expected
265        } else {
266            self.resolve_vars_with_obligations(expected)
267        };
268
269        let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {
270            Ok(ty) => return Ok(ty),
271            Err(e) => e,
272        };
273
274        self.adjust_expr_for_assert_eq_macro(&mut expr, &mut expected_ty_expr);
275
276        self.set_tainted_by_errors(self.dcx().span_delayed_bug(
277            expr.span,
278            "`TypeError` when attempting coercion but no error emitted",
279        ));
280        let expr = expr.peel_drop_temps();
281        let cause = self.misc(expr.span);
282        let expr_ty = self.resolve_vars_if_possible(checked_ty);
283        let mut err =
284            self.err_ctxt().report_mismatched_types(&cause, self.param_env, expected, expr_ty, e);
285
286        self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e));
287
288        Err(err)
289    }
290
291    /// Notes the point at which a variable is constrained to some type incompatible
292    /// with some expectation given by `source`.
293    pub(crate) fn note_source_of_type_mismatch_constraint(
294        &self,
295        err: &mut Diag<'_>,
296        expr: &hir::Expr<'_>,
297        source: TypeMismatchSource<'tcx>,
298    ) -> bool {
299        let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else {
300            return false;
301        };
302        let [hir::PathSegment { ident, args: None, .. }] = p.segments else {
303            return false;
304        };
305        let hir::def::Res::Local(local_hir_id) = p.res else {
306            return false;
307        };
308        let hir::Node::Pat(pat) = self.tcx.hir_node(local_hir_id) else {
309            return false;
310        };
311        let (init_ty_hir_id, init) = match self.tcx.parent_hir_node(pat.hir_id) {
312            hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init, .. }) => (ty.hir_id, *init),
313            hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => (init.hir_id, Some(*init)),
314            _ => return false,
315        };
316        let Some(init_ty) = self.node_ty_opt(init_ty_hir_id) else {
317            return false;
318        };
319
320        // Locate all the usages of the relevant binding.
321        struct FindExprs<'tcx> {
322            hir_id: hir::HirId,
323            uses: Vec<&'tcx hir::Expr<'tcx>>,
324        }
325        impl<'tcx> Visitor<'tcx> for FindExprs<'tcx> {
326            fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
327                if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = ex.kind
328                    && let hir::def::Res::Local(hir_id) = path.res
329                    && hir_id == self.hir_id
330                {
331                    self.uses.push(ex);
332                }
333                hir::intravisit::walk_expr(self, ex);
334            }
335        }
336
337        let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() };
338        let body = self.tcx.hir_body_owned_by(self.body_id);
339        expr_finder.visit_expr(body.value);
340
341        // Replaces all of the variables in the given type with a fresh inference variable.
342        let mut fudger = BottomUpFolder {
343            tcx: self.tcx,
344            ty_op: |ty| {
345                if let ty::Infer(infer) = ty.kind() {
346                    match infer {
347                        ty::TyVar(_) => self.next_ty_var(DUMMY_SP),
348                        ty::IntVar(_) => self.next_int_var(),
349                        ty::FloatVar(_) => self.next_float_var(),
350                        ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
351                            bug!("unexpected fresh ty outside of the trait solver")
352                        }
353                    }
354                } else {
355                    ty
356                }
357            },
358            lt_op: |_| self.tcx.lifetimes.re_erased,
359            ct_op: |ct| {
360                if let ty::ConstKind::Infer(_) = ct.kind() {
361                    self.next_const_var(DUMMY_SP)
362                } else {
363                    ct
364                }
365            },
366        };
367
368        let expected_ty = match source {
369            TypeMismatchSource::Ty(expected_ty) => expected_ty,
370            // Try to deduce what the possible value of `expr` would be if the
371            // incompatible arg were compatible. For example, given `Vec<i32>`
372            // and `vec.push(1u32)`, we ideally want to deduce that the type of
373            // `vec` *should* have been `Vec<u32>`. This will allow us to then
374            // run the subsequent code with this expectation, finding out exactly
375            // when this type diverged from our expectation.
376            TypeMismatchSource::Arg { call_expr, incompatible_arg: idx } => {
377                let hir::ExprKind::MethodCall(segment, _, args, _) = call_expr.kind else {
378                    return false;
379                };
380                let Some(arg_ty) = self.node_ty_opt(args[idx].hir_id) else {
381                    return false;
382                };
383                let possible_rcvr_ty = expr_finder.uses.iter().rev().find_map(|binding| {
384                    let possible_rcvr_ty = self.node_ty_opt(binding.hir_id)?;
385                    if possible_rcvr_ty.is_ty_var() {
386                        return None;
387                    }
388                    // Fudge the receiver, so we can do new inference on it.
389                    let possible_rcvr_ty = possible_rcvr_ty.fold_with(&mut fudger);
390                    let method = self
391                        .lookup_method_for_diagnostic(
392                            possible_rcvr_ty,
393                            segment,
394                            DUMMY_SP,
395                            call_expr,
396                            binding,
397                        )
398                        .ok()?;
399                    // Make sure we select the same method that we started with...
400                    if Some(method.def_id)
401                        != self.typeck_results.borrow().type_dependent_def_id(call_expr.hir_id)
402                    {
403                        return None;
404                    }
405                    // Unify the method signature with our incompatible arg, to
406                    // do inference in the *opposite* direction and to find out
407                    // what our ideal rcvr ty would look like.
408                    let _ = self
409                        .at(&ObligationCause::dummy(), self.param_env)
410                        .eq(DefineOpaqueTypes::Yes, method.sig.inputs()[idx + 1], arg_ty)
411                        .ok()?;
412                    self.select_obligations_where_possible(|errs| {
413                        // Yeet the errors, we're already reporting errors.
414                        errs.clear();
415                    });
416                    Some(self.resolve_vars_if_possible(possible_rcvr_ty))
417                });
418                let Some(rcvr_ty) = possible_rcvr_ty else { return false };
419                rcvr_ty
420            }
421        };
422
423        // If our expected_ty does not equal init_ty, then it *began* as incompatible.
424        // No need to note in this case...
425        if !self.can_eq(self.param_env, expected_ty, init_ty.fold_with(&mut fudger)) {
426            return false;
427        }
428
429        for window in expr_finder.uses.windows(2) {
430            // Bindings always update their recorded type after the fact, so we
431            // need to look at the *following* usage's type to see when the
432            // binding became incompatible.
433            let [binding, next_usage] = *window else {
434                continue;
435            };
436
437            // Don't go past the binding (always gonna be a nonsense label if so)
438            if binding.hir_id == expr.hir_id {
439                break;
440            }
441
442            let Some(next_use_ty) = self.node_ty_opt(next_usage.hir_id) else {
443                continue;
444            };
445
446            // If the type is not constrained in a way making it not possible to
447            // equate with `expected_ty` by this point, skip.
448            if self.can_eq(self.param_env, expected_ty, next_use_ty.fold_with(&mut fudger)) {
449                continue;
450            }
451
452            if let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(binding.hir_id)
453                && let hir::ExprKind::MethodCall(segment, rcvr, args, _) = parent_expr.kind
454                && rcvr.hir_id == binding.hir_id
455            {
456                // If our binding became incompatible while it was a receiver
457                // to a method call, we may be able to make a better guess to
458                // the source of a type mismatch.
459                let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else {
460                    continue;
461                };
462                let rcvr_ty = rcvr_ty.fold_with(&mut fudger);
463                let Ok(method) = self.lookup_method_for_diagnostic(
464                    rcvr_ty,
465                    segment,
466                    DUMMY_SP,
467                    parent_expr,
468                    rcvr,
469                ) else {
470                    continue;
471                };
472                // Make sure we select the same method that we started with...
473                if Some(method.def_id)
474                    != self.typeck_results.borrow().type_dependent_def_id(parent_expr.hir_id)
475                {
476                    continue;
477                }
478
479                let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger);
480                let ideal_method = self
481                    .lookup_method_for_diagnostic(
482                        ideal_rcvr_ty,
483                        segment,
484                        DUMMY_SP,
485                        parent_expr,
486                        rcvr,
487                    )
488                    .ok()
489                    .and_then(|method| {
490                        let _ = self
491                            .at(&ObligationCause::dummy(), self.param_env)
492                            .eq(DefineOpaqueTypes::Yes, ideal_rcvr_ty, expected_ty)
493                            .ok()?;
494                        Some(method)
495                    });
496
497                // Find what argument caused our rcvr to become incompatible
498                // with the expected ty.
499                for (idx, (expected_arg_ty, arg_expr)) in
500                    std::iter::zip(&method.sig.inputs()[1..], args).enumerate()
501                {
502                    let Some(arg_ty) = self.node_ty_opt(arg_expr.hir_id) else {
503                        continue;
504                    };
505                    let arg_ty = arg_ty.fold_with(&mut fudger);
506                    let _ =
507                        self.coerce(arg_expr, arg_ty, *expected_arg_ty, AllowTwoPhase::No, None);
508                    self.select_obligations_where_possible(|errs| {
509                        // Yeet the errors, we're already reporting errors.
510                        errs.clear();
511                    });
512                    // If our rcvr, after inference due to unifying the signature
513                    // with the expected argument type, is still compatible with
514                    // the rcvr, then it must've not been the source of blame.
515                    if self.can_eq(self.param_env, rcvr_ty, expected_ty) {
516                        continue;
517                    }
518                    err.span_label(arg_expr.span, format!("this argument has type `{arg_ty}`..."));
519                    err.span_label(
520                        binding.span,
521                        format!("... which causes `{ident}` to have type `{next_use_ty}`"),
522                    );
523                    // Using our "ideal" method signature, suggest a fix to this
524                    // blame arg, if possible. Don't do this if we're coming from
525                    // arg mismatch code, because we'll possibly suggest a mutually
526                    // incompatible fix at the original mismatch site.
527                    // HACK(compiler-errors): We don't actually consider the implications
528                    // of our inference guesses in `emit_type_mismatch_suggestions`, so
529                    // only suggest things when we know our type error is precisely due to
530                    // a type mismatch, and not via some projection or something. See #116155.
531                    if matches!(source, TypeMismatchSource::Ty(_))
532                        && let Some(ideal_method) = ideal_method
533                        && Some(ideal_method.def_id)
534                            == self
535                                .typeck_results
536                                .borrow()
537                                .type_dependent_def_id(parent_expr.hir_id)
538                        && let ideal_arg_ty =
539                            self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1])
540                        && !ideal_arg_ty.has_non_region_infer()
541                    {
542                        self.emit_type_mismatch_suggestions(
543                            err,
544                            arg_expr,
545                            arg_ty,
546                            ideal_arg_ty,
547                            None,
548                            None,
549                        );
550                    }
551                    return true;
552                }
553            }
554            err.span_label(
555                binding.span,
556                format!("here the type of `{ident}` is inferred to be `{next_use_ty}`"),
557            );
558            return true;
559        }
560
561        // We must've not found something that constrained the expr.
562        false
563    }
564
565    // When encountering a type error on the value of a `break`, try to point at the reason for the
566    // expected type.
567    pub(crate) fn annotate_loop_expected_due_to_inference(
568        &self,
569        err: &mut Diag<'_>,
570        expr: &hir::Expr<'_>,
571        error: Option<TypeError<'tcx>>,
572    ) {
573        let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
574            return;
575        };
576        let mut parent_id = self.tcx.parent_hir_id(expr.hir_id);
577        let mut parent;
578        'outer: loop {
579            // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
580            let (hir::Node::Stmt(&hir::Stmt { kind: hir::StmtKind::Semi(p), .. })
581            | hir::Node::Block(&hir::Block { expr: Some(p), .. })
582            | hir::Node::Expr(p)) = self.tcx.hir_node(parent_id)
583            else {
584                break;
585            };
586            parent = p;
587            parent_id = self.tcx.parent_hir_id(parent_id);
588            let hir::ExprKind::Break(destination, _) = parent.kind else {
589                continue;
590            };
591            let mut parent_id = parent_id;
592            let mut direct = false;
593            loop {
594                // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
595                let parent = match self.tcx.hir_node(parent_id) {
596                    hir::Node::Expr(parent) => {
597                        parent_id = self.tcx.parent_hir_id(parent.hir_id);
598                        parent
599                    }
600                    hir::Node::Stmt(hir::Stmt {
601                        hir_id,
602                        kind: hir::StmtKind::Semi(parent) | hir::StmtKind::Expr(parent),
603                        ..
604                    }) => {
605                        parent_id = self.tcx.parent_hir_id(*hir_id);
606                        parent
607                    }
608                    hir::Node::Block(_) => {
609                        parent_id = self.tcx.parent_hir_id(parent_id);
610                        parent
611                    }
612                    _ => break,
613                };
614                if let hir::ExprKind::Loop(..) = parent.kind {
615                    // When you have `'a: loop { break; }`, the `break` corresponds to the labeled
616                    // loop, so we need to account for that.
617                    direct = !direct;
618                }
619                if let hir::ExprKind::Loop(block, label, _, span) = parent.kind
620                    && (destination.label == label || direct)
621                {
622                    if let Some((reason_span, message)) =
623                        self.maybe_get_coercion_reason(parent_id, parent.span)
624                    {
625                        err.span_label(reason_span, message);
626                        err.span_label(
627                            span,
628                            format!("this loop is expected to be of type `{expected}`"),
629                        );
630                        break 'outer;
631                    } else {
632                        // Locate all other `break` statements within the same `loop` that might
633                        // have affected inference.
634                        struct FindBreaks<'tcx> {
635                            label: Option<rustc_ast::Label>,
636                            uses: Vec<&'tcx hir::Expr<'tcx>>,
637                            nest_depth: usize,
638                        }
639                        impl<'tcx> Visitor<'tcx> for FindBreaks<'tcx> {
640                            fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
641                                let nest_depth = self.nest_depth;
642                                if let hir::ExprKind::Loop(_, label, _, _) = ex.kind {
643                                    if label == self.label {
644                                        // Account for `'a: loop { 'a: loop {...} }`.
645                                        return;
646                                    }
647                                    self.nest_depth += 1;
648                                }
649                                if let hir::ExprKind::Break(destination, _) = ex.kind
650                                    && (self.label == destination.label
651                                        // Account for `loop { 'a: loop { loop { break; } } }`.
652                                        || destination.label.is_none() && self.nest_depth == 0)
653                                {
654                                    self.uses.push(ex);
655                                }
656                                hir::intravisit::walk_expr(self, ex);
657                                self.nest_depth = nest_depth;
658                            }
659                        }
660                        let mut expr_finder = FindBreaks { label, uses: vec![], nest_depth: 0 };
661                        expr_finder.visit_block(block);
662                        let mut exit = false;
663                        for ex in expr_finder.uses {
664                            let hir::ExprKind::Break(_, val) = ex.kind else {
665                                continue;
666                            };
667                            let ty = match val {
668                                Some(val) => {
669                                    match self.typeck_results.borrow().expr_ty_adjusted_opt(val) {
670                                        None => continue,
671                                        Some(ty) => ty,
672                                    }
673                                }
674                                None => self.tcx.types.unit,
675                            };
676                            if self.can_eq(self.param_env, ty, expected) {
677                                err.span_label(ex.span, "expected because of this `break`");
678                                exit = true;
679                            }
680                        }
681                        if exit {
682                            break 'outer;
683                        }
684                    }
685                }
686            }
687        }
688    }
689
690    fn annotate_expected_due_to_let_ty(
691        &self,
692        err: &mut Diag<'_>,
693        expr: &hir::Expr<'_>,
694        error: Option<TypeError<'tcx>>,
695    ) {
696        match (self.tcx.parent_hir_node(expr.hir_id), error) {
697            (hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init: Some(init), .. }), _)
698                if init.hir_id == expr.hir_id && !ty.span.source_equal(init.span) =>
699            {
700                // Point at `let` assignment type.
701                err.span_label(ty.span, "expected due to this");
702            }
703            (
704                hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }),
705                Some(TypeError::Sorts(ExpectedFound { expected, .. })),
706            ) if rhs.hir_id == expr.hir_id && !expected.is_closure() => {
707                // We ignore closures explicitly because we already point at them elsewhere.
708                // Point at the assigned-to binding.
709                let mut primary_span = lhs.span;
710                let mut secondary_span = lhs.span;
711                let mut post_message = "";
712                match lhs.kind {
713                    hir::ExprKind::Path(hir::QPath::Resolved(
714                        None,
715                        hir::Path {
716                            res:
717                                hir::def::Res::Def(
718                                    hir::def::DefKind::Static { .. } | hir::def::DefKind::Const,
719                                    def_id,
720                                ),
721                            ..
722                        },
723                    )) => {
724                        if let Some(hir::Node::Item(hir::Item {
725                            kind:
726                                hir::ItemKind::Static(_, ident, ty, _)
727                                | hir::ItemKind::Const(ident, _, ty, _),
728                            ..
729                        })) = self.tcx.hir_get_if_local(*def_id)
730                        {
731                            primary_span = ty.span;
732                            secondary_span = ident.span;
733                            post_message = " type";
734                        }
735                    }
736                    hir::ExprKind::Path(hir::QPath::Resolved(
737                        None,
738                        hir::Path { res: hir::def::Res::Local(hir_id), .. },
739                    )) => {
740                        if let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) {
741                            primary_span = pat.span;
742                            secondary_span = pat.span;
743                            match self.tcx.parent_hir_node(pat.hir_id) {
744                                hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => {
745                                    primary_span = ty.span;
746                                    post_message = " type";
747                                }
748                                hir::Node::LetStmt(hir::LetStmt { init: Some(init), .. }) => {
749                                    primary_span = init.span;
750                                    post_message = " value";
751                                }
752                                hir::Node::Param(hir::Param { ty_span, .. }) => {
753                                    primary_span = *ty_span;
754                                    post_message = " parameter type";
755                                }
756                                _ => {}
757                            }
758                        }
759                    }
760                    _ => {}
761                }
762
763                if primary_span != secondary_span
764                    && self
765                        .tcx
766                        .sess
767                        .source_map()
768                        .is_multiline(secondary_span.shrink_to_hi().until(primary_span))
769                {
770                    // We are pointing at the binding's type or initializer value, but it's pattern
771                    // is in a different line, so we point at both.
772                    err.span_label(secondary_span, "expected due to the type of this binding");
773                    err.span_label(primary_span, format!("expected due to this{post_message}"));
774                } else if post_message.is_empty() {
775                    // We are pointing at either the assignment lhs or the binding def pattern.
776                    err.span_label(primary_span, "expected due to the type of this binding");
777                } else {
778                    // We are pointing at the binding's type or initializer value.
779                    err.span_label(primary_span, format!("expected due to this{post_message}"));
780                }
781
782                if !lhs.is_syntactic_place_expr() {
783                    // We already emitted E0070 "invalid left-hand side of assignment", so we
784                    // silence this.
785                    err.downgrade_to_delayed_bug();
786                }
787            }
788            (
789                hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(_, lhs, rhs), .. }),
790                Some(TypeError::Sorts(ExpectedFound { expected, .. })),
791            ) if rhs.hir_id == expr.hir_id
792                && self.typeck_results.borrow().expr_ty_adjusted_opt(lhs) == Some(expected)
793                // let expressions being marked as `bool` is confusing (see issue #147665)
794                && !matches!(lhs.kind, hir::ExprKind::Let(..)) =>
795            {
796                err.span_label(lhs.span, format!("expected because this is `{expected}`"));
797            }
798            _ => {}
799        }
800    }
801
802    /// Detect the following case
803    ///
804    /// ```text
805    /// fn change_object(mut b: &Ty) {
806    ///     let a = Ty::new();
807    ///     b = a;
808    /// }
809    /// ```
810    ///
811    /// where the user likely meant to modify the value behind there reference, use `b` as an out
812    /// parameter, instead of mutating the local binding. When encountering this we suggest:
813    ///
814    /// ```text
815    /// fn change_object(b: &'_ mut Ty) {
816    ///     let a = Ty::new();
817    ///     *b = a;
818    /// }
819    /// ```
820    fn annotate_mut_binding_to_immutable_binding(
821        &self,
822        err: &mut Diag<'_>,
823        expr: &hir::Expr<'_>,
824        expr_ty: Ty<'tcx>,
825        expected: Ty<'tcx>,
826        error: Option<TypeError<'tcx>>,
827    ) -> bool {
828        if let Some(TypeError::Sorts(ExpectedFound { .. })) = error
829            && let ty::Ref(_, inner, hir::Mutability::Not) = expected.kind()
830
831            // The difference between the expected and found values is one level of borrowing.
832            && self.can_eq(self.param_env, *inner, expr_ty)
833
834            // We have an `ident = expr;` assignment.
835            && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
836                self.tcx.parent_hir_node(expr.hir_id)
837            && rhs.hir_id == expr.hir_id
838
839            // We are assigning to some binding.
840            && let hir::ExprKind::Path(hir::QPath::Resolved(
841                None,
842                hir::Path { res: hir::def::Res::Local(hir_id), .. },
843            )) = lhs.kind
844            && let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id)
845
846            // The pattern we have is an fn argument.
847            && let hir::Node::Param(hir::Param { ty_span, .. }) =
848                self.tcx.parent_hir_node(pat.hir_id)
849            && let item = self.tcx.hir_get_parent_item(pat.hir_id)
850            && let item = self.tcx.hir_owner_node(item)
851            && let Some(fn_decl) = item.fn_decl()
852
853            // We have a mutable binding in the argument.
854            && let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind
855
856            // Look for the type corresponding to the argument pattern we have in the argument list.
857            && let Some(ty_ref) = fn_decl
858                .inputs
859                .iter()
860                .filter_map(|ty| match ty.kind {
861                    hir::TyKind::Ref(lt, mut_ty) if ty.span == *ty_span => Some((lt, mut_ty)),
862                    _ => None,
863                })
864                .next()
865        {
866            let mut sugg = if ty_ref.1.mutbl.is_mut() {
867                // Leave `&'name mut Ty` and `&mut Ty` as they are (#136028).
868                vec![]
869            } else {
870                // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
871                vec![(
872                    ty_ref.1.ty.span.shrink_to_lo(),
873                    format!("{}mut ", if ty_ref.0.ident.span.is_empty() { "" } else { " " },),
874                )]
875            };
876            sugg.extend([
877                (pat.span.until(ident.span), String::new()),
878                (lhs.span.shrink_to_lo(), "*".to_string()),
879            ]);
880            // We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the
881            // assignment from `ident = val;` to `*ident = val;`.
882            err.multipart_suggestion_verbose(
883                "you might have meant to mutate the pointed at value being passed in, instead of \
884                changing the reference in the local binding",
885                sugg,
886                Applicability::MaybeIncorrect,
887            );
888            return true;
889        }
890        false
891    }
892
893    fn annotate_alternative_method_deref(
894        &self,
895        err: &mut Diag<'_>,
896        expr: &hir::Expr<'_>,
897        error: Option<TypeError<'tcx>>,
898    ) {
899        let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
900            return;
901        };
902        let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
903            self.tcx.parent_hir_node(expr.hir_id)
904        else {
905            return;
906        };
907        if rhs.hir_id != expr.hir_id || expected.is_closure() {
908            return;
909        }
910        let hir::ExprKind::Unary(hir::UnOp::Deref, deref) = lhs.kind else {
911            return;
912        };
913        let hir::ExprKind::MethodCall(path, base, args, _) = deref.kind else {
914            return;
915        };
916        let Some(self_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(base) else {
917            return;
918        };
919
920        let Ok(pick) = self.lookup_probe_for_diagnostic(
921            path.ident,
922            self_ty,
923            deref,
924            probe::ProbeScope::TraitsInScope,
925            None,
926        ) else {
927            return;
928        };
929
930        let Ok(in_scope_methods) = self.probe_for_name_many(
931            probe::Mode::MethodCall,
932            path.ident,
933            Some(expected),
934            probe::IsSuggestion(true),
935            self_ty,
936            deref.hir_id,
937            probe::ProbeScope::TraitsInScope,
938        ) else {
939            return;
940        };
941
942        let other_methods_in_scope: Vec<_> =
943            in_scope_methods.iter().filter(|c| c.item.def_id != pick.item.def_id).collect();
944
945        let Ok(all_methods) = self.probe_for_name_many(
946            probe::Mode::MethodCall,
947            path.ident,
948            Some(expected),
949            probe::IsSuggestion(true),
950            self_ty,
951            deref.hir_id,
952            probe::ProbeScope::AllTraits,
953        ) else {
954            return;
955        };
956
957        let suggestions: Vec<_> = all_methods
958            .into_iter()
959            .filter(|c| c.item.def_id != pick.item.def_id)
960            .map(|c| {
961                let m = c.item;
962                let generic_args = ty::GenericArgs::for_item(self.tcx, m.def_id, |param, _| {
963                    self.var_for_def(deref.span, param)
964                });
965                let mutability =
966                    match self.tcx.fn_sig(m.def_id).skip_binder().input(0).skip_binder().kind() {
967                        ty::Ref(_, _, hir::Mutability::Mut) => "&mut ",
968                        ty::Ref(_, _, _) => "&",
969                        _ => "",
970                    };
971                vec![
972                    (
973                        deref.span.until(base.span),
974                        format!(
975                            "{}({}",
976                            with_no_trimmed_paths!(
977                                self.tcx.def_path_str_with_args(m.def_id, generic_args,)
978                            ),
979                            mutability,
980                        ),
981                    ),
982                    match &args {
983                        [] => (base.span.shrink_to_hi().with_hi(deref.span.hi()), ")".to_string()),
984                        [first, ..] => (base.span.between(first.span), ", ".to_string()),
985                    },
986                ]
987            })
988            .collect();
989        if suggestions.is_empty() {
990            return;
991        }
992        let mut path_span: MultiSpan = path.ident.span.into();
993        path_span.push_span_label(
994            path.ident.span,
995            with_no_trimmed_paths!(format!(
996                "refers to `{}`",
997                self.tcx.def_path_str(pick.item.def_id),
998            )),
999        );
1000        let container_id = pick.item.container_id(self.tcx);
1001        let container = with_no_trimmed_paths!(self.tcx.def_path_str(container_id));
1002        for def_id in pick.import_ids {
1003            let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
1004            path_span
1005                .push_span_label(self.tcx.hir_span(hir_id), format!("`{container}` imported here"));
1006        }
1007        let tail = with_no_trimmed_paths!(match &other_methods_in_scope[..] {
1008            [] => return,
1009            [candidate] => format!(
1010                "the method of the same name on {} `{}`",
1011                match candidate.kind {
1012                    probe::CandidateKind::InherentImplCandidate { .. } => "the inherent impl for",
1013                    _ => "trait",
1014                },
1015                self.tcx.def_path_str(candidate.item.container_id(self.tcx))
1016            ),
1017            _ if other_methods_in_scope.len() < 5 => {
1018                format!(
1019                    "the methods of the same name on {}",
1020                    listify(
1021                        &other_methods_in_scope[..other_methods_in_scope.len() - 1],
1022                        |c| format!("`{}`", self.tcx.def_path_str(c.item.container_id(self.tcx)))
1023                    )
1024                    .unwrap_or_default(),
1025                )
1026            }
1027            _ => format!(
1028                "the methods of the same name on {} other traits",
1029                other_methods_in_scope.len()
1030            ),
1031        });
1032        err.span_note(
1033            path_span,
1034            format!(
1035                "the `{}` call is resolved to the method in `{container}`, shadowing {tail}",
1036                path.ident,
1037            ),
1038        );
1039        if suggestions.len() > other_methods_in_scope.len() {
1040            err.note(format!(
1041                "additionally, there are {} other available methods that aren't in scope",
1042                suggestions.len() - other_methods_in_scope.len()
1043            ));
1044        }
1045        err.multipart_suggestions(
1046            format!(
1047                "you might have meant to call {}; you can use the fully-qualified path to call {} \
1048                 explicitly",
1049                if suggestions.len() == 1 {
1050                    "the other method"
1051                } else {
1052                    "one of the other methods"
1053                },
1054                if suggestions.len() == 1 { "it" } else { "one of them" },
1055            ),
1056            suggestions,
1057            Applicability::MaybeIncorrect,
1058        );
1059    }
1060
1061    pub(crate) fn get_conversion_methods_for_diagnostic(
1062        &self,
1063        span: Span,
1064        expected: Ty<'tcx>,
1065        checked_ty: Ty<'tcx>,
1066        hir_id: hir::HirId,
1067    ) -> Vec<AssocItem> {
1068        let methods = self.probe_for_return_type_for_diagnostic(
1069            span,
1070            probe::Mode::MethodCall,
1071            expected,
1072            checked_ty,
1073            hir_id,
1074            |m| {
1075                self.has_only_self_parameter(m)
1076                    && self
1077                        .tcx
1078                        // This special internal attribute is used to permit
1079                        // "identity-like" conversion methods to be suggested here.
1080                        //
1081                        // FIXME (#46459 and #46460): ideally
1082                        // `std::convert::Into::into` and `std::borrow:ToOwned` would
1083                        // also be `#[rustc_conversion_suggestion]`, if not for
1084                        // method-probing false-positives and -negatives (respectively).
1085                        //
1086                        // FIXME? Other potential candidate methods: `as_ref` and
1087                        // `as_mut`?
1088                        .has_attr(m.def_id, sym::rustc_conversion_suggestion)
1089            },
1090        );
1091
1092        methods
1093    }
1094
1095    /// This function checks whether the method is not static and does not accept other parameters than `self`.
1096    fn has_only_self_parameter(&self, method: &AssocItem) -> bool {
1097        method.is_method()
1098            && self.tcx.fn_sig(method.def_id).skip_binder().inputs().skip_binder().len() == 1
1099    }
1100
1101    /// If the given `HirId` corresponds to a block with a trailing expression, return that expression
1102    pub(crate) fn maybe_get_block_expr(
1103        &self,
1104        expr: &hir::Expr<'tcx>,
1105    ) -> Option<&'tcx hir::Expr<'tcx>> {
1106        match expr {
1107            hir::Expr { kind: hir::ExprKind::Block(block, ..), .. } => block.expr,
1108            _ => None,
1109        }
1110    }
1111
1112    /// Returns whether the given expression is a destruct assignment desugaring.
1113    /// For example, `(a, b) = (1, &2);`
1114    /// Here we try to find the pattern binding of the expression,
1115    /// `default_binding_modes` is false only for destruct assignment desugaring.
1116    pub(crate) fn is_destruct_assignment_desugaring(&self, expr: &hir::Expr<'_>) -> bool {
1117        if let hir::ExprKind::Path(hir::QPath::Resolved(
1118            _,
1119            hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
1120        )) = expr.kind
1121            && let bind = self.tcx.hir_node(*bind_hir_id)
1122            && let parent = self.tcx.parent_hir_node(*bind_hir_id)
1123            && let hir::Node::Pat(hir::Pat {
1124                kind: hir::PatKind::Binding(_, _hir_id, _, _), ..
1125            }) = bind
1126            && let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent
1127        {
1128            true
1129        } else {
1130            false
1131        }
1132    }
1133
1134    fn explain_self_literal(
1135        &self,
1136        err: &mut Diag<'_>,
1137        expr: &hir::Expr<'tcx>,
1138        expected: Ty<'tcx>,
1139        found: Ty<'tcx>,
1140    ) {
1141        match expr.peel_drop_temps().kind {
1142            hir::ExprKind::Struct(
1143                hir::QPath::Resolved(
1144                    None,
1145                    hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, span, .. },
1146                ),
1147                ..,
1148            )
1149            | hir::ExprKind::Call(
1150                hir::Expr {
1151                    kind:
1152                        hir::ExprKind::Path(hir::QPath::Resolved(
1153                            None,
1154                            hir::Path {
1155                                res: hir::def::Res::SelfTyAlias { alias_to, .. },
1156                                span,
1157                                ..
1158                            },
1159                        )),
1160                    ..
1161                },
1162                ..,
1163            ) => {
1164                if let Some(hir::Node::Item(hir::Item {
1165                    kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
1166                    ..
1167                })) = self.tcx.hir_get_if_local(*alias_to)
1168                {
1169                    err.span_label(self_ty.span, "this is the type of the `Self` literal");
1170                }
1171                if let ty::Adt(e_def, e_args) = expected.kind()
1172                    && let ty::Adt(f_def, _f_args) = found.kind()
1173                    && e_def == f_def
1174                {
1175                    err.span_suggestion_verbose(
1176                        *span,
1177                        "use the type name directly",
1178                        self.tcx.value_path_str_with_args(e_def.did(), e_args),
1179                        Applicability::MaybeIncorrect,
1180                    );
1181                }
1182            }
1183            _ => {}
1184        }
1185    }
1186
1187    fn note_wrong_return_ty_due_to_generic_arg(
1188        &self,
1189        err: &mut Diag<'_>,
1190        expr: &hir::Expr<'_>,
1191        checked_ty: Ty<'tcx>,
1192    ) {
1193        let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr.hir_id) else {
1194            return;
1195        };
1196        if parent_expr.span.desugaring_kind().is_some() {
1197            return;
1198        }
1199        enum CallableKind {
1200            Function,
1201            Method,
1202            Constructor,
1203        }
1204        let mut maybe_emit_help = |def_id: hir::def_id::DefId,
1205                                   callable: Ident,
1206                                   args: &[hir::Expr<'_>],
1207                                   kind: CallableKind| {
1208            let arg_idx = args.iter().position(|a| a.hir_id == expr.hir_id).unwrap();
1209            let fn_ty = self.tcx.type_of(def_id).skip_binder();
1210            if !fn_ty.is_fn() {
1211                return;
1212            }
1213            let fn_sig = fn_ty.fn_sig(self.tcx).skip_binder();
1214            let Some(&arg) = fn_sig
1215                .inputs()
1216                .get(arg_idx + if matches!(kind, CallableKind::Method) { 1 } else { 0 })
1217            else {
1218                return;
1219            };
1220            if matches!(arg.kind(), ty::Param(_))
1221                && fn_sig.output().contains(arg)
1222                && self.node_ty(args[arg_idx].hir_id) == checked_ty
1223            {
1224                let mut multi_span: MultiSpan = parent_expr.span.into();
1225                multi_span.push_span_label(
1226                    args[arg_idx].span,
1227                    format!(
1228                        "this argument influences the {} of `{}`",
1229                        if matches!(kind, CallableKind::Constructor) {
1230                            "type"
1231                        } else {
1232                            "return type"
1233                        },
1234                        callable
1235                    ),
1236                );
1237                err.span_help(
1238                    multi_span,
1239                    format!(
1240                        "the {} `{}` due to the type of the argument passed",
1241                        match kind {
1242                            CallableKind::Function => "return type of this call is",
1243                            CallableKind::Method => "return type of this call is",
1244                            CallableKind::Constructor => "type constructed contains",
1245                        },
1246                        checked_ty
1247                    ),
1248                );
1249            }
1250        };
1251        match parent_expr.kind {
1252            hir::ExprKind::Call(fun, args) => {
1253                let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = fun.kind else {
1254                    return;
1255                };
1256                let hir::def::Res::Def(kind, def_id) = path.res else {
1257                    return;
1258                };
1259                let callable_kind = if matches!(kind, hir::def::DefKind::Ctor(_, _)) {
1260                    CallableKind::Constructor
1261                } else {
1262                    CallableKind::Function
1263                };
1264                maybe_emit_help(def_id, path.segments.last().unwrap().ident, args, callable_kind);
1265            }
1266            hir::ExprKind::MethodCall(method, _receiver, args, _span) => {
1267                let Some(def_id) =
1268                    self.typeck_results.borrow().type_dependent_def_id(parent_expr.hir_id)
1269                else {
1270                    return;
1271                };
1272                maybe_emit_help(def_id, method.ident, args, CallableKind::Method)
1273            }
1274            _ => return,
1275        }
1276    }
1277}
1278
1279pub(crate) enum TypeMismatchSource<'tcx> {
1280    /// Expected the binding to have the given type, but it was found to have
1281    /// a different type. Find out when that type first became incompatible.
1282    Ty(Ty<'tcx>),
1283    /// When we fail during method argument checking, try to find out if a previous
1284    /// expression has constrained the method's receiver in a way that makes the
1285    /// argument's type incompatible.
1286    Arg { call_expr: &'tcx hir::Expr<'tcx>, incompatible_arg: usize },
1287}