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