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::*;
9 potentially_plural_count, struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt,
10 LocalTy, Needs, TupleArgumentsFlag,
12 use crate::structured_errors::StructuredDiagnostic;
15 use rustc_data_structures::sync::Lrc;
16 use rustc_errors::{Applicability, Diagnostic, DiagnosticId, MultiSpan};
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};
36 enum TupleMatchFound {
39 /// Beginning and end Span
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(..) {
51 pub(in super::super) fn check_method_argument_types(
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>,
60 let has_error = match method {
61 Ok(method) => method.substs.references_error() || method.sig.references_error(),
65 let err_inputs = self.err_args(args_no_rcvr.len());
67 let err_inputs = match tuple_arguments {
68 DontTupleArguments => err_inputs,
69 TupleArguments => vec![self.tcx.intern_tup(&err_inputs)],
72 self.check_argument_types(
82 return self.tcx.ty_error();
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(
91 &method.sig.inputs()[1..],
93 self.check_argument_types(
96 &method.sig.inputs()[1..],
99 method.sig.c_variadic,
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(
110 // Span enclosing the call site
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
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>,
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 | ...
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.
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);
147 let mut err_code = "E0061";
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() {
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()),
169 (arg_types.iter().collect(), expected_input_tys)
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
178 "cannot use call notation; the first type parameter \
179 for the function trait is neither a tuple nor unit"
182 (self.err_args(provided_args.len()), None)
186 (formal_input_tys.to_vec(), expected_input_tys)
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());
194 formal_input_tys.clone()
197 let minimum_input_count = expected_input_tys.len();
198 let provided_arg_count = provided_args.len();
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];
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];
211 debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
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);
218 let checked_ty = self.check_expr_with_expectation(provided_arg, expectation);
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);
225 // Keep track of these for below
226 final_arg_types[idx] = Some((checked_ty, coerced_ty));
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.
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(
243 // Make sure we store the resolved type
244 final_arg_types[idx] = Some((checked_ty, coerced_ty));
246 let coerce_error = self
247 .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
250 if coerce_error.is_some() {
251 return Compatibility::Incompatible(coerce_error);
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);
264 Err(err) => Some(err),
267 // If neither check failed, the types are compatible
268 match subtyping_error {
269 None => Compatibility::Compatible,
270 Some(_) => Compatibility::Incompatible(subtyping_error),
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];
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
284 if formal_input_ty.references_error() || expected_input_ty.references_error() {
285 return Compatibility::Incompatible(None);
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.
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);
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);
301 return Compatibility::Incompatible(None);
304 let subtyping_result = self
305 .at(&self.misc(provided_arg.span), self.param_env)
306 .sup(formal_input_ty, coerced_ty);
308 // Same as above: if either the coerce type or the checked type is an error type,
309 // consider them *not* compatible.
311 !coerced_ty.references_error() && !checked_ty.references_error() && can_coerce;
313 match (coercible, &subtyping_result) {
314 (true, Ok(_)) => Compatibility::Compatible,
315 _ => Compatibility::Incompatible(subtyping_result.err()),
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()];
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
330 provided_arg_count == minimum_input_count
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.
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(
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!(), || {})`.
362 self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
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 {
374 let is_closure = matches!(arg.kind, ExprKind::Closure(..));
375 if is_closure != check_closures {
379 let compatible = demand_compatible(idx, &mut final_arg_types);
380 let is_compatible = matches!(compatible, Compatibility::Compatible);
381 compatibility[idx] = compatible;
384 call_appears_satisfied = false;
389 // Logic here is a bit hairy
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 {
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
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) }
412 // Okay, so here's where it gets complicated in regards to what errors
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`
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.
427 let found_errors = !errors.is_empty();
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();
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() {
453 // Next, let's construct the error
454 let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
459 hir::ExprKind::Path(hir::QPath::Resolved(
461 hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
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())
476 *span, ident_span, None, // methods are never ctors
479 k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
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",
487 if c_variadic && provided_arg_count < minimum_input_count {
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,
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(
516 final_arg_types[0].map(|ty| ty.0).unwrap(),
517 final_arg_types[0].map(|ty| ty.1).unwrap(),
523 format!("arguments to this {} are incorrect", call_name),
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();
531 .get_if_local(def_id)
532 .and_then(|node| node.body_id())
534 .map(|id| tcx.hir().body(id).params)
537 for param in params {
538 spans.push_span_label(param.span, String::new());
541 let def_kind = tcx.def_kind(def_id);
542 err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
547 TupleMatchFound::Multiple(start, end) => {
548 let mut err = tcx.sess.struct_span_err_with_code(
551 "this {} takes {}{} but {} {} supplied",
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" }
558 DiagnosticId::Error(err_code.to_owned()),
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();
566 .get_if_local(def_id)
567 .and_then(|node| node.body_id())
569 .map(|id| tcx.hir().body(id).params)
572 for param in params {
573 spans.push_span_label(param.span, String::new());
576 let def_kind = tcx.def_kind(def_id);
577 err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
579 err.multipart_suggestion(
580 "use parentheses to construct a tuple",
581 vec![(start, '('.to_string()), (end, ')'.to_string())],
582 Applicability::MachineApplicable,
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.
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)))) =
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(
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(),
613 format!("arguments to this {} are incorrect", call_name),
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();
621 .get_if_local(def_id)
622 .and_then(|node| node.body_id())
624 .map(|id| tcx.hir().body(id).params)
627 for param in params {
628 spans.push_span_label(param.span, String::new());
631 let def_kind = tcx.def_kind(def_id);
632 err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
639 let mut err = if minimum_input_count == provided_arg_count {
644 "arguments to this {} are incorrect",
648 tcx.sess.struct_span_err_with_code(
651 "this {} takes {}{} but {} {} supplied",
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" }
658 DiagnosticId::Error(err_code.to_owned()),
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 {
674 let mut suggestion_text = SuggestionText::None;
676 let mut errors = errors.into_iter().peekable();
677 while let Some(error) = errors.next() {
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 {
698 self.emit_coerce_suggestions(
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(),
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() {
712 format!(" of type `{}`", ty)
718 provided_args[arg_idx].span,
719 format!("argument{} unexpected", arg_type),
721 suggestion_text = match suggestion_text {
722 SuggestionText::None => SuggestionText::Remove(false),
723 SuggestionText::Remove(_) => SuggestionText::Remove(true),
724 _ => SuggestionText::DidYouMean,
727 Error::Missing(input_idx) => {
728 // If there are multiple missing arguments adjacent to each other,
729 // then we can provide a single error.
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))) {
734 Error::Missing(input_idx) => missing_idxs.push(input_idx),
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[..] {
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)
754 if input_ty.references_error() || input_ty.has_infer_types() {
757 format!(" of type `{}`", input_ty)
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,
766 &[first_idx, second_idx] => {
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]);
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;
777 second_arg_span.hi(),
778 first_arg_span.ctxt(),
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 {
793 " of type `{}` and `{}`",
794 first_input_ty, second_input_ty
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)
803 _ => SuggestionText::DidYouMean,
806 &[first_idx, second_idx, third_idx] => {
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]);
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;
819 first_arg_span.ctxt(),
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 {
836 " of type `{}`, `{}`, and `{}`",
837 first_input_ty, second_input_ty, third_input_ty
842 format!("three arguments{} are missing", arg_type),
844 suggestion_text = match suggestion_text {
845 SuggestionText::None | SuggestionText::Provide(_) => {
846 SuggestionText::Provide(true)
848 _ => SuggestionText::DidYouMean,
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
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;
862 second_arg_span.hi(),
863 first_arg_span.ctxt(),
867 // Otherwise just label the whole function
870 labels.push((span, format!("multiple arguments are missing")));
871 suggestion_text = match suggestion_text {
872 SuggestionText::None | SuggestionText::Provide(_) => {
873 SuggestionText::Provide(true)
875 _ => SuggestionText::DidYouMean,
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;
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)
893 format!("expected `{}`{}", first_expected_ty, first_provided_ty),
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)
905 format!("expected `{}`{}", other_expected_ty, other_provided_ty),
907 suggestion_text = match suggestion_text {
908 SuggestionText::None => SuggestionText::Swap,
909 _ => SuggestionText::DidYouMean,
912 Error::Permutation(args) => {
913 for (dst_arg, dest_input) in args {
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)
922 provided_args[dst_arg].span,
923 format!("expected `{}`{}", expected_ty, provided_ty),
927 suggestion_text = match suggestion_text {
928 SuggestionText::None => SuggestionText::Reorder,
929 _ => SuggestionText::DidYouMean,
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);
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();
948 .get_if_local(def_id)
949 .and_then(|node| node.body_id())
951 .flat_map(|id| tcx.hir().body(id).params)
954 for param in params {
955 spans.push_span_label(param.span, String::new());
958 let def_kind = tcx.def_kind(def_id);
959 err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
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 { "" }))
968 SuggestionText::Remove(plural) => {
969 Some(format!("remove the extra argument{}", if plural { "s" } else { "" }))
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()),
975 if let Some(suggestion_text) = suggestion_text {
976 let source_map = self.sess().source_map();
977 let mut suggestion = format!(
979 source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| String::new())
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();
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() {
993 format!("{{{}}}", input_ty)
996 suggestion += &suggestion_text;
997 if idx < minimum_input_count - 1 {
1002 err.span_suggestion_verbose(
1006 Applicability::HasPlaceholders,
1012 for arg in provided_args.iter().skip(minimum_input_count) {
1013 let arg_ty = self.check_expr(&arg);
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
1020 fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
1021 use crate::structured_errors::MissingCastForVariadicArg;
1023 MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
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");
1033 ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
1034 variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
1036 ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
1037 variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
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());
1050 fn suggested_tuple_wrap(
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 };
1060 // First check that there are the same number of types.
1061 if expected_types.len() != provided_args.len() {
1062 return TupleMatchFound::None;
1065 let supplied_types: Vec<_> = provided_args.iter().map(|arg| self.check_expr(arg)).collect();
1067 let all_match = iter::zip(expected_types, supplied_types)
1068 .all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok());
1071 return TupleMatchFound::None;
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())
1082 // AST fragment checking
1083 pub(in super::super) fn check_lit(
1086 expected: Expectation<'tcx>,
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))
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),
1107 opt_ty.unwrap_or_else(|| self.next_int_var())
1109 ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => {
1110 tcx.mk_mach_float(ty::float_ty(t))
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),
1117 opt_ty.unwrap_or_else(|| self.next_float_var())
1119 ast::LitKind::Bool(_) => tcx.types.bool,
1120 ast::LitKind::Err(_) => tcx.ty_error(),
1124 pub fn check_struct_path(
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 {
1133 self.set_tainted_by_errors();
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),
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))
1147 _ => bug!("unexpected definition: {:?}", def),
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);
1154 // Check bounds on type arguments used in the path.
1155 self.add_required_obligations(path_span, did, substs);
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
1171 "expected struct, variant or union type, found {}",
1172 ty.sort_string(self.tcx)
1174 .span_label(path_span, "not a struct")
1182 pub fn check_decl_initializer(
1185 pat: &'tcx hir::Pat<'tcx>,
1186 init: &'tcx hir::Expr<'tcx>,
1188 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
1189 // for #42640 (default match binding modes).
1192 let ref_bindings = pat.contains_explicit_ref_binding();
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);
1208 self.check_expr_coercable_to_type(init, local_ty, None)
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);
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);
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.
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);
1236 /// Type check a `let` statement.
1237 pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
1238 self.check_decl(local.into());
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`.
1244 hir::StmtKind::Item(..) => return,
1245 hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
1248 self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
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);
1255 hir::StmtKind::Local(ref l) => {
1256 self.check_decl_local(&l);
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);
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),
1276 self.check_expr_with_expectation(expr, expectation);
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);
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));
1289 // if the block produces a `!` value, that can always be
1290 // (effectively) coerced to unit.
1292 self.demand_suptype(blk.span, unit, ty);
1296 pub(in super::super) fn check_block_with_expected(
1298 blk: &'tcx hir::Block<'tcx>,
1299 expected: Expectation<'tcx>,
1301 let prev = self.ps.replace(self.ps.get().recurse(blk));
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.
1310 // 'a: { if true { break 'a Err(()); } Ok(()) }
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
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)
1324 let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
1325 Some(e) => slice::from_ref(e),
1328 CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
1331 let prev_diverges = self.diverges.get();
1332 let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
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);
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));
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(
1359 Some(&mut |diag: &mut Diagnostic| {
1360 self.suggest_block_to_brackets(diag, blk, tail_expr_ty, ty_for_diagnostic);
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
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 {
1391 fn_span = Some(ident.span);
1395 coerce.coerce_forced_unit(
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.
1405 // Our block must be a `assign desugar local; assignment`
1406 if let Some(hir::Node::Block(hir::Block {
1411 hir::StmtKind::Local(hir::Local {
1413 hir::LocalSource::AssignDesugar(_),
1420 hir::StmtKind::Expr(hir::Expr {
1421 kind: hir::ExprKind::Assign(..),
1428 })) = self.tcx.hir().find(blk.hir_id)
1430 self.comes_from_while_condition(blk.hir_id, |_| {
1431 err.downgrade_to_delayed_bug();
1436 if let Some(fn_span) = fn_span {
1439 "implicitly returns `()` as its body has no tail or `return` \
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);
1456 let mut ty = ctxt.coerce.unwrap().complete(self);
1458 if self.has_errors.get() || ty.references_error() {
1459 ty = self.tcx.ty_error()
1462 self.write_ty(blk.hir_id, ty);
1468 /// A common error is to add an extra semicolon:
1471 /// fn foo() -> usize {
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(
1481 blk: &'tcx hir::Block<'tcx>,
1482 expected_ty: Ty<'tcx>,
1483 err: &mut Diagnostic,
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(
1489 "consider removing this semicolon and boxing the expression",
1491 Applicability::HasPlaceholders,
1494 err.span_suggestion_short(
1496 "remove this semicolon",
1498 Applicability::MachineApplicable,
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));
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);
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))
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:
1529 /// if false { return 0i32; } else { 1u32 }
1530 /// // ^^^^ point at this instead of the whole `if` expression
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))
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)
1551 if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
1552 if let Some(rslt) = check_in_progress(el) {
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() {
1569 fn overwrite_local_ty_if_err(
1572 pat: &'tcx hir::Pat<'tcx>,
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);
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(
1593 ) -> (Res, Ty<'tcx>) {
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);
1600 QPath::TypeRelative(ref qself, ref segment) => {
1601 let ty = self.to_ty(qself);
1603 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
1608 let result = <dyn AstConv<'_>>::associated_path_to_ty(
1609 self, hir_id, path_span, ty, res, segment, true,
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));
1614 // Write back the new resolution.
1615 self.write_resolution(hir_id, result);
1617 (result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
1619 QPath::LangItem(lang_item, span, id) => {
1620 self.resolve_lang_item_path(lang_item, span, hir_id, id)
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(
1633 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1634 final_arg_types: &[Option<(Ty<'tcx>, Ty<'tcx>)>],
1635 expr: &'tcx hir::Expr<'tcx>,
1637 args: &'tcx [hir::Expr<'tcx>],
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() {
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) {
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.
1657 mut code: Lrc<ObligationCauseCode<'_>>,
1658 ) -> Lrc<ObligationCauseCode<'_>> {
1659 let mut result_code = code.clone();
1661 let parent = match &*code {
1662 ObligationCauseCode::ImplDerivedObligation(c) => {
1663 c.derived.parent_code.clone()
1665 ObligationCauseCode::BuiltinDerivedObligation(c)
1666 | ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(),
1669 result_code = std::mem::replace(&mut code, parent);
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()
1678 ObligationCauseCode::ImplDerivedObligation(code) => {
1679 code.derived.parent_trait_pred.self_ty().skip_binder().into()
1681 _ if let ty::PredicateKind::Trait(predicate) =
1682 error.obligation.predicate.kind().skip_binder() => {
1683 predicate.self_ty().into()
1687 let self_ = self.resolve_vars_if_possible(self_);
1689 // Collect the argument position for all arguments that could have caused this
1690 // `FulfillmentError`.
1691 let mut referenced_in = final_arg_types
1694 .filter_map(|(i, arg)| match arg {
1695 Some((checked_ty, coerce_ty)) => Some([(i, *checked_ty), (i, *coerce_ty)]),
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 }
1705 .collect::<Vec<usize>>();
1707 // Both checked and coerced types could have matched, thus we need to remove
1710 // We sort primitive type usize here and can use unstable sort
1711 referenced_in.sort_unstable();
1712 referenced_in.dedup();
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() {
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,
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;
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(
1745 errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1746 call_expr: &'tcx hir::Expr<'tcx>,
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()
1754 // If any of the type arguments in this path segment caused the
1755 // `FulfillmentError`, point at its span (#61860).
1759 .filter_map(|seg| seg.args.as_ref())
1760 .flat_map(|a| a.args.iter())
1762 if let hir::GenericArg::Type(hir_ty) = &arg {
1763 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
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`.
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;