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