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