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