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