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