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