]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
rustc_hir_typeck: fix paths and partially mv files
[rust.git] / compiler / rustc_hir_typeck / src / fn_ctxt / checks.rs
1 use crate::coercion::CoerceMany;
2 use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx};
3 use crate::gather_locals::Declaration;
4 use crate::method::MethodCallee;
5 use crate::Expectation::*;
6 use crate::TupleArgumentsFlag::*;
7 use crate::{
8     struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, Needs,
9     TupleArgumentsFlag,
10 };
11 use rustc_ast as ast;
12 use rustc_data_structures::fx::FxHashSet;
13 use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
14 use rustc_hir as hir;
15 use rustc_hir::def::{CtorOf, DefKind, Res};
16 use rustc_hir::def_id::DefId;
17 use rustc_hir::{ExprKind, Node, QPath};
18 use rustc_hir_analysis::astconv::AstConv;
19 use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
20 use rustc_hir_analysis::check::potentially_plural_count;
21 use rustc_hir_analysis::structured_errors::StructuredDiagnostic;
22 use rustc_index::vec::IndexVec;
23 use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
24 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
25 use rustc_infer::infer::InferOk;
26 use rustc_infer::infer::TypeTrace;
27 use rustc_middle::ty::adjustment::AllowTwoPhase;
28 use rustc_middle::ty::visit::TypeVisitable;
29 use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor};
30 use rustc_session::Session;
31 use rustc_span::symbol::Ident;
32 use rustc_span::{self, sym, Span};
33 use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
34
35 use std::iter;
36 use std::ops::ControlFlow;
37 use std::slice;
38
39 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
40     pub(in super::super) fn check_casts(&self) {
41         let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
42         debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
43         for cast in deferred_cast_checks.drain(..) {
44             cast.check(self);
45         }
46     }
47
48     pub(in super::super) fn check_transmutes(&self) {
49         let mut deferred_transmute_checks = self.deferred_transmute_checks.borrow_mut();
50         debug!("FnCtxt::check_transmutes: {} deferred checks", deferred_transmute_checks.len());
51         for (from, to, hir_id) in deferred_transmute_checks.drain(..) {
52             self.check_transmute(from, to, hir_id);
53         }
54     }
55
56     pub(in super::super) fn check_asms(&self) {
57         let mut deferred_asm_checks = self.deferred_asm_checks.borrow_mut();
58         debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
59         for (asm, hir_id) in deferred_asm_checks.drain(..) {
60             let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
61             let get_operand_ty = |expr| {
62                 let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
63                 let ty = self.resolve_vars_if_possible(ty);
64                 if ty.has_non_region_infer() {
65                     assert!(self.is_tainted_by_errors());
66                     self.tcx.ty_error()
67                 } else {
68                     self.tcx.erase_regions(ty)
69                 }
70             };
71             InlineAsmCtxt::new_in_fn(self.tcx, self.param_env, get_operand_ty)
72                 .check_asm(asm, self.tcx.hir().local_def_id_to_hir_id(enclosing_id));
73         }
74     }
75
76     pub(in super::super) fn check_method_argument_types(
77         &self,
78         sp: Span,
79         expr: &'tcx hir::Expr<'tcx>,
80         method: Result<MethodCallee<'tcx>, ()>,
81         args_no_rcvr: &'tcx [hir::Expr<'tcx>],
82         tuple_arguments: TupleArgumentsFlag,
83         expected: Expectation<'tcx>,
84     ) -> Ty<'tcx> {
85         let has_error = match method {
86             Ok(method) => method.substs.references_error() || method.sig.references_error(),
87             Err(_) => true,
88         };
89         if has_error {
90             let err_inputs = self.err_args(args_no_rcvr.len());
91
92             let err_inputs = match tuple_arguments {
93                 DontTupleArguments => err_inputs,
94                 TupleArguments => vec![self.tcx.intern_tup(&err_inputs)],
95             };
96
97             self.check_argument_types(
98                 sp,
99                 expr,
100                 &err_inputs,
101                 None,
102                 args_no_rcvr,
103                 false,
104                 tuple_arguments,
105                 method.ok().map(|method| method.def_id),
106             );
107             return self.tcx.ty_error();
108         }
109
110         let method = method.unwrap();
111         // HACK(eddyb) ignore self in the definition (see above).
112         let expected_input_tys = self.expected_inputs_for_expected_output(
113             sp,
114             expected,
115             method.sig.output(),
116             &method.sig.inputs()[1..],
117         );
118         self.check_argument_types(
119             sp,
120             expr,
121             &method.sig.inputs()[1..],
122             expected_input_tys,
123             args_no_rcvr,
124             method.sig.c_variadic,
125             tuple_arguments,
126             Some(method.def_id),
127         );
128         method.sig.output()
129     }
130
131     /// Generic function that factors out common logic from function calls,
132     /// method calls and overloaded operators.
133     pub(in super::super) fn check_argument_types(
134         &self,
135         // Span enclosing the call site
136         call_span: Span,
137         // Expression of the call site
138         call_expr: &'tcx hir::Expr<'tcx>,
139         // Types (as defined in the *signature* of the target function)
140         formal_input_tys: &[Ty<'tcx>],
141         // More specific expected types, after unifying with caller output types
142         expected_input_tys: Option<Vec<Ty<'tcx>>>,
143         // The expressions for each provided argument
144         provided_args: &'tcx [hir::Expr<'tcx>],
145         // Whether the function is variadic, for example when imported from C
146         c_variadic: bool,
147         // Whether the arguments have been bundled in a tuple (ex: closures)
148         tuple_arguments: TupleArgumentsFlag,
149         // The DefId for the function being called, for better error messages
150         fn_def_id: Option<DefId>,
151     ) {
152         let tcx = self.tcx;
153
154         // Conceptually, we've got some number of expected inputs, and some number of provided arguments
155         // and we can form a grid of whether each argument could satisfy a given input:
156         //      in1 | in2 | in3 | ...
157         // arg1  ?  |     |     |
158         // arg2     |  ?  |     |
159         // arg3     |     |  ?  |
160         // ...
161         // Initially, we just check the diagonal, because in the case of correct code
162         // these are the only checks that matter
163         // However, in the unhappy path, we'll fill in this whole grid to attempt to provide
164         // better error messages about invalid method calls.
165
166         // All the input types from the fn signature must outlive the call
167         // so as to validate implied bounds.
168         for (&fn_input_ty, arg_expr) in iter::zip(formal_input_tys, provided_args) {
169             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
170         }
171
172         let mut err_code = "E0061";
173
174         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
175         let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
176             let tuple_type = self.structurally_resolved_type(call_span, formal_input_tys[0]);
177             match tuple_type.kind() {
178                 // We expected a tuple and got a tuple
179                 ty::Tuple(arg_types) => {
180                     // Argument length differs
181                     if arg_types.len() != provided_args.len() {
182                         err_code = "E0057";
183                     }
184                     let expected_input_tys = match expected_input_tys {
185                         Some(expected_input_tys) => match expected_input_tys.get(0) {
186                             Some(ty) => match ty.kind() {
187                                 ty::Tuple(tys) => Some(tys.iter().collect()),
188                                 _ => None,
189                             },
190                             None => None,
191                         },
192                         None => None,
193                     };
194                     (arg_types.iter().collect(), expected_input_tys)
195                 }
196                 _ => {
197                     // Otherwise, there's a mismatch, so clear out what we're expecting, and set
198                     // our input types to err_args so we don't blow up the error messages
199                     struct_span_err!(
200                         tcx.sess,
201                         call_span,
202                         E0059,
203                         "cannot use call notation; the first type parameter \
204                          for the function trait is neither a tuple nor unit"
205                     )
206                     .emit();
207                     (self.err_args(provided_args.len()), None)
208                 }
209             }
210         } else {
211             (formal_input_tys.to_vec(), expected_input_tys)
212         };
213
214         // If there are no external expectations at the call site, just use the types from the function defn
215         let expected_input_tys = if let Some(expected_input_tys) = expected_input_tys {
216             assert_eq!(expected_input_tys.len(), formal_input_tys.len());
217             expected_input_tys
218         } else {
219             formal_input_tys.clone()
220         };
221
222         let minimum_input_count = expected_input_tys.len();
223         let provided_arg_count = provided_args.len();
224
225         let is_const_eval_select = matches!(fn_def_id, Some(def_id) if
226             self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
227             && self.tcx.is_intrinsic(def_id)
228             && self.tcx.item_name(def_id) == sym::const_eval_select);
229
230         // We introduce a helper function to demand that a given argument satisfy a given input
231         // This is more complicated than just checking type equality, as arguments could be coerced
232         // This version writes those types back so further type checking uses the narrowed types
233         let demand_compatible = |idx| {
234             let formal_input_ty: Ty<'tcx> = formal_input_tys[idx];
235             let expected_input_ty: Ty<'tcx> = expected_input_tys[idx];
236             let provided_arg = &provided_args[idx];
237
238             debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
239
240             // We're on the happy path here, so we'll do a more involved check and write back types
241             // To check compatibility, we'll do 3 things:
242             // 1. Unify the provided argument with the expected type
243             let expectation = Expectation::rvalue_hint(self, expected_input_ty);
244
245             let checked_ty = self.check_expr_with_expectation(provided_arg, expectation);
246
247             // 2. Coerce to the most detailed type that could be coerced
248             //    to, which is `expected_ty` if `rvalue_hint` returns an
249             //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
250             let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
251
252             // Cause selection errors caused by resolving a single argument to point at the
253             // argument and not the call. This lets us customize the span pointed to in the
254             // fulfillment error to be more accurate.
255             let coerced_ty = self.resolve_vars_with_obligations(coerced_ty);
256
257             let coerce_error = self
258                 .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
259                 .err();
260
261             if coerce_error.is_some() {
262                 return Compatibility::Incompatible(coerce_error);
263             }
264
265             // Check that second and third argument of `const_eval_select` must be `FnDef`, and additionally that
266             // the second argument must be `const fn`. The first argument must be a tuple, but this is already expressed
267             // in the function signature (`F: FnOnce<ARG>`), so I did not bother to add another check here.
268             //
269             // This check is here because there is currently no way to express a trait bound for `FnDef` types only.
270             if is_const_eval_select && (1..=2).contains(&idx) {
271                 if let ty::FnDef(def_id, _) = checked_ty.kind() {
272                     if idx == 1 && !self.tcx.is_const_fn_raw(*def_id) {
273                         self.tcx
274                             .sess
275                             .struct_span_err(provided_arg.span, "this argument must be a `const fn`")
276                             .help("consult the documentation on `const_eval_select` for more information")
277                             .emit();
278                     }
279                 } else {
280                     self.tcx
281                         .sess
282                         .struct_span_err(provided_arg.span, "this argument must be a function item")
283                         .note(format!("expected a function item, found {checked_ty}"))
284                         .help(
285                             "consult the documentation on `const_eval_select` for more information",
286                         )
287                         .emit();
288                 }
289             }
290
291             // 3. Check if the formal type is a supertype of the checked one
292             //    and register any such obligations for future type checks
293             let supertype_error = self
294                 .at(&self.misc(provided_arg.span), self.param_env)
295                 .sup(formal_input_ty, coerced_ty);
296             let subtyping_error = match supertype_error {
297                 Ok(InferOk { obligations, value: () }) => {
298                     self.register_predicates(obligations);
299                     None
300                 }
301                 Err(err) => Some(err),
302             };
303
304             // If neither check failed, the types are compatible
305             match subtyping_error {
306                 None => Compatibility::Compatible,
307                 Some(_) => Compatibility::Incompatible(subtyping_error),
308             }
309         };
310
311         // To start, we only care "along the diagonal", where we expect every
312         // provided arg to be in the right spot
313         let mut compatibility_diagonal =
314             vec![Compatibility::Incompatible(None); provided_args.len()];
315
316         // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path
317         // if the wrong number of arguments were supplied, we CAN'T be satisfied,
318         // and if we're c_variadic, the supplied arguments must be >= the minimum count from the function
319         // otherwise, they need to be identical, because rust doesn't currently support variadic functions
320         let mut call_appears_satisfied = if c_variadic {
321             provided_arg_count >= minimum_input_count
322         } else {
323             provided_arg_count == minimum_input_count
324         };
325
326         // Check the arguments.
327         // We do this in a pretty awful way: first we type-check any arguments
328         // that are not closures, then we type-check the closures. This is so
329         // that we have more information about the types of arguments when we
330         // type-check the functions. This isn't really the right way to do this.
331         for check_closures in [false, true] {
332             // More awful hacks: before we check argument types, try to do
333             // an "opportunistic" trait resolution of any trait bounds on
334             // the call. This helps coercions.
335             if check_closures {
336                 self.select_obligations_where_possible(false, |_| {})
337             }
338
339             // Check each argument, to satisfy the input it was provided for
340             // Visually, we're traveling down the diagonal of the compatibility matrix
341             for (idx, arg) in provided_args.iter().enumerate() {
342                 // Warn only for the first loop (the "no closures" one).
343                 // Closure arguments themselves can't be diverging, but
344                 // a previous argument can, e.g., `foo(panic!(), || {})`.
345                 if !check_closures {
346                     self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
347                 }
348
349                 // For C-variadic functions, we don't have a declared type for all of
350                 // the arguments hence we only do our usual type checking with
351                 // the arguments who's types we do know. However, we *can* check
352                 // for unreachable expressions (see above).
353                 // FIXME: unreachable warning current isn't emitted
354                 if idx >= minimum_input_count {
355                     continue;
356                 }
357
358                 let is_closure = matches!(arg.kind, ExprKind::Closure { .. });
359                 if is_closure != check_closures {
360                     continue;
361                 }
362
363                 let compatible = demand_compatible(idx);
364                 let is_compatible = matches!(compatible, Compatibility::Compatible);
365                 compatibility_diagonal[idx] = compatible;
366
367                 if !is_compatible {
368                     call_appears_satisfied = false;
369                 }
370             }
371         }
372
373         if c_variadic && provided_arg_count < minimum_input_count {
374             err_code = "E0060";
375         }
376
377         for arg in provided_args.iter().skip(minimum_input_count) {
378             // Make sure we've checked this expr at least once.
379             let arg_ty = self.check_expr(&arg);
380
381             // If the function is c-style variadic, we skipped a bunch of arguments
382             // so we need to check those, and write out the types
383             // Ideally this would be folded into the above, for uniform style
384             // but c-variadic is already a corner case
385             if c_variadic {
386                 fn variadic_error<'tcx>(
387                     sess: &'tcx Session,
388                     span: Span,
389                     ty: Ty<'tcx>,
390                     cast_ty: &str,
391                 ) {
392                     use rustc_hir_analysis::structured_errors::MissingCastForVariadicArg;
393
394                     MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
395                 }
396
397                 // There are a few types which get autopromoted when passed via varargs
398                 // in C but we just error out instead and require explicit casts.
399                 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
400                 match arg_ty.kind() {
401                     ty::Float(ty::FloatTy::F32) => {
402                         variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
403                     }
404                     ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
405                         variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
406                     }
407                     ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
408                         variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
409                     }
410                     ty::FnDef(..) => {
411                         let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
412                         let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
413                         variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
414                     }
415                     _ => {}
416                 }
417             }
418         }
419
420         if !call_appears_satisfied {
421             let compatibility_diagonal = IndexVec::from_raw(compatibility_diagonal);
422             let provided_args = IndexVec::from_iter(provided_args.iter().take(if c_variadic {
423                 minimum_input_count
424             } else {
425                 provided_arg_count
426             }));
427             debug_assert_eq!(
428                 formal_input_tys.len(),
429                 expected_input_tys.len(),
430                 "expected formal_input_tys to be the same size as expected_input_tys"
431             );
432             let formal_and_expected_inputs = IndexVec::from_iter(
433                 formal_input_tys
434                     .iter()
435                     .copied()
436                     .zip(expected_input_tys.iter().copied())
437                     .map(|vars| self.resolve_vars_if_possible(vars)),
438             );
439
440             self.report_arg_errors(
441                 compatibility_diagonal,
442                 formal_and_expected_inputs,
443                 provided_args,
444                 c_variadic,
445                 err_code,
446                 fn_def_id,
447                 call_span,
448                 call_expr,
449             );
450         }
451     }
452
453     fn report_arg_errors(
454         &self,
455         compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
456         formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
457         provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
458         c_variadic: bool,
459         err_code: &str,
460         fn_def_id: Option<DefId>,
461         call_span: Span,
462         call_expr: &hir::Expr<'tcx>,
463     ) {
464         // Next, let's construct the error
465         let (error_span, full_call_span, ctor_of, is_method) = match &call_expr.kind {
466             hir::ExprKind::Call(
467                 hir::Expr { hir_id, span, kind: hir::ExprKind::Path(qpath), .. },
468                 _,
469             ) => {
470                 if let Res::Def(DefKind::Ctor(of, _), _) =
471                     self.typeck_results.borrow().qpath_res(qpath, *hir_id)
472                 {
473                     (call_span, *span, Some(of), false)
474                 } else {
475                     (call_span, *span, None, false)
476                 }
477             }
478             hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
479             hir::ExprKind::MethodCall(path_segment, _, _, span) => {
480                 let ident_span = path_segment.ident.span;
481                 let ident_span = if let Some(args) = path_segment.args {
482                     ident_span.with_hi(args.span_ext.hi())
483                 } else {
484                     ident_span
485                 };
486                 // methods are never ctors
487                 (*span, ident_span, None, true)
488             }
489             k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
490         };
491         let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
492         let call_name = match ctor_of {
493             Some(CtorOf::Struct) => "struct",
494             Some(CtorOf::Variant) => "enum variant",
495             None => "function",
496         };
497
498         // Don't print if it has error types or is just plain `_`
499         fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
500             tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
501         }
502
503         self.set_tainted_by_errors();
504         let tcx = self.tcx;
505
506         // Get the argument span in the context of the call span so that
507         // suggestions and labels are (more) correct when an arg is a
508         // macro invocation.
509         let normalize_span = |span: Span| -> Span {
510             let normalized_span = span.find_ancestor_inside(error_span).unwrap_or(span);
511             // Sometimes macros mess up the spans, so do not normalize the
512             // arg span to equal the error span, because that's less useful
513             // than pointing out the arg expr in the wrong context.
514             if normalized_span.source_equal(error_span) { span } else { normalized_span }
515         };
516
517         // Precompute the provided types and spans, since that's all we typically need for below
518         let provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)> = provided_args
519             .iter()
520             .map(|expr| {
521                 let ty = self
522                     .typeck_results
523                     .borrow()
524                     .expr_ty_adjusted_opt(*expr)
525                     .unwrap_or_else(|| tcx.ty_error());
526                 (self.resolve_vars_if_possible(ty), normalize_span(expr.span))
527             })
528             .collect();
529         let callee_expr = match &call_expr.peel_blocks().kind {
530             hir::ExprKind::Call(callee, _) => Some(*callee),
531             hir::ExprKind::MethodCall(_, receiver, ..) => {
532                 if let Some((DefKind::AssocFn, def_id)) =
533                     self.typeck_results.borrow().type_dependent_def(call_expr.hir_id)
534                     && let Some(assoc) = tcx.opt_associated_item(def_id)
535                     && assoc.fn_has_self_parameter
536                 {
537                     Some(*receiver)
538                 } else {
539                     None
540                 }
541             }
542             _ => None,
543         };
544         let callee_ty = callee_expr
545             .and_then(|callee_expr| self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr));
546
547         // A "softer" version of the `demand_compatible`, which checks types without persisting them,
548         // and treats error types differently
549         // This will allow us to "probe" for other argument orders that would likely have been correct
550         let check_compatible = |provided_idx: ProvidedIdx, expected_idx: ExpectedIdx| {
551             if provided_idx.as_usize() == expected_idx.as_usize() {
552                 return compatibility_diagonal[provided_idx].clone();
553             }
554
555             let (formal_input_ty, expected_input_ty) = formal_and_expected_inputs[expected_idx];
556             // If either is an error type, we defy the usual convention and consider them to *not* be
557             // coercible. This prevents our error message heuristic from trying to pass errors into
558             // every argument.
559             if (formal_input_ty, expected_input_ty).references_error() {
560                 return Compatibility::Incompatible(None);
561             }
562
563             let (arg_ty, arg_span) = provided_arg_tys[provided_idx];
564
565             let expectation = Expectation::rvalue_hint(self, expected_input_ty);
566             let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
567             let can_coerce = self.can_coerce(arg_ty, coerced_ty);
568             if !can_coerce {
569                 return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts(
570                     ty::error::ExpectedFound::new(true, coerced_ty, arg_ty),
571                 )));
572             }
573
574             // Using probe here, since we don't want this subtyping to affect inference.
575             let subtyping_error = self.probe(|_| {
576                 self.at(&self.misc(arg_span), self.param_env).sup(formal_input_ty, coerced_ty).err()
577             });
578
579             // Same as above: if either the coerce type or the checked type is an error type,
580             // consider them *not* compatible.
581             let references_error = (coerced_ty, arg_ty).references_error();
582             match (references_error, subtyping_error) {
583                 (false, None) => Compatibility::Compatible,
584                 (_, subtyping_error) => Compatibility::Incompatible(subtyping_error),
585             }
586         };
587
588         // The algorithm here is inspired by levenshtein distance and longest common subsequence.
589         // We'll try to detect 4 different types of mistakes:
590         // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
591         // - An input is missing, which isn't satisfied by *any* of the other arguments
592         // - Some number of arguments have been provided in the wrong order
593         // - A type is straight up invalid
594
595         // First, let's find the errors
596         let (mut errors, matched_inputs) =
597             ArgMatrix::new(provided_args.len(), formal_and_expected_inputs.len(), check_compatible)
598                 .find_errors();
599
600         // First, check if we just need to wrap some arguments in a tuple.
601         if let Some((mismatch_idx, terr)) =
602             compatibility_diagonal.iter().enumerate().find_map(|(i, c)| {
603                 if let Compatibility::Incompatible(Some(terr)) = c {
604                     Some((i, *terr))
605                 } else {
606                     None
607                 }
608             })
609         {
610             // Is the first bad expected argument a tuple?
611             // Do we have as many extra provided arguments as the tuple's length?
612             // If so, we might have just forgotten to wrap some args in a tuple.
613             if let Some(ty::Tuple(tys)) =
614                 formal_and_expected_inputs.get(mismatch_idx.into()).map(|tys| tys.1.kind())
615                 // If the tuple is unit, we're not actually wrapping any arguments.
616                 && !tys.is_empty()
617                 && provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len()
618             {
619                 // Wrap up the N provided arguments starting at this position in a tuple.
620                 let provided_as_tuple = tcx.mk_tup(
621                     provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx).take(tys.len()),
622                 );
623
624                 let mut satisfied = true;
625                 // Check if the newly wrapped tuple + rest of the arguments are compatible.
626                 for ((_, expected_ty), provided_ty) in std::iter::zip(
627                     formal_and_expected_inputs.iter().skip(mismatch_idx),
628                     [provided_as_tuple].into_iter().chain(
629                         provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx + tys.len()),
630                     ),
631                 ) {
632                     if !self.can_coerce(provided_ty, *expected_ty) {
633                         satisfied = false;
634                         break;
635                     }
636                 }
637
638                 // If they're compatible, suggest wrapping in an arg, and we're done!
639                 // Take some care with spans, so we don't suggest wrapping a macro's
640                 // innards in parenthesis, for example.
641                 if satisfied
642                     && let Some((_, lo)) =
643                         provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx))
644                     && let Some((_, hi)) =
645                         provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx + tys.len() - 1))
646                 {
647                     let mut err;
648                     if tys.len() == 1 {
649                         // A tuple wrap suggestion actually occurs within,
650                         // so don't do anything special here.
651                         err = self.err_ctxt().report_and_explain_type_error(
652                             TypeTrace::types(
653                                 &self.misc(*lo),
654                                 true,
655                                 formal_and_expected_inputs[mismatch_idx.into()].1,
656                                 provided_arg_tys[mismatch_idx.into()].0,
657                             ),
658                             terr,
659                         );
660                         err.span_label(
661                             full_call_span,
662                             format!("arguments to this {} are incorrect", call_name),
663                         );
664                     } else {
665                         err = tcx.sess.struct_span_err_with_code(
666                             full_call_span,
667                             &format!(
668                                 "this {} takes {}{} but {} {} supplied",
669                                 call_name,
670                                 if c_variadic { "at least " } else { "" },
671                                 potentially_plural_count(
672                                     formal_and_expected_inputs.len(),
673                                     "argument"
674                                 ),
675                                 potentially_plural_count(provided_args.len(), "argument"),
676                                 pluralize!("was", provided_args.len())
677                             ),
678                             DiagnosticId::Error(err_code.to_owned()),
679                         );
680                         err.multipart_suggestion_verbose(
681                             "wrap these arguments in parentheses to construct a tuple",
682                             vec![
683                                 (lo.shrink_to_lo(), "(".to_string()),
684                                 (hi.shrink_to_hi(), ")".to_string()),
685                             ],
686                             Applicability::MachineApplicable,
687                         );
688                     };
689                     self.label_fn_like(
690                         &mut err,
691                         fn_def_id,
692                         callee_ty,
693                         Some(mismatch_idx),
694                         is_method,
695                     );
696                     err.emit();
697                     return;
698                 }
699             }
700         }
701
702         // Okay, so here's where it gets complicated in regards to what errors
703         // we emit and how.
704         // There are 3 different "types" of errors we might encounter.
705         //   1) Missing/extra/swapped arguments
706         //   2) Valid but incorrect arguments
707         //   3) Invalid arguments
708         //      - Currently I think this only comes up with `CyclicTy`
709         //
710         // We first need to go through, remove those from (3) and emit those
711         // as their own error, particularly since they're error code and
712         // message is special. From what I can tell, we *must* emit these
713         // here (vs somewhere prior to this function) since the arguments
714         // become invalid *because* of how they get used in the function.
715         // It is what it is.
716
717         if errors.is_empty() {
718             if cfg!(debug_assertions) {
719                 span_bug!(error_span, "expected errors from argument matrix");
720             } else {
721                 tcx.sess
722                     .struct_span_err(
723                         error_span,
724                         "argument type mismatch was detected, \
725                         but rustc had trouble determining where",
726                     )
727                     .note(
728                         "we would appreciate a bug report: \
729                         https://github.com/rust-lang/rust/issues/new",
730                     )
731                     .emit();
732             }
733             return;
734         }
735
736         errors.drain_filter(|error| {
737                 let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
738                 let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
739                 let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
740                 let cause = &self.misc(provided_span);
741                 let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
742                 if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
743                     self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
744                     return true;
745                 }
746                 false
747             });
748
749         // We're done if we found errors, but we already emitted them.
750         if errors.is_empty() {
751             return;
752         }
753
754         // Okay, now that we've emitted the special errors separately, we
755         // are only left missing/extra/swapped and mismatched arguments, both
756         // can be collated pretty easily if needed.
757
758         // Next special case: if there is only one "Incompatible" error, just emit that
759         if let [
760             Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(err))),
761         ] = &errors[..]
762         {
763             let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
764             let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
765             let cause = &self.misc(provided_arg_span);
766             let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
767             let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
768             self.emit_coerce_suggestions(
769                 &mut err,
770                 &provided_args[*provided_idx],
771                 provided_ty,
772                 Expectation::rvalue_hint(self, expected_ty)
773                     .only_has_type(self)
774                     .unwrap_or(formal_ty),
775                 None,
776                 None,
777             );
778             err.span_label(
779                 full_call_span,
780                 format!("arguments to this {} are incorrect", call_name),
781             );
782             // Call out where the function is defined
783             self.label_fn_like(
784                 &mut err,
785                 fn_def_id,
786                 callee_ty,
787                 Some(expected_idx.as_usize()),
788                 is_method,
789             );
790             err.emit();
791             return;
792         }
793
794         let mut err = if formal_and_expected_inputs.len() == provided_args.len() {
795             struct_span_err!(
796                 tcx.sess,
797                 full_call_span,
798                 E0308,
799                 "arguments to this {} are incorrect",
800                 call_name,
801             )
802         } else {
803             tcx.sess.struct_span_err_with_code(
804                 full_call_span,
805                 &format!(
806                     "this {} takes {}{} but {} {} supplied",
807                     call_name,
808                     if c_variadic { "at least " } else { "" },
809                     potentially_plural_count(formal_and_expected_inputs.len(), "argument"),
810                     potentially_plural_count(provided_args.len(), "argument"),
811                     pluralize!("was", provided_args.len())
812                 ),
813                 DiagnosticId::Error(err_code.to_owned()),
814             )
815         };
816
817         // As we encounter issues, keep track of what we want to provide for the suggestion
818         let mut labels = vec![];
819         // If there is a single error, we give a specific suggestion; otherwise, we change to
820         // "did you mean" with the suggested function call
821         enum SuggestionText {
822             None,
823             Provide(bool),
824             Remove(bool),
825             Swap,
826             Reorder,
827             DidYouMean,
828         }
829         let mut suggestion_text = SuggestionText::None;
830
831         let mut errors = errors.into_iter().peekable();
832         while let Some(error) = errors.next() {
833             match error {
834                 Error::Invalid(provided_idx, expected_idx, compatibility) => {
835                     let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
836                     let (provided_ty, provided_span) = provided_arg_tys[provided_idx];
837                     if let Compatibility::Incompatible(error) = compatibility {
838                         let cause = &self.misc(provided_span);
839                         let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
840                         if let Some(e) = error {
841                             self.err_ctxt().note_type_err(
842                                 &mut err,
843                                 &trace.cause,
844                                 None,
845                                 Some(trace.values),
846                                 e,
847                                 false,
848                                 true,
849                             );
850                         }
851                     }
852
853                     self.emit_coerce_suggestions(
854                         &mut err,
855                         &provided_args[provided_idx],
856                         provided_ty,
857                         Expectation::rvalue_hint(self, expected_ty)
858                             .only_has_type(self)
859                             .unwrap_or(formal_ty),
860                         None,
861                         None,
862                     );
863                 }
864                 Error::Extra(arg_idx) => {
865                     let (provided_ty, provided_span) = provided_arg_tys[arg_idx];
866                     let provided_ty_name = if !has_error_or_infer([provided_ty]) {
867                         // FIXME: not suggestable, use something else
868                         format!(" of type `{}`", provided_ty)
869                     } else {
870                         "".to_string()
871                     };
872                     labels
873                         .push((provided_span, format!("argument{} unexpected", provided_ty_name)));
874                     suggestion_text = match suggestion_text {
875                         SuggestionText::None => SuggestionText::Remove(false),
876                         SuggestionText::Remove(_) => SuggestionText::Remove(true),
877                         _ => SuggestionText::DidYouMean,
878                     };
879                 }
880                 Error::Missing(expected_idx) => {
881                     // If there are multiple missing arguments adjacent to each other,
882                     // then we can provide a single error.
883
884                     let mut missing_idxs = vec![expected_idx];
885                     while let Some(e) = errors.next_if(|e| {
886                         matches!(e, Error::Missing(next_expected_idx)
887                             if *next_expected_idx == *missing_idxs.last().unwrap() + 1)
888                     }) {
889                         match e {
890                             Error::Missing(expected_idx) => missing_idxs.push(expected_idx),
891                             _ => unreachable!(),
892                         }
893                     }
894
895                     // NOTE: Because we might be re-arranging arguments, might have extra
896                     // arguments, etc. it's hard to *really* know where we should provide
897                     // this error label, so as a heuristic, we point to the provided arg, or
898                     // to the call if the missing inputs pass the provided args.
899                     match &missing_idxs[..] {
900                         &[expected_idx] => {
901                             let (_, input_ty) = formal_and_expected_inputs[expected_idx];
902                             let span = if let Some((_, arg_span)) =
903                                 provided_arg_tys.get(expected_idx.to_provided_idx())
904                             {
905                                 *arg_span
906                             } else {
907                                 args_span
908                             };
909                             let rendered = if !has_error_or_infer([input_ty]) {
910                                 format!(" of type `{}`", input_ty)
911                             } else {
912                                 "".to_string()
913                             };
914                             labels.push((span, format!("an argument{} is missing", rendered)));
915                             suggestion_text = match suggestion_text {
916                                 SuggestionText::None => SuggestionText::Provide(false),
917                                 SuggestionText::Provide(_) => SuggestionText::Provide(true),
918                                 _ => SuggestionText::DidYouMean,
919                             };
920                         }
921                         &[first_idx, second_idx] => {
922                             let (_, first_expected_ty) = formal_and_expected_inputs[first_idx];
923                             let (_, second_expected_ty) = formal_and_expected_inputs[second_idx];
924                             let span = if let (Some((_, first_span)), Some((_, second_span))) = (
925                                 provided_arg_tys.get(first_idx.to_provided_idx()),
926                                 provided_arg_tys.get(second_idx.to_provided_idx()),
927                             ) {
928                                 first_span.to(*second_span)
929                             } else {
930                                 args_span
931                             };
932                             let rendered =
933                                 if !has_error_or_infer([first_expected_ty, second_expected_ty]) {
934                                     format!(
935                                         " of type `{}` and `{}`",
936                                         first_expected_ty, second_expected_ty
937                                     )
938                                 } else {
939                                     "".to_string()
940                                 };
941                             labels.push((span, format!("two arguments{} are missing", rendered)));
942                             suggestion_text = match suggestion_text {
943                                 SuggestionText::None | SuggestionText::Provide(_) => {
944                                     SuggestionText::Provide(true)
945                                 }
946                                 _ => SuggestionText::DidYouMean,
947                             };
948                         }
949                         &[first_idx, second_idx, third_idx] => {
950                             let (_, first_expected_ty) = formal_and_expected_inputs[first_idx];
951                             let (_, second_expected_ty) = formal_and_expected_inputs[second_idx];
952                             let (_, third_expected_ty) = formal_and_expected_inputs[third_idx];
953                             let span = if let (Some((_, first_span)), Some((_, third_span))) = (
954                                 provided_arg_tys.get(first_idx.to_provided_idx()),
955                                 provided_arg_tys.get(third_idx.to_provided_idx()),
956                             ) {
957                                 first_span.to(*third_span)
958                             } else {
959                                 args_span
960                             };
961                             let rendered = if !has_error_or_infer([
962                                 first_expected_ty,
963                                 second_expected_ty,
964                                 third_expected_ty,
965                             ]) {
966                                 format!(
967                                     " of type `{}`, `{}`, and `{}`",
968                                     first_expected_ty, second_expected_ty, third_expected_ty
969                                 )
970                             } else {
971                                 "".to_string()
972                             };
973                             labels.push((span, format!("three arguments{} are missing", rendered)));
974                             suggestion_text = match suggestion_text {
975                                 SuggestionText::None | SuggestionText::Provide(_) => {
976                                     SuggestionText::Provide(true)
977                                 }
978                                 _ => SuggestionText::DidYouMean,
979                             };
980                         }
981                         missing_idxs => {
982                             let first_idx = *missing_idxs.first().unwrap();
983                             let last_idx = *missing_idxs.last().unwrap();
984                             // NOTE: Because we might be re-arranging arguments, might have extra arguments, etc.
985                             // It's hard to *really* know where we should provide this error label, so this is a
986                             // decent heuristic
987                             let span = if let (Some((_, first_span)), Some((_, last_span))) = (
988                                 provided_arg_tys.get(first_idx.to_provided_idx()),
989                                 provided_arg_tys.get(last_idx.to_provided_idx()),
990                             ) {
991                                 first_span.to(*last_span)
992                             } else {
993                                 args_span
994                             };
995                             labels.push((span, format!("multiple arguments are missing")));
996                             suggestion_text = match suggestion_text {
997                                 SuggestionText::None | SuggestionText::Provide(_) => {
998                                     SuggestionText::Provide(true)
999                                 }
1000                                 _ => SuggestionText::DidYouMean,
1001                             };
1002                         }
1003                     }
1004                 }
1005                 Error::Swap(
1006                     first_provided_idx,
1007                     second_provided_idx,
1008                     first_expected_idx,
1009                     second_expected_idx,
1010                 ) => {
1011                     let (first_provided_ty, first_span) = provided_arg_tys[first_provided_idx];
1012                     let (_, first_expected_ty) = formal_and_expected_inputs[first_expected_idx];
1013                     let first_provided_ty_name = if !has_error_or_infer([first_provided_ty]) {
1014                         format!(", found `{}`", first_provided_ty)
1015                     } else {
1016                         String::new()
1017                     };
1018                     labels.push((
1019                         first_span,
1020                         format!("expected `{}`{}", first_expected_ty, first_provided_ty_name),
1021                     ));
1022
1023                     let (second_provided_ty, second_span) = provided_arg_tys[second_provided_idx];
1024                     let (_, second_expected_ty) = formal_and_expected_inputs[second_expected_idx];
1025                     let second_provided_ty_name = if !has_error_or_infer([second_provided_ty]) {
1026                         format!(", found `{}`", second_provided_ty)
1027                     } else {
1028                         String::new()
1029                     };
1030                     labels.push((
1031                         second_span,
1032                         format!("expected `{}`{}", second_expected_ty, second_provided_ty_name),
1033                     ));
1034
1035                     suggestion_text = match suggestion_text {
1036                         SuggestionText::None => SuggestionText::Swap,
1037                         _ => SuggestionText::DidYouMean,
1038                     };
1039                 }
1040                 Error::Permutation(args) => {
1041                     for (dst_arg, dest_input) in args {
1042                         let (_, expected_ty) = formal_and_expected_inputs[dst_arg];
1043                         let (provided_ty, provided_span) = provided_arg_tys[dest_input];
1044                         let provided_ty_name = if !has_error_or_infer([provided_ty]) {
1045                             format!(", found `{}`", provided_ty)
1046                         } else {
1047                             String::new()
1048                         };
1049                         labels.push((
1050                             provided_span,
1051                             format!("expected `{}`{}", expected_ty, provided_ty_name),
1052                         ));
1053                     }
1054
1055                     suggestion_text = match suggestion_text {
1056                         SuggestionText::None => SuggestionText::Reorder,
1057                         _ => SuggestionText::DidYouMean,
1058                     };
1059                 }
1060             }
1061         }
1062
1063         // If we have less than 5 things to say, it would be useful to call out exactly what's wrong
1064         if labels.len() <= 5 {
1065             for (span, label) in labels {
1066                 err.span_label(span, label);
1067             }
1068         }
1069
1070         // Call out where the function is defined
1071         self.label_fn_like(&mut err, fn_def_id, callee_ty, None, is_method);
1072
1073         // And add a suggestion block for all of the parameters
1074         let suggestion_text = match suggestion_text {
1075             SuggestionText::None => None,
1076             SuggestionText::Provide(plural) => {
1077                 Some(format!("provide the argument{}", if plural { "s" } else { "" }))
1078             }
1079             SuggestionText::Remove(plural) => {
1080                 Some(format!("remove the extra argument{}", if plural { "s" } else { "" }))
1081             }
1082             SuggestionText::Swap => Some("swap these arguments".to_string()),
1083             SuggestionText::Reorder => Some("reorder these arguments".to_string()),
1084             SuggestionText::DidYouMean => Some("did you mean".to_string()),
1085         };
1086         if let Some(suggestion_text) = suggestion_text {
1087             let source_map = self.sess().source_map();
1088             let (mut suggestion, suggestion_span) =
1089                 if let Some(call_span) = full_call_span.find_ancestor_inside(error_span) {
1090                     ("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
1091                 } else {
1092                     (
1093                         format!(
1094                             "{}(",
1095                             source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
1096                                 fn_def_id.map_or("".to_string(), |fn_def_id| {
1097                                     tcx.item_name(fn_def_id).to_string()
1098                                 })
1099                             })
1100                         ),
1101                         error_span,
1102                     )
1103                 };
1104             let mut needs_comma = false;
1105             for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
1106                 if needs_comma {
1107                     suggestion += ", ";
1108                 } else {
1109                     needs_comma = true;
1110                 }
1111                 let suggestion_text = if let Some(provided_idx) = provided_idx
1112                     && let (_, provided_span) = provided_arg_tys[*provided_idx]
1113                     && let Ok(arg_text) = source_map.span_to_snippet(provided_span)
1114                 {
1115                     arg_text
1116                 } else {
1117                     // Propose a placeholder of the correct type
1118                     let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
1119                     if expected_ty.is_unit() {
1120                         "()".to_string()
1121                     } else if expected_ty.is_suggestable(tcx, false) {
1122                         format!("/* {} */", expected_ty)
1123                     } else {
1124                         "/* value */".to_string()
1125                     }
1126                 };
1127                 suggestion += &suggestion_text;
1128             }
1129             suggestion += ")";
1130             err.span_suggestion_verbose(
1131                 suggestion_span,
1132                 &suggestion_text,
1133                 suggestion,
1134                 Applicability::HasPlaceholders,
1135             );
1136         }
1137
1138         err.emit();
1139     }
1140
1141     // AST fragment checking
1142     pub(in super::super) fn check_lit(
1143         &self,
1144         lit: &hir::Lit,
1145         expected: Expectation<'tcx>,
1146     ) -> Ty<'tcx> {
1147         let tcx = self.tcx;
1148
1149         match lit.node {
1150             ast::LitKind::Str(..) => tcx.mk_static_str(),
1151             ast::LitKind::ByteStr(ref v) => {
1152                 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
1153             }
1154             ast::LitKind::Byte(_) => tcx.types.u8,
1155             ast::LitKind::Char(_) => tcx.types.char,
1156             ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(ty::int_ty(t)),
1157             ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(ty::uint_ty(t)),
1158             ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
1159                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
1160                     ty::Int(_) | ty::Uint(_) => Some(ty),
1161                     ty::Char => Some(tcx.types.u8),
1162                     ty::RawPtr(..) => Some(tcx.types.usize),
1163                     ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
1164                     _ => None,
1165                 });
1166                 opt_ty.unwrap_or_else(|| self.next_int_var())
1167             }
1168             ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => {
1169                 tcx.mk_mach_float(ty::float_ty(t))
1170             }
1171             ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
1172                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
1173                     ty::Float(_) => Some(ty),
1174                     _ => None,
1175                 });
1176                 opt_ty.unwrap_or_else(|| self.next_float_var())
1177             }
1178             ast::LitKind::Bool(_) => tcx.types.bool,
1179             ast::LitKind::Err => tcx.ty_error(),
1180         }
1181     }
1182
1183     pub fn check_struct_path(
1184         &self,
1185         qpath: &QPath<'_>,
1186         hir_id: hir::HirId,
1187     ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
1188         let path_span = qpath.span();
1189         let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
1190         let variant = match def {
1191             Res::Err => {
1192                 self.set_tainted_by_errors();
1193                 return None;
1194             }
1195             Res::Def(DefKind::Variant, _) => match ty.kind() {
1196                 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did(), substs)),
1197                 _ => bug!("unexpected type: {:?}", ty),
1198             },
1199             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
1200             | Res::SelfTyParam { .. }
1201             | Res::SelfTyAlias { .. } => match ty.kind() {
1202                 ty::Adt(adt, substs) if !adt.is_enum() => {
1203                     Some((adt.non_enum_variant(), adt.did(), substs))
1204                 }
1205                 _ => None,
1206             },
1207             _ => bug!("unexpected definition: {:?}", def),
1208         };
1209
1210         if let Some((variant, did, substs)) = variant {
1211             debug!("check_struct_path: did={:?} substs={:?}", did, substs);
1212             self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
1213
1214             // Check bounds on type arguments used in the path.
1215             self.add_required_obligations_for_hir(path_span, did, substs, hir_id);
1216
1217             Some((variant, ty))
1218         } else {
1219             match ty.kind() {
1220                 ty::Error(_) => {
1221                     // E0071 might be caused by a spelling error, which will have
1222                     // already caused an error message and probably a suggestion
1223                     // elsewhere. Refrain from emitting more unhelpful errors here
1224                     // (issue #88844).
1225                 }
1226                 _ => {
1227                     struct_span_err!(
1228                         self.tcx.sess,
1229                         path_span,
1230                         E0071,
1231                         "expected struct, variant or union type, found {}",
1232                         ty.sort_string(self.tcx)
1233                     )
1234                     .span_label(path_span, "not a struct")
1235                     .emit();
1236                 }
1237             }
1238             None
1239         }
1240     }
1241
1242     pub fn check_decl_initializer(
1243         &self,
1244         hir_id: hir::HirId,
1245         pat: &'tcx hir::Pat<'tcx>,
1246         init: &'tcx hir::Expr<'tcx>,
1247     ) -> Ty<'tcx> {
1248         // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
1249         // for #42640 (default match binding modes).
1250         //
1251         // See #44848.
1252         let ref_bindings = pat.contains_explicit_ref_binding();
1253
1254         let local_ty = self.local_ty(init.span, hir_id).revealed_ty;
1255         if let Some(m) = ref_bindings {
1256             // Somewhat subtle: if we have a `ref` binding in the pattern,
1257             // we want to avoid introducing coercions for the RHS. This is
1258             // both because it helps preserve sanity and, in the case of
1259             // ref mut, for soundness (issue #23116). In particular, in
1260             // the latter case, we need to be clear that the type of the
1261             // referent for the reference that results is *equal to* the
1262             // type of the place it is referencing, and not some
1263             // supertype thereof.
1264             let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
1265             self.demand_eqtype(init.span, local_ty, init_ty);
1266             init_ty
1267         } else {
1268             self.check_expr_coercable_to_type(init, local_ty, None)
1269         }
1270     }
1271
1272     pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
1273         // Determine and write the type which we'll check the pattern against.
1274         let decl_ty = self.local_ty(decl.span, decl.hir_id).decl_ty;
1275         self.write_ty(decl.hir_id, decl_ty);
1276
1277         // Type check the initializer.
1278         if let Some(ref init) = decl.init {
1279             let init_ty = self.check_decl_initializer(decl.hir_id, decl.pat, &init);
1280             self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, init_ty);
1281         }
1282
1283         // Does the expected pattern type originate from an expression and what is the span?
1284         let (origin_expr, ty_span) = match (decl.ty, decl.init) {
1285             (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
1286             (_, Some(init)) => {
1287                 (true, Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span)))
1288             } // No explicit type; so use the scrutinee.
1289             _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
1290         };
1291
1292         // Type check the pattern. Override if necessary to avoid knock-on errors.
1293         self.check_pat_top(&decl.pat, decl_ty, ty_span, origin_expr);
1294         let pat_ty = self.node_ty(decl.pat.hir_id);
1295         self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, pat_ty);
1296
1297         if let Some(blk) = decl.els {
1298             let previous_diverges = self.diverges.get();
1299             let else_ty = self.check_block_with_expected(blk, NoExpectation);
1300             let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
1301             if let Some(mut err) =
1302                 self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty)
1303             {
1304                 err.emit();
1305             }
1306             self.diverges.set(previous_diverges);
1307         }
1308     }
1309
1310     /// Type check a `let` statement.
1311     pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
1312         self.check_decl(local.into());
1313     }
1314
1315     pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>, is_last: bool) {
1316         // Don't do all the complex logic below for `DeclItem`.
1317         match stmt.kind {
1318             hir::StmtKind::Item(..) => return,
1319             hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
1320         }
1321
1322         self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
1323
1324         // Hide the outer diverging and `has_errors` flags.
1325         let old_diverges = self.diverges.replace(Diverges::Maybe);
1326         let old_has_errors = self.has_errors.replace(false);
1327
1328         match stmt.kind {
1329             hir::StmtKind::Local(l) => {
1330                 self.check_decl_local(l);
1331             }
1332             // Ignore for now.
1333             hir::StmtKind::Item(_) => {}
1334             hir::StmtKind::Expr(ref expr) => {
1335                 // Check with expected type of `()`.
1336                 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
1337                     if expr.can_have_side_effects() {
1338                         self.suggest_semicolon_at_end(expr.span, err);
1339                     }
1340                 });
1341             }
1342             hir::StmtKind::Semi(ref expr) => {
1343                 // All of this is equivalent to calling `check_expr`, but it is inlined out here
1344                 // in order to capture the fact that this `match` is the last statement in its
1345                 // function. This is done for better suggestions to remove the `;`.
1346                 let expectation = match expr.kind {
1347                     hir::ExprKind::Match(..) if is_last => IsLast(stmt.span),
1348                     _ => NoExpectation,
1349                 };
1350                 self.check_expr_with_expectation(expr, expectation);
1351             }
1352         }
1353
1354         // Combine the diverging and `has_error` flags.
1355         self.diverges.set(self.diverges.get() | old_diverges);
1356         self.has_errors.set(self.has_errors.get() | old_has_errors);
1357     }
1358
1359     pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
1360         let unit = self.tcx.mk_unit();
1361         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
1362
1363         // if the block produces a `!` value, that can always be
1364         // (effectively) coerced to unit.
1365         if !ty.is_never() {
1366             self.demand_suptype(blk.span, unit, ty);
1367         }
1368     }
1369
1370     pub(in super::super) fn check_block_with_expected(
1371         &self,
1372         blk: &'tcx hir::Block<'tcx>,
1373         expected: Expectation<'tcx>,
1374     ) -> Ty<'tcx> {
1375         let prev = self.ps.replace(self.ps.get().recurse(blk));
1376
1377         // In some cases, blocks have just one exit, but other blocks
1378         // can be targeted by multiple breaks. This can happen both
1379         // with labeled blocks as well as when we desugar
1380         // a `try { ... }` expression.
1381         //
1382         // Example 1:
1383         //
1384         //    'a: { if true { break 'a Err(()); } Ok(()) }
1385         //
1386         // Here we would wind up with two coercions, one from
1387         // `Err(())` and the other from the tail expression
1388         // `Ok(())`. If the tail expression is omitted, that's a
1389         // "forced unit" -- unless the block diverges, in which
1390         // case we can ignore the tail expression (e.g., `'a: {
1391         // break 'a 22; }` would not force the type of the block
1392         // to be `()`).
1393         let tail_expr = blk.expr.as_ref();
1394         let coerce_to_ty = expected.coercion_target_type(self, blk.span);
1395         let coerce = if blk.targeted_by_break {
1396             CoerceMany::new(coerce_to_ty)
1397         } else {
1398             let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
1399                 Some(e) => slice::from_ref(e),
1400                 None => &[],
1401             };
1402             CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
1403         };
1404
1405         let prev_diverges = self.diverges.get();
1406         let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
1407
1408         let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
1409             for (pos, s) in blk.stmts.iter().enumerate() {
1410                 self.check_stmt(s, blk.stmts.len() - 1 == pos);
1411             }
1412
1413             // check the tail expression **without** holding the
1414             // `enclosing_breakables` lock below.
1415             let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
1416
1417             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
1418             let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
1419             let coerce = ctxt.coerce.as_mut().unwrap();
1420             if let Some(tail_expr_ty) = tail_expr_ty {
1421                 let tail_expr = tail_expr.unwrap();
1422                 let span = self.get_expr_coercion_span(tail_expr);
1423                 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
1424                 let ty_for_diagnostic = coerce.merged_ty();
1425                 // We use coerce_inner here because we want to augment the error
1426                 // suggesting to wrap the block in square brackets if it might've
1427                 // been mistaken array syntax
1428                 coerce.coerce_inner(
1429                     self,
1430                     &cause,
1431                     Some(tail_expr),
1432                     tail_expr_ty,
1433                     Some(&mut |diag: &mut Diagnostic| {
1434                         self.suggest_block_to_brackets(diag, blk, tail_expr_ty, ty_for_diagnostic);
1435                     }),
1436                     false,
1437                 );
1438             } else {
1439                 // Subtle: if there is no explicit tail expression,
1440                 // that is typically equivalent to a tail expression
1441                 // of `()` -- except if the block diverges. In that
1442                 // case, there is no value supplied from the tail
1443                 // expression (assuming there are no other breaks,
1444                 // this implies that the type of the block will be
1445                 // `!`).
1446                 //
1447                 // #41425 -- label the implicit `()` as being the
1448                 // "found type" here, rather than the "expected type".
1449                 if !self.diverges.get().is_always() {
1450                     // #50009 -- Do not point at the entire fn block span, point at the return type
1451                     // span, as it is the cause of the requirement, and
1452                     // `consider_hint_about_removing_semicolon` will point at the last expression
1453                     // if it were a relevant part of the error. This improves usability in editors
1454                     // that highlight errors inline.
1455                     let mut sp = blk.span;
1456                     let mut fn_span = None;
1457                     if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
1458                         let ret_sp = decl.output.span();
1459                         if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
1460                             // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
1461                             // output would otherwise be incorrect and even misleading. Make sure
1462                             // the span we're aiming at correspond to a `fn` body.
1463                             if block_sp == blk.span {
1464                                 sp = ret_sp;
1465                                 fn_span = Some(ident.span);
1466                             }
1467                         }
1468                     }
1469                     coerce.coerce_forced_unit(
1470                         self,
1471                         &self.misc(sp),
1472                         &mut |err| {
1473                             if let Some(expected_ty) = expected.only_has_type(self) {
1474                                 if !self.consider_removing_semicolon(blk, expected_ty, err) {
1475                                     self.err_ctxt().consider_returning_binding(
1476                                         blk,
1477                                         expected_ty,
1478                                         err,
1479                                     );
1480                                 }
1481                                 if expected_ty == self.tcx.types.bool {
1482                                     // If this is caused by a missing `let` in a `while let`,
1483                                     // silence this redundant error, as we already emit E0070.
1484
1485                                     // Our block must be a `assign desugar local; assignment`
1486                                     if let Some(hir::Node::Block(hir::Block {
1487                                         stmts:
1488                                             [
1489                                                 hir::Stmt {
1490                                                     kind:
1491                                                         hir::StmtKind::Local(hir::Local {
1492                                                             source:
1493                                                                 hir::LocalSource::AssignDesugar(_),
1494                                                             ..
1495                                                         }),
1496                                                     ..
1497                                                 },
1498                                                 hir::Stmt {
1499                                                     kind:
1500                                                         hir::StmtKind::Expr(hir::Expr {
1501                                                             kind: hir::ExprKind::Assign(..),
1502                                                             ..
1503                                                         }),
1504                                                     ..
1505                                                 },
1506                                             ],
1507                                         ..
1508                                     })) = self.tcx.hir().find(blk.hir_id)
1509                                     {
1510                                         self.comes_from_while_condition(blk.hir_id, |_| {
1511                                             err.downgrade_to_delayed_bug();
1512                                         })
1513                                     }
1514                                 }
1515                             }
1516                             if let Some(fn_span) = fn_span {
1517                                 err.span_label(
1518                                     fn_span,
1519                                     "implicitly returns `()` as its body has no tail or `return` \
1520                                      expression",
1521                                 );
1522                             }
1523                         },
1524                         false,
1525                     );
1526                 }
1527             }
1528         });
1529
1530         if ctxt.may_break {
1531             // If we can break from the block, then the block's exit is always reachable
1532             // (... as long as the entry is reachable) - regardless of the tail of the block.
1533             self.diverges.set(prev_diverges);
1534         }
1535
1536         let mut ty = ctxt.coerce.unwrap().complete(self);
1537
1538         if self.has_errors.get() || ty.references_error() {
1539             ty = self.tcx.ty_error()
1540         }
1541
1542         self.write_ty(blk.hir_id, ty);
1543
1544         self.ps.set(prev);
1545         ty
1546     }
1547
1548     fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
1549         let node = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(id).def_id);
1550         match node {
1551             Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
1552             | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
1553                 let body = self.tcx.hir().body(body_id);
1554                 if let ExprKind::Block(block, _) = &body.value.kind {
1555                     return Some(block.span);
1556                 }
1557             }
1558             _ => {}
1559         }
1560         None
1561     }
1562
1563     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
1564     fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
1565         let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
1566         self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
1567     }
1568
1569     /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
1570     /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
1571     /// when given code like the following:
1572     /// ```text
1573     /// if false { return 0i32; } else { 1u32 }
1574     /// //                               ^^^^ point at this instead of the whole `if` expression
1575     /// ```
1576     fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
1577         let check_in_progress = |elem: &hir::Expr<'_>| {
1578             self.typeck_results.borrow().node_type_opt(elem.hir_id).filter(|ty| !ty.is_never()).map(
1579                 |_| match elem.kind {
1580                     // Point at the tail expression when possible.
1581                     hir::ExprKind::Block(block, _) => block.expr.map_or(block.span, |e| e.span),
1582                     _ => elem.span,
1583                 },
1584             )
1585         };
1586
1587         if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
1588             if let Some(rslt) = check_in_progress(el) {
1589                 return rslt;
1590             }
1591         }
1592
1593         if let hir::ExprKind::Match(_, arms, _) = expr.kind {
1594             let mut iter = arms.iter().filter_map(|arm| check_in_progress(arm.body));
1595             if let Some(span) = iter.next() {
1596                 if iter.next().is_none() {
1597                     return span;
1598                 }
1599             }
1600         }
1601
1602         expr.span
1603     }
1604
1605     fn overwrite_local_ty_if_err(
1606         &self,
1607         hir_id: hir::HirId,
1608         pat: &'tcx hir::Pat<'tcx>,
1609         decl_ty: Ty<'tcx>,
1610         ty: Ty<'tcx>,
1611     ) {
1612         if ty.references_error() {
1613             // Override the types everywhere with `err()` to avoid knock on errors.
1614             self.write_ty(hir_id, ty);
1615             self.write_ty(pat.hir_id, ty);
1616             let local_ty = LocalTy { decl_ty, revealed_ty: ty };
1617             self.locals.borrow_mut().insert(hir_id, local_ty);
1618             self.locals.borrow_mut().insert(pat.hir_id, local_ty);
1619         }
1620     }
1621
1622     // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
1623     // The newly resolved definition is written into `type_dependent_defs`.
1624     fn finish_resolving_struct_path(
1625         &self,
1626         qpath: &QPath<'_>,
1627         path_span: Span,
1628         hir_id: hir::HirId,
1629     ) -> (Res, Ty<'tcx>) {
1630         match *qpath {
1631             QPath::Resolved(ref maybe_qself, ref path) => {
1632                 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
1633                 let ty = <dyn AstConv<'_>>::res_to_ty(self, self_ty, path, true);
1634                 (path.res, ty)
1635             }
1636             QPath::TypeRelative(ref qself, ref segment) => {
1637                 let ty = self.to_ty(qself);
1638
1639                 let result = <dyn AstConv<'_>>::associated_path_to_ty(
1640                     self, hir_id, path_span, ty, qself, segment, true,
1641                 );
1642                 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
1643                 let result = result.map(|(_, kind, def_id)| (kind, def_id));
1644
1645                 // Write back the new resolution.
1646                 self.write_resolution(hir_id, result);
1647
1648                 (result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
1649             }
1650             QPath::LangItem(lang_item, span, id) => {
1651                 self.resolve_lang_item_path(lang_item, span, hir_id, id)
1652             }
1653         }
1654     }
1655
1656     /// Given a vector of fulfillment errors, try to adjust the spans of the
1657     /// errors to more accurately point at the cause of the failure.
1658     ///
1659     /// This applies to calls, methods, and struct expressions. This will also
1660     /// try to deduplicate errors that are due to the same cause but might
1661     /// have been created with different [`ObligationCause`][traits::ObligationCause]s.
1662     pub(super) fn adjust_fulfillment_errors_for_expr_obligation(
1663         &self,
1664         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1665     ) {
1666         // Store a mapping from `(Span, Predicate) -> ObligationCause`, so that
1667         // other errors that have the same span and predicate can also get fixed,
1668         // even if their `ObligationCauseCode` isn't an `Expr*Obligation` kind.
1669         // This is important since if we adjust one span but not the other, then
1670         // we will have "duplicated" the error on the UI side.
1671         let mut remap_cause = FxHashSet::default();
1672         let mut not_adjusted = vec![];
1673
1674         for error in errors {
1675             let before_span = error.obligation.cause.span;
1676             if self.adjust_fulfillment_error_for_expr_obligation(error)
1677                 || before_span != error.obligation.cause.span
1678             {
1679                 // Store both the predicate and the predicate *without constness*
1680                 // since sometimes we instantiate and check both of these in a
1681                 // method call, for example.
1682                 remap_cause.insert((
1683                     before_span,
1684                     error.obligation.predicate,
1685                     error.obligation.cause.clone(),
1686                 ));
1687                 remap_cause.insert((
1688                     before_span,
1689                     error.obligation.predicate.without_const(self.tcx),
1690                     error.obligation.cause.clone(),
1691                 ));
1692             } else {
1693                 // If it failed to be adjusted once around, it may be adjusted
1694                 // via the "remap cause" mapping the second time...
1695                 not_adjusted.push(error);
1696             }
1697         }
1698
1699         for error in not_adjusted {
1700             for (span, predicate, cause) in &remap_cause {
1701                 if *predicate == error.obligation.predicate
1702                     && span.contains(error.obligation.cause.span)
1703                 {
1704                     error.obligation.cause = cause.clone();
1705                     continue;
1706                 }
1707             }
1708         }
1709     }
1710
1711     fn adjust_fulfillment_error_for_expr_obligation(
1712         &self,
1713         error: &mut traits::FulfillmentError<'tcx>,
1714     ) -> bool {
1715         let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx))
1716             = *error.obligation.cause.code().peel_derives() else { return false; };
1717         let hir = self.tcx.hir();
1718         let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; };
1719
1720         // Skip over mentioning async lang item
1721         if Some(def_id) == self.tcx.lang_items().from_generator_fn()
1722             && error.obligation.cause.span.desugaring_kind()
1723                 == Some(rustc_span::DesugaringKind::Async)
1724         {
1725             return false;
1726         }
1727
1728         let Some(unsubstituted_pred) =
1729             self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx)
1730             else { return false; };
1731
1732         let generics = self.tcx.generics_of(def_id);
1733         let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
1734             ty::PredicateKind::Trait(pred) => pred.trait_ref.substs,
1735             ty::PredicateKind::Projection(pred) => pred.projection_ty.substs,
1736             _ => ty::List::empty(),
1737         };
1738
1739         let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| {
1740             predicate_substs.types().find_map(|ty| {
1741                 ty.walk().find_map(|arg| {
1742                     if let ty::GenericArgKind::Type(ty) = arg.unpack()
1743                         && let ty::Param(param_ty) = ty.kind()
1744                         && matches(param_ty)
1745                     {
1746                         Some(arg)
1747                     } else {
1748                         None
1749                     }
1750                 })
1751             })
1752         };
1753
1754         // Prefer generics that are local to the fn item, since these are likely
1755         // to be the cause of the unsatisfied predicate.
1756         let mut param_to_point_at = find_param_matching(&|param_ty| {
1757             self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id
1758         });
1759         // Fall back to generic that isn't local to the fn item. This will come
1760         // from a trait or impl, for example.
1761         let mut fallback_param_to_point_at = find_param_matching(&|param_ty| {
1762             self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id
1763                 && param_ty.name != rustc_span::symbol::kw::SelfUpper
1764         });
1765         // Finally, the `Self` parameter is possibly the reason that the predicate
1766         // is unsatisfied. This is less likely to be true for methods, because
1767         // method probe means that we already kinda check that the predicates due
1768         // to the `Self` type are true.
1769         let mut self_param_to_point_at =
1770             find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper);
1771
1772         // Finally, for ambiguity-related errors, we actually want to look
1773         // for a parameter that is the source of the inference type left
1774         // over in this predicate.
1775         if let traits::FulfillmentErrorCode::CodeAmbiguity = error.code {
1776             fallback_param_to_point_at = None;
1777             self_param_to_point_at = None;
1778             param_to_point_at =
1779                 self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
1780         }
1781
1782         if self.closure_span_overlaps_error(error, expr.span) {
1783             return false;
1784         }
1785
1786         match &expr.kind {
1787             hir::ExprKind::Path(qpath) => {
1788                 if let hir::Node::Expr(hir::Expr {
1789                     kind: hir::ExprKind::Call(callee, args),
1790                     hir_id: call_hir_id,
1791                     span: call_span,
1792                     ..
1793                 }) = hir.get(hir.get_parent_node(expr.hir_id))
1794                     && callee.hir_id == expr.hir_id
1795                 {
1796                     if self.closure_span_overlaps_error(error, *call_span) {
1797                         return false;
1798                     }
1799
1800                     for param in
1801                         [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
1802                         .into_iter()
1803                         .flatten()
1804                     {
1805                         if self.point_at_arg_if_possible(
1806                                 error,
1807                                 def_id,
1808                                 param,
1809                                 *call_hir_id,
1810                                 callee.span,
1811                                 None,
1812                                 args,
1813                             )
1814                         {
1815                             return true;
1816                         }
1817                     }
1818                 }
1819                 // Notably, we only point to params that are local to the
1820                 // item we're checking, since those are the ones we are able
1821                 // to look in the final `hir::PathSegment` for. Everything else
1822                 // would require a deeper search into the `qpath` than I think
1823                 // is worthwhile.
1824                 if let Some(param_to_point_at) = param_to_point_at
1825                     && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
1826                 {
1827                     return true;
1828                 }
1829             }
1830             hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
1831                 for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
1832                     .into_iter()
1833                     .flatten()
1834                 {
1835                     if self.point_at_arg_if_possible(
1836                         error,
1837                         def_id,
1838                         param,
1839                         hir_id,
1840                         segment.ident.span,
1841                         Some(receiver),
1842                         args,
1843                     ) {
1844                         return true;
1845                     }
1846                 }
1847                 if let Some(param_to_point_at) = param_to_point_at
1848                     && self.point_at_generic_if_possible(error, def_id, param_to_point_at, segment)
1849                 {
1850                     return true;
1851                 }
1852             }
1853             hir::ExprKind::Struct(qpath, fields, ..) => {
1854                 if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
1855                     self.typeck_results.borrow().qpath_res(qpath, hir_id)
1856                 {
1857                     for param in
1858                         [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
1859                     {
1860                         if let Some(param) = param
1861                             && self.point_at_field_if_possible(
1862                                 error,
1863                                 def_id,
1864                                 param,
1865                                 variant_def_id,
1866                                 fields,
1867                             )
1868                         {
1869                             return true;
1870                         }
1871                     }
1872                 }
1873                 if let Some(param_to_point_at) = param_to_point_at
1874                     && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
1875                 {
1876                     return true;
1877                 }
1878             }
1879             _ => {}
1880         }
1881
1882         false
1883     }
1884
1885     fn closure_span_overlaps_error(
1886         &self,
1887         error: &traits::FulfillmentError<'tcx>,
1888         span: Span,
1889     ) -> bool {
1890         if let traits::FulfillmentErrorCode::CodeSelectionError(
1891             traits::SelectionError::OutputTypeParameterMismatch(_, expected, _),
1892         ) = error.code
1893             && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind()
1894             && span.overlaps(self.tcx.def_span(*def_id))
1895         {
1896             true
1897         } else {
1898             false
1899         }
1900     }
1901
1902     fn point_at_arg_if_possible(
1903         &self,
1904         error: &mut traits::FulfillmentError<'tcx>,
1905         def_id: DefId,
1906         param_to_point_at: ty::GenericArg<'tcx>,
1907         call_hir_id: hir::HirId,
1908         callee_span: Span,
1909         receiver: Option<&'tcx hir::Expr<'tcx>>,
1910         args: &'tcx [hir::Expr<'tcx>],
1911     ) -> bool {
1912         let sig = self.tcx.fn_sig(def_id).skip_binder();
1913         let args_referencing_param: Vec<_> = sig
1914             .inputs()
1915             .iter()
1916             .enumerate()
1917             .filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at))
1918             .collect();
1919         // If there's one field that references the given generic, great!
1920         if let [(idx, _)] = args_referencing_param.as_slice()
1921             && let Some(arg) = receiver
1922                 .map_or(args.get(*idx), |rcvr| if *idx == 0 { Some(rcvr) } else { args.get(*idx - 1) }) {
1923             error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span);
1924             error.obligation.cause.map_code(|parent_code| {
1925                 ObligationCauseCode::FunctionArgumentObligation {
1926                     arg_hir_id: arg.hir_id,
1927                     call_hir_id,
1928                     parent_code,
1929                 }
1930             });
1931             return true;
1932         } else if args_referencing_param.len() > 0 {
1933             // If more than one argument applies, then point to the callee span at least...
1934             // We have chance to fix this up further in `point_at_generics_if_possible`
1935             error.obligation.cause.span = callee_span;
1936         }
1937
1938         false
1939     }
1940
1941     fn point_at_field_if_possible(
1942         &self,
1943         error: &mut traits::FulfillmentError<'tcx>,
1944         def_id: DefId,
1945         param_to_point_at: ty::GenericArg<'tcx>,
1946         variant_def_id: DefId,
1947         expr_fields: &[hir::ExprField<'tcx>],
1948     ) -> bool {
1949         let def = self.tcx.adt_def(def_id);
1950
1951         let identity_substs = ty::InternalSubsts::identity_for_item(self.tcx, def_id);
1952         let fields_referencing_param: Vec<_> = def
1953             .variant_with_id(variant_def_id)
1954             .fields
1955             .iter()
1956             .filter(|field| {
1957                 let field_ty = field.ty(self.tcx, identity_substs);
1958                 find_param_in_ty(field_ty, param_to_point_at)
1959             })
1960             .collect();
1961
1962         if let [field] = fields_referencing_param.as_slice() {
1963             for expr_field in expr_fields {
1964                 // Look for the ExprField that matches the field, using the
1965                 // same rules that check_expr_struct uses for macro hygiene.
1966                 if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx)
1967                 {
1968                     error.obligation.cause.span = expr_field
1969                         .expr
1970                         .span
1971                         .find_ancestor_in_same_ctxt(error.obligation.cause.span)
1972                         .unwrap_or(expr_field.span);
1973                     return true;
1974                 }
1975             }
1976         }
1977
1978         false
1979     }
1980
1981     fn point_at_path_if_possible(
1982         &self,
1983         error: &mut traits::FulfillmentError<'tcx>,
1984         def_id: DefId,
1985         param: ty::GenericArg<'tcx>,
1986         qpath: &QPath<'tcx>,
1987     ) -> bool {
1988         match qpath {
1989             hir::QPath::Resolved(_, path) => {
1990                 if let Some(segment) = path.segments.last()
1991                     && self.point_at_generic_if_possible(error, def_id, param, segment)
1992                 {
1993                     return true;
1994                 }
1995             }
1996             hir::QPath::TypeRelative(_, segment) => {
1997                 if self.point_at_generic_if_possible(error, def_id, param, segment) {
1998                     return true;
1999                 }
2000             }
2001             _ => {}
2002         }
2003
2004         false
2005     }
2006
2007     fn point_at_generic_if_possible(
2008         &self,
2009         error: &mut traits::FulfillmentError<'tcx>,
2010         def_id: DefId,
2011         param_to_point_at: ty::GenericArg<'tcx>,
2012         segment: &hir::PathSegment<'tcx>,
2013     ) -> bool {
2014         let own_substs = self
2015             .tcx
2016             .generics_of(def_id)
2017             .own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
2018         let Some((index, _)) = own_substs
2019             .iter()
2020             .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
2021             .enumerate()
2022             .find(|(_, arg)| **arg == param_to_point_at) else { return false };
2023         let Some(arg) = segment
2024             .args()
2025             .args
2026             .iter()
2027             .filter(|arg| matches!(arg, hir::GenericArg::Type(_)))
2028             .nth(index) else { return false; };
2029         error.obligation.cause.span = arg
2030             .span()
2031             .find_ancestor_in_same_ctxt(error.obligation.cause.span)
2032             .unwrap_or(arg.span());
2033         true
2034     }
2035
2036     fn find_ambiguous_parameter_in<T: TypeVisitable<'tcx>>(
2037         &self,
2038         item_def_id: DefId,
2039         t: T,
2040     ) -> Option<ty::GenericArg<'tcx>> {
2041         struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId);
2042         impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> {
2043             type BreakTy = ty::GenericArg<'tcx>;
2044             fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
2045                 if let Some(origin) = self.0.type_var_origin(ty)
2046                     && let TypeVariableOriginKind::TypeParameterDefinition(_, Some(def_id)) =
2047                         origin.kind
2048                     && let generics = self.0.tcx.generics_of(self.1)
2049                     && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
2050                     && let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1)
2051                         .get(index as usize)
2052                 {
2053                     ControlFlow::Break(*subst)
2054                 } else {
2055                     ty.super_visit_with(self)
2056                 }
2057             }
2058         }
2059         t.visit_with(&mut FindAmbiguousParameter(self, item_def_id)).break_value()
2060     }
2061
2062     fn label_fn_like(
2063         &self,
2064         err: &mut Diagnostic,
2065         callable_def_id: Option<DefId>,
2066         callee_ty: Option<Ty<'tcx>>,
2067         // A specific argument should be labeled, instead of all of them
2068         expected_idx: Option<usize>,
2069         is_method: bool,
2070     ) {
2071         let Some(mut def_id) = callable_def_id else {
2072             return;
2073         };
2074
2075         if let Some(assoc_item) = self.tcx.opt_associated_item(def_id)
2076             // Possibly points at either impl or trait item, so try to get it
2077             // to point to trait item, then get the parent.
2078             // This parent might be an impl in the case of an inherent function,
2079             // but the next check will fail.
2080             && let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
2081             && let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
2082             // Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
2083             && let Some(call_kind) = ty::ClosureKind::from_def_id(self.tcx, maybe_trait_def_id)
2084             && let Some(callee_ty) = callee_ty
2085         {
2086             let callee_ty = callee_ty.peel_refs();
2087             match *callee_ty.kind() {
2088                 ty::Param(param) => {
2089                     let param =
2090                         self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx);
2091                     if param.kind.is_synthetic() {
2092                         // if it's `impl Fn() -> ..` then just fall down to the def-id based logic
2093                         def_id = param.def_id;
2094                     } else {
2095                         // Otherwise, find the predicate that makes this generic callable,
2096                         // and point at that.
2097                         let instantiated = self
2098                             .tcx
2099                             .explicit_predicates_of(self.body_id.owner)
2100                             .instantiate_identity(self.tcx);
2101                         // FIXME(compiler-errors): This could be problematic if something has two
2102                         // fn-like predicates with different args, but callable types really never
2103                         // do that, so it's OK.
2104                         for (predicate, span) in
2105                             std::iter::zip(instantiated.predicates, instantiated.spans)
2106                         {
2107                             if let ty::PredicateKind::Trait(pred) = predicate.kind().skip_binder()
2108                                 && pred.self_ty().peel_refs() == callee_ty
2109                                 && ty::ClosureKind::from_def_id(self.tcx, pred.def_id()).is_some()
2110                             {
2111                                 err.span_note(span, "callable defined here");
2112                                 return;
2113                             }
2114                         }
2115                     }
2116                 }
2117                 ty::Opaque(new_def_id, _)
2118                 | ty::Closure(new_def_id, _)
2119                 | ty::FnDef(new_def_id, _) => {
2120                     def_id = new_def_id;
2121                 }
2122                 _ => {
2123                     // Look for a user-provided impl of a `Fn` trait, and point to it.
2124                     let new_def_id = self.probe(|_| {
2125                         let trait_ref = ty::TraitRef::new(
2126                             call_kind.to_def_id(self.tcx),
2127                             self.tcx.mk_substs(
2128                                 [
2129                                     ty::GenericArg::from(callee_ty),
2130                                     self.next_ty_var(TypeVariableOrigin {
2131                                         kind: TypeVariableOriginKind::MiscVariable,
2132                                         span: rustc_span::DUMMY_SP,
2133                                     })
2134                                     .into(),
2135                                 ]
2136                                 .into_iter(),
2137                             ),
2138                         );
2139                         let obligation = traits::Obligation::new(
2140                             traits::ObligationCause::dummy(),
2141                             self.param_env,
2142                             ty::Binder::dummy(ty::TraitPredicate {
2143                                 trait_ref,
2144                                 constness: ty::BoundConstness::NotConst,
2145                                 polarity: ty::ImplPolarity::Positive,
2146                             }),
2147                         );
2148                         match SelectionContext::new(&self).select(&obligation) {
2149                             Ok(Some(traits::ImplSource::UserDefined(impl_source))) => {
2150                                 Some(impl_source.impl_def_id)
2151                             }
2152                             _ => None,
2153                         }
2154                     });
2155                     if let Some(new_def_id) = new_def_id {
2156                         def_id = new_def_id;
2157                     } else {
2158                         return;
2159                     }
2160                 }
2161             }
2162         }
2163
2164         if let Some(def_span) = self.tcx.def_ident_span(def_id) && !def_span.is_dummy() {
2165             let mut spans: MultiSpan = def_span.into();
2166
2167             let params = self
2168                 .tcx
2169                 .hir()
2170                 .get_if_local(def_id)
2171                 .and_then(|node| node.body_id())
2172                 .into_iter()
2173                 .flat_map(|id| self.tcx.hir().body(id).params)
2174                 .skip(if is_method { 1 } else { 0 });
2175
2176             for (_, param) in params
2177                 .into_iter()
2178                 .enumerate()
2179                 .filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
2180             {
2181                 spans.push_span_label(param.span, "");
2182             }
2183
2184             let def_kind = self.tcx.def_kind(def_id);
2185             err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
2186         } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
2187             && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
2188         {
2189             let param = expected_idx
2190                 .and_then(|expected_idx| self.tcx.hir().body(*body).params.get(expected_idx));
2191             let (kind, span) = if let Some(param) = param {
2192                 ("closure parameter", param.span)
2193             } else {
2194                 ("closure", self.tcx.def_span(def_id))
2195             };
2196             err.span_note(span, &format!("{} defined here", kind));
2197         } else {
2198             let def_kind = self.tcx.def_kind(def_id);
2199             err.span_note(
2200                 self.tcx.def_span(def_id),
2201                 &format!("{} defined here", def_kind.descr(def_id)),
2202             );
2203         }
2204     }
2205 }
2206
2207 fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>) -> bool {
2208     let mut walk = ty.walk();
2209     while let Some(arg) = walk.next() {
2210         if arg == param_to_point_at {
2211             return true;
2212         } else if let ty::GenericArgKind::Type(ty) = arg.unpack()
2213             && let ty::Projection(..) = ty.kind()
2214         {
2215             // This logic may seem a bit strange, but typically when
2216             // we have a projection type in a function signature, the
2217             // argument that's being passed into that signature is
2218             // not actually constraining that projection's substs in
2219             // a meaningful way. So we skip it, and see improvements
2220             // in some UI tests.
2221             walk.skip_current_subtree();
2222         }
2223     }
2224     false
2225 }