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