1use std::iter;
4
5use rustc_abi::ExternAbi;
6use tracing::debug;
7
8use hir_def::{CallableDefId, ConstParamId, hir::ExprId, signatures::FunctionSignature};
9use rustc_type_ir::{
10 InferTy, Interner,
11 inherent::{GenericArgs as _, IntoKind, Ty as _},
12};
13
14use crate::{
15 Adjust, Adjustment, AutoBorrow,
16 autoderef::{GeneralAutoderef, InferenceContextAutoderef},
17 infer::{
18 AllowTwoPhase, AutoBorrowMutability, Expectation, InferenceContext, InferenceDiagnostic,
19 expr::{ExprIsRead, TupleArgumentsFlag},
20 },
21 method_resolution::{MethodCallee, TreatNotYetDefinedOpaques},
22 next_solver::{
23 ConstKind, FnSig, Ty, TyKind,
24 infer::{BoundRegionConversionTime, traits::ObligationCause},
25 },
26};
27
28#[derive(Debug)]
29enum CallStep<'db> {
30 Builtin(Ty<'db>),
31 DeferredClosure(ExprId, FnSig<'db>),
32 Overloaded(MethodCallee<'db>),
34}
35
36impl<'db> InferenceContext<'db> {
37 pub(crate) fn infer_call(
38 &mut self,
39 call_expr: ExprId,
40 callee_expr: ExprId,
41 arg_exprs: &[ExprId],
42 expected: &Expectation<'db>,
43 ) -> Ty<'db> {
44 let original_callee_ty = self.infer_expr_no_expect(callee_expr, ExprIsRead::Yes);
45
46 let expr_ty =
47 self.table.try_structurally_resolve_type(callee_expr.into(), original_callee_ty);
48
49 let mut autoderef =
50 GeneralAutoderef::new_from_inference_context(self, expr_ty, callee_expr.into());
51 let mut result = None;
52 let mut error_reported = false;
53 while result.is_none() && autoderef.next().is_some() {
54 result = Self::try_overloaded_call_step(
55 call_expr,
56 callee_expr,
57 arg_exprs,
58 &mut autoderef,
59 &mut error_reported,
60 );
61 }
62
63 let obligations = autoderef.take_obligations();
66 self.table.register_predicates(obligations);
67
68 let output = match result {
69 None => {
70 for &arg in arg_exprs {
73 self.infer_expr_no_expect(arg, ExprIsRead::Yes);
74 }
75
76 if !error_reported {
77 self.push_diagnostic(InferenceDiagnostic::ExpectedFunction {
78 call_expr,
79 found: original_callee_ty.store(),
80 });
81 }
82
83 self.types.types.error
84 }
85
86 Some(CallStep::Builtin(callee_ty)) => {
87 self.confirm_builtin_call(callee_expr, call_expr, callee_ty, arg_exprs, expected)
88 }
89
90 Some(CallStep::DeferredClosure(_def_id, fn_sig)) => {
91 self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig)
92 }
93
94 Some(CallStep::Overloaded(method_callee)) => {
95 self.confirm_overloaded_call(call_expr, arg_exprs, expected, method_callee)
96 }
97 };
98
99 self.table.register_wf_obligation(output.into(), ObligationCause::new(call_expr));
101
102 output
103 }
104
105 fn try_overloaded_call_step(
106 call_expr: ExprId,
107 callee_expr: ExprId,
108 arg_exprs: &[ExprId],
109 autoderef: &mut InferenceContextAutoderef<'_, 'db>,
110 error_reported: &mut bool,
111 ) -> Option<CallStep<'db>> {
112 let final_ty = autoderef.final_ty();
113 let adjusted_ty =
114 autoderef.ctx().table.try_structurally_resolve_type(callee_expr.into(), final_ty);
115
116 match adjusted_ty.kind() {
118 TyKind::FnDef(..) | TyKind::FnPtr(..) => {
119 let adjust_steps = autoderef.adjust_steps_as_infer_ok();
120 let adjustments =
121 autoderef.ctx().table.register_infer_ok(adjust_steps).into_boxed_slice();
122 autoderef.ctx().write_expr_adj(callee_expr, adjustments);
123 return Some(CallStep::Builtin(adjusted_ty));
124 }
125
126 TyKind::Closure(def_id, args)
130 if autoderef.ctx().infcx().closure_kind(adjusted_ty).is_none() =>
131 {
132 let closure_sig = args.as_closure().sig();
133 let closure_sig = autoderef.ctx().infcx().instantiate_binder_with_fresh_vars(
134 callee_expr.into(),
135 BoundRegionConversionTime::FnCall,
136 closure_sig,
137 );
138 let adjust_steps = autoderef.adjust_steps_as_infer_ok();
139 let adjustments = autoderef.ctx().table.register_infer_ok(adjust_steps);
140 let def_id = def_id.0.loc(autoderef.ctx().db).expr;
141 autoderef.ctx().record_deferred_call_resolution(
142 def_id,
143 DeferredCallResolution {
144 call_expr,
145 callee_expr,
146 closure_ty: adjusted_ty,
147 adjustments,
148 fn_sig: closure_sig,
149 },
150 );
151 return Some(CallStep::DeferredClosure(def_id, closure_sig));
152 }
153
154 TyKind::CoroutineClosure(def_id, args)
160 if autoderef.ctx().infcx().closure_kind(adjusted_ty).is_none() =>
161 {
162 let closure_args = args.as_coroutine_closure();
163 let coroutine_closure_sig =
164 autoderef.ctx().infcx().instantiate_binder_with_fresh_vars(
165 callee_expr.into(),
166 BoundRegionConversionTime::FnCall,
167 closure_args.coroutine_closure_sig(),
168 );
169 let tupled_upvars_ty = autoderef.ctx().table.next_ty_var(call_expr.into());
170 let kind_ty = autoderef.ctx().table.next_ty_var(call_expr.into());
175 let interner = autoderef.ctx().interner();
176
177 let call_sig = interner.mk_fn_sig(
179 [coroutine_closure_sig.tupled_inputs_ty],
180 coroutine_closure_sig.to_coroutine(
181 interner,
182 closure_args.parent_args(),
183 kind_ty,
184 interner.coroutine_for_closure(def_id),
185 tupled_upvars_ty,
186 ),
187 coroutine_closure_sig.fn_sig_kind.c_variadic(),
188 coroutine_closure_sig.fn_sig_kind.safety(),
189 coroutine_closure_sig.fn_sig_kind.abi(),
190 );
191 let adjust_steps = autoderef.adjust_steps_as_infer_ok();
192 let adjustments = autoderef.ctx().table.register_infer_ok(adjust_steps);
193 let def_id = def_id.0.loc(autoderef.ctx().db).expr;
194 autoderef.ctx().record_deferred_call_resolution(
195 def_id,
196 DeferredCallResolution {
197 call_expr,
198 callee_expr,
199 closure_ty: adjusted_ty,
200 adjustments,
201 fn_sig: call_sig,
202 },
203 );
204 return Some(CallStep::DeferredClosure(def_id, call_sig));
205 }
206
207 TyKind::Ref(..) if autoderef.step_count() == 0 => {
220 return None;
221 }
222
223 TyKind::Infer(InferTy::TyVar(vid))
224 if !autoderef.ctx().infcx().has_opaques_with_sub_unified_hidden_type(vid) => {
227 autoderef
228 .ctx()
229 .type_must_be_known_at_this_point(callee_expr.into(), adjusted_ty);
230 *error_reported = true;
231 return None;
232 }
233
234 TyKind::Error(_) => {
235 return None;
236 }
237
238 _ => {}
239 }
240
241 autoderef
249 .ctx()
250 .try_overloaded_call_traits(call_expr, adjusted_ty, Some(arg_exprs))
251 .or_else(|| autoderef.ctx().try_overloaded_call_traits(call_expr, adjusted_ty, None))
252 .map(|(autoref, method)| {
253 let adjustments = autoderef.adjust_steps_as_infer_ok();
254 let mut adjustments = autoderef.ctx().table.register_infer_ok(adjustments);
255 adjustments.extend(autoref);
256 autoderef.ctx().write_expr_adj(callee_expr, adjustments.into_boxed_slice());
257 CallStep::Overloaded(method)
258 })
259 }
260
261 fn try_overloaded_call_traits(
262 &mut self,
263 call_expr: ExprId,
264 adjusted_ty: Ty<'db>,
265 opt_arg_exprs: Option<&[ExprId]>,
266 ) -> Option<(Option<Adjustment>, MethodCallee<'db>)> {
267 let call_trait_choices = if self.shallow_resolve(adjusted_ty).is_coroutine_closure() {
281 [
282 (self.lang_items.AsyncFn, self.lang_items.AsyncFn_async_call, true),
283 (self.lang_items.AsyncFnMut, self.lang_items.AsyncFnMut_async_call_mut, true),
284 (self.lang_items.AsyncFnOnce, self.lang_items.AsyncFnOnce_async_call_once, false),
285 (self.lang_items.Fn, self.lang_items.Fn_call, true),
286 (self.lang_items.FnMut, self.lang_items.FnMut_call_mut, true),
287 (self.lang_items.FnOnce, self.lang_items.FnOnce_call_once, false),
288 ]
289 } else {
290 [
291 (self.lang_items.Fn, self.lang_items.Fn_call, true),
292 (self.lang_items.FnMut, self.lang_items.FnMut_call_mut, true),
293 (self.lang_items.FnOnce, self.lang_items.FnOnce_call_once, false),
294 (self.lang_items.AsyncFn, self.lang_items.AsyncFn_async_call, true),
295 (self.lang_items.AsyncFnMut, self.lang_items.AsyncFnMut_async_call_mut, true),
296 (self.lang_items.AsyncFnOnce, self.lang_items.AsyncFnOnce_async_call_once, false),
297 ]
298 };
299
300 for (opt_trait_def_id, opt_method_def_id, borrow) in call_trait_choices {
302 let (Some(trait_def_id), Some(method_def_id)) = (opt_trait_def_id, opt_method_def_id)
303 else {
304 continue;
305 };
306
307 let opt_input_type = opt_arg_exprs.map(|arg_exprs| {
308 Ty::new_tup_from_iter(
309 self.interner(),
310 arg_exprs.iter().map(|&arg| self.table.next_ty_var(arg.into())),
311 )
312 });
313
314 if let Some(ok) = self.table.lookup_method_for_operator(
321 ObligationCause::new(call_expr),
322 trait_def_id,
323 method_def_id,
324 adjusted_ty,
325 opt_input_type,
326 TreatNotYetDefinedOpaques::AsRigid,
327 ) {
328 let method = self.table.register_infer_ok(ok);
329 let mut autoref = None;
330 if borrow {
331 let TyKind::Ref(_, _, mutbl) = method.sig.inputs_and_output.inputs()[0].kind()
334 else {
335 panic!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut")
336 };
337
338 let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::No);
342
343 autoref = Some(Adjustment {
344 kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
345 target: method.sig.inputs_and_output.inputs()[0].store(),
346 });
347 }
348
349 return Some((autoref, method));
350 }
351 }
352
353 None
354 }
355
356 fn check_legacy_const_generics(
358 &mut self,
359 callee: Option<CallableDefId>,
360 callee_ty: Ty<'db>,
361 args: &[ExprId],
362 ) -> Box<[u32]> {
363 let (func, fn_generic_args) = match (callee, callee_ty.kind()) {
364 (Some(CallableDefId::FunctionId(func)), TyKind::FnDef(_, fn_generic_args)) => {
365 (func, fn_generic_args)
366 }
367 _ => return Default::default(),
368 };
369 let generics = crate::generics::generics(self.db, func.into());
370 let const_params = generics
371 .iter_self_type_or_consts()
372 .filter(|(_, param_data)| param_data.const_param().is_some())
373 .map(|(id, _)| ConstParamId::from_unchecked(id))
374 .collect::<Vec<_>>();
375
376 let data = FunctionSignature::of(self.db, func);
377 let Some(legacy_const_generics_indices) = data.legacy_const_generics_indices(self.db, func)
378 else {
379 return Default::default();
380 };
381 let mut legacy_const_generics_indices = Box::<[u32]>::from(legacy_const_generics_indices);
382
383 if data.params.len() + legacy_const_generics_indices.len() != args.len() {
385 if args.len() <= data.params.len() {
386 return Default::default();
387 } else {
388 legacy_const_generics_indices.sort_unstable();
391 return legacy_const_generics_indices;
392 }
393 }
394
395 for (const_idx, arg_idx) in legacy_const_generics_indices.iter().copied().enumerate() {
397 if arg_idx >= args.len() as u32 {
398 continue;
399 }
400
401 if let Some(const_arg) = fn_generic_args.get(const_idx).and_then(|it| it.konst())
402 && let ConstKind::Infer(_) = const_arg.kind()
403 {
404 _ = self
407 .table
408 .at(&ObligationCause::dummy())
409 .eq(self.types.consts.error, const_arg)
410 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
411 }
412
413 let expected = if let Some(&const_param) = const_params.get(const_idx) {
414 Expectation::has_type(self.db.const_param_ty(const_param))
415 } else {
416 Expectation::None
417 };
418
419 self.infer_expr(args[arg_idx as usize], &expected, ExprIsRead::Yes);
420 }
422 legacy_const_generics_indices.sort_unstable();
423 legacy_const_generics_indices
424 }
425
426 fn confirm_builtin_call(
427 &mut self,
428 callee_expr: ExprId,
429 call_expr: ExprId,
430 callee_ty: Ty<'db>,
431 arg_exprs: &[ExprId],
432 expected: &Expectation<'db>,
433 ) -> Ty<'db> {
434 let (fn_sig, def_id) = match callee_ty.kind() {
435 TyKind::FnDef(def_id, args) => {
436 let fn_sig = self
437 .db
438 .callable_item_signature(def_id.0)
439 .instantiate(self.interner(), args)
440 .skip_norm_wip();
441 (fn_sig, Some(def_id.0))
442 }
443
444 TyKind::FnPtr(sig_tys, hdr) => (sig_tys.with(hdr), None),
446
447 _ => unreachable!(),
448 };
449
450 let fn_sig = self.infcx().instantiate_binder_with_fresh_vars(
456 callee_expr.into(),
457 BoundRegionConversionTime::FnCall,
458 fn_sig,
459 );
460
461 let indices_to_skip = self.check_legacy_const_generics(def_id, callee_ty, arg_exprs);
462 self.check_call_arguments(
463 call_expr,
464 fn_sig.inputs(),
465 fn_sig.output(),
466 expected,
467 arg_exprs,
468 &indices_to_skip,
469 fn_sig.c_variadic(),
470 TupleArgumentsFlag::DontTupleArguments,
471 );
472
473 if fn_sig.abi() == ExternAbi::RustCall
474 && let Some(ty) = fn_sig.inputs().last().copied()
475 && let Some(tuple_trait) = self.lang_items.Tuple
476 {
477 let span = arg_exprs.last().copied().unwrap_or(call_expr);
478 self.table.register_bound(ty, tuple_trait, ObligationCause::new(span));
479 self.require_type_is_sized(ty, span.into());
480 }
481
482 fn_sig.output()
483 }
484
485 fn confirm_deferred_closure_call(
486 &mut self,
487 call_expr: ExprId,
488 arg_exprs: &[ExprId],
489 expected: &Expectation<'db>,
490 fn_sig: FnSig<'db>,
491 ) -> Ty<'db> {
492 self.check_call_arguments(
497 call_expr,
498 fn_sig.inputs(),
499 fn_sig.output(),
500 expected,
501 arg_exprs,
502 &[],
503 fn_sig.c_variadic(),
504 TupleArgumentsFlag::TupleArguments,
505 );
506
507 fn_sig.output()
508 }
509
510 fn confirm_overloaded_call(
511 &mut self,
512 call_expr: ExprId,
513 arg_exprs: &[ExprId],
514 expected: &Expectation<'db>,
515 method: MethodCallee<'db>,
516 ) -> Ty<'db> {
517 self.check_call_arguments(
518 call_expr,
519 &method.sig.inputs()[1..],
520 method.sig.output(),
521 expected,
522 arg_exprs,
523 &[],
524 method.sig.c_variadic(),
525 TupleArgumentsFlag::TupleArguments,
526 );
527
528 self.write_method_resolution(call_expr, method.def_id, method.args);
529
530 method.sig.output()
531 }
532}
533
534#[derive(Debug, Clone)]
535pub(crate) struct DeferredCallResolution<'db> {
536 call_expr: ExprId,
537 callee_expr: ExprId,
538 closure_ty: Ty<'db>,
539 adjustments: Vec<Adjustment>,
540 fn_sig: FnSig<'db>,
541}
542
543impl<'db> DeferredCallResolution<'db> {
544 pub(crate) fn resolve(self, ctx: &mut InferenceContext<'db>) {
545 debug!("DeferredCallResolution::resolve() {:?}", self);
546
547 assert!(ctx.infcx().closure_kind(self.closure_ty).is_some());
550
551 match ctx.try_overloaded_call_traits(self.call_expr, self.closure_ty, None) {
553 Some((autoref, method_callee)) => {
554 let method_sig = method_callee.sig;
563
564 debug!("attempt_resolution: method_callee={:?}", method_callee);
565
566 for (method_arg_ty, self_arg_ty) in
567 iter::zip(method_sig.inputs().iter().skip(1), self.fn_sig.inputs())
568 {
569 _ = ctx.demand_eqtype(self.call_expr.into(), *self_arg_ty, *method_arg_ty);
570 }
571
572 _ = ctx.demand_eqtype(
573 self.call_expr.into(),
574 method_sig.output(),
575 self.fn_sig.output(),
576 );
577
578 let mut adjustments = self.adjustments;
579 adjustments.extend(autoref);
580 ctx.write_expr_adj(self.callee_expr, adjustments.into_boxed_slice());
581
582 ctx.write_method_resolution(
583 self.call_expr,
584 method_callee.def_id,
585 method_callee.args,
586 );
587 }
588 None => {}
589 }
590 }
591}