Skip to main content

hir_ty/infer/
closure.rs

1//! Inference of closure parameter types based on the closure's expected type.
2
3pub(crate) mod analysis;
4
5use std::{iter, mem, ops::ControlFlow};
6
7use hir_def::{
8    AdtId, TraitId,
9    hir::{ClosureKind, CoroutineKind, CoroutineSource, ExprId, PatId},
10    type_ref::TypeRefId,
11};
12use indexmap::IndexMap;
13use rustc_abi::ExternAbi;
14use rustc_type_ir::{
15    AliasTyKind, ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts,
16    CoroutineClosureArgs, CoroutineClosureArgsParts, InferTy, Interner, TypeSuperVisitable,
17    TypeVisitable, TypeVisitableExt, TypeVisitor,
18    inherent::{BoundExistentialPredicates, GenericArgs as _, IntoKind, Ty as _},
19};
20use tracing::{debug, instrument};
21
22use crate::{
23    Span,
24    db::{InternedClosure, InternedClosureId, InternedCoroutineClosureId, InternedCoroutineId},
25    infer::{BreakableKind, ClosureData, Diverges, coerce::CoerceMany, pat::PatOrigin},
26    next_solver::{
27        AliasTy, Binder, ClauseKind, DbInterner, ErrorGuaranteed, FnSig, GenericArg, PolyFnSig,
28        PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, StoredFnSig, TermId, Ty,
29        TyKind, Unnormalized,
30        abi::Safety,
31        infer::{
32            BoundRegionConversionTime, InferOk, InferResult,
33            traits::{ObligationCause, PredicateObligations},
34        },
35    },
36};
37
38use super::{Expectation, InferenceContext};
39
40#[derive(Debug)]
41struct ClosureSignatures<'db> {
42    /// The signature users of the closure see.
43    bound_sig: PolyFnSig<'db>,
44    /// The signature within the function body.
45    /// This mostly differs in the sense that lifetimes are now early bound and any
46    /// opaque types from the signature expectation are overridden in case there are
47    /// explicit hidden types written by the user in the closure signature.
48    liberated_sig: FnSig<'db>,
49}
50
51impl<'db> InferenceContext<'db> {
52    fn poll_option_ty(&mut self, item_ty: Ty<'db>) -> Ty<'db> {
53        let interner = self.interner();
54
55        let (Some(option), Some(poll)) = (self.lang_items.Option, self.lang_items.Poll) else {
56            return self.types.types.error;
57        };
58
59        let option_ty = Ty::new_adt(
60            interner,
61            AdtId::EnumId(option),
62            interner.mk_args(&[GenericArg::from(item_ty)]),
63        );
64
65        Ty::new_adt(interner, AdtId::EnumId(poll), interner.mk_args(&[GenericArg::from(option_ty)]))
66    }
67
68    pub(super) fn infer_closure(
69        &mut self,
70        body: ExprId,
71        args: &[PatId],
72        ret_type: Option<TypeRefId>,
73        arg_types: &[Option<TypeRefId>],
74        closure_kind: ClosureKind,
75        closure_expr: ExprId,
76        expected: &Expectation<'db>,
77    ) -> Ty<'db> {
78        assert_eq!(args.len(), arg_types.len());
79
80        let interner = self.interner();
81        // It's always helpful for inference if we know the kind of
82        // closure sooner rather than later, so first examine the expected
83        // type, and see if can glean a closure kind from there.
84        let (expected_sig, expected_kind) = match expected.to_option(&self.table) {
85            Some(ty) => {
86                let ty = self.table.try_structurally_resolve_type(closure_expr.into(), ty);
87                self.deduce_closure_signature(closure_expr, ty, closure_kind)
88            }
89            None => (None, None),
90        };
91
92        let ClosureSignatures { bound_sig, mut liberated_sig } = self.sig_of_closure(
93            closure_expr,
94            args,
95            arg_types,
96            ret_type,
97            expected_sig,
98            closure_kind,
99        );
100
101        debug!(?bound_sig, ?liberated_sig);
102
103        let parent_args = self.identity_args();
104
105        let tupled_upvars_ty = self.table.next_ty_var(closure_expr.into());
106
107        let closure_loc =
108            InternedClosure { owner: self.owner, expr: closure_expr, kind: closure_kind };
109        // FIXME: We could probably actually just unify this further --
110        // instead of having a `FnSig` and a `Option<CoroutineTypes>`,
111        // we can have a `ClosureSignature { Coroutine { .. }, Closure { .. } }`,
112        // similar to how `ty::GenSig` is a distinct data structure.
113        let (closure_ty, resume_yield_tys) = match closure_kind {
114            ClosureKind::Closure => {
115                // Tuple up the arguments and insert the resulting function type into
116                // the `closures` table.
117                let sig = bound_sig.map_bound(|sig| {
118                    interner.mk_fn_sig(
119                        [Ty::new_tup(interner, sig.inputs())],
120                        sig.output(),
121                        sig.c_variadic(),
122                        sig.safety(),
123                        sig.abi(),
124                    )
125                });
126
127                debug!(?sig, ?expected_kind);
128
129                let closure_kind_ty = match expected_kind {
130                    Some(kind) => Ty::from_closure_kind(interner, kind),
131                    // Create a type variable (for now) to represent the closure kind.
132                    // It will be unified during the upvar inference phase (`upvar.rs`)
133                    None => self.table.next_ty_var(closure_expr.into()),
134                };
135
136                let closure_args = ClosureArgs::new(
137                    interner,
138                    ClosureArgsParts {
139                        parent_args: parent_args.as_slice(),
140                        closure_kind_ty,
141                        closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(interner, sig),
142                        tupled_upvars_ty,
143                    },
144                );
145
146                let closure_id = InternedClosureId::new(self.db, closure_loc);
147
148                (Ty::new_closure(interner, closure_id.into(), closure_args.args), None)
149            }
150            ClosureKind::OldCoroutine(_) | ClosureKind::Coroutine { .. } => {
151                let yield_ty = match closure_kind {
152                    ClosureKind::OldCoroutine(_)
153                    | ClosureKind::Coroutine { kind: CoroutineKind::Gen, .. } => {
154                        let yield_ty = self.table.next_ty_var(closure_expr.into());
155                        self.require_type_is_sized(yield_ty, closure_expr.into());
156                        yield_ty
157                    }
158                    ClosureKind::Coroutine { kind: CoroutineKind::Async, .. } => {
159                        self.types.types.unit
160                    }
161                    ClosureKind::Coroutine { kind: CoroutineKind::AsyncGen, .. } => {
162                        let yield_ty = self.table.next_ty_var(closure_expr.into());
163                        self.require_type_is_sized(yield_ty, closure_expr.into());
164                        self.poll_option_ty(yield_ty)
165                    }
166                    _ => unreachable!(),
167                };
168
169                // Resume type defaults to `()` if the coroutine has no argument.
170                let resume_ty =
171                    liberated_sig.inputs().first().copied().unwrap_or(self.types.types.unit);
172
173                // Coroutines that come from coroutine closures have not yet determined
174                // their kind ty, so make a fresh infer var which will be constrained
175                // later during upvar analysis. Regular coroutines always have the kind
176                // ty of `().`
177                let kind_ty = match closure_kind {
178                    ClosureKind::Coroutine { source: CoroutineSource::Closure, .. } => {
179                        self.table.next_ty_var(closure_expr.into())
180                    }
181                    _ => self.types.types.unit,
182                };
183
184                let coroutine_args = CoroutineArgs::new(
185                    interner,
186                    CoroutineArgsParts {
187                        parent_args: parent_args.as_slice(),
188                        kind_ty,
189                        resume_ty,
190                        yield_ty,
191                        return_ty: liberated_sig.output(),
192                        tupled_upvars_ty,
193                    },
194                );
195
196                let coroutine_id = InternedCoroutineId::new(self.db, closure_loc);
197
198                (
199                    Ty::new_coroutine(interner, coroutine_id.into(), coroutine_args.args),
200                    Some((resume_ty, yield_ty)),
201                )
202            }
203            ClosureKind::CoroutineClosure(coroutine_kind) => {
204                let (bound_return_ty, bound_yield_ty) = match coroutine_kind {
205                    CoroutineKind::Gen => {
206                        (self.types.types.unit, self.table.next_ty_var(closure_expr.into()))
207                    }
208                    CoroutineKind::Async => {
209                        (bound_sig.skip_binder().output(), self.types.types.unit)
210                    }
211                    CoroutineKind::AsyncGen => {
212                        let yield_ty = self.table.next_ty_var(closure_expr.into());
213                        (self.types.types.unit, self.poll_option_ty(yield_ty))
214                    }
215                };
216
217                // Compute all of the variables that will be used to populate the coroutine.
218                let resume_ty = self.table.next_ty_var(closure_expr.into());
219
220                let closure_kind_ty = match expected_kind {
221                    Some(kind) => Ty::from_closure_kind(interner, kind),
222
223                    // Create a type variable (for now) to represent the closure kind.
224                    // It will be unified during the upvar inference phase (`upvar.rs`)
225                    None => self.table.next_ty_var(closure_expr.into()),
226                };
227
228                let coroutine_captures_by_ref_ty = self.table.next_ty_var(closure_expr.into());
229
230                let closure_args = CoroutineClosureArgs::new(
231                    interner,
232                    CoroutineClosureArgsParts {
233                        parent_args: parent_args.as_slice(),
234                        closure_kind_ty,
235                        signature_parts_ty: Ty::new_fn_ptr(
236                            interner,
237                            bound_sig.map_bound(|sig| {
238                                interner.mk_fn_sig(
239                                    [
240                                        resume_ty,
241                                        Ty::new_tup_from_iter(
242                                            interner,
243                                            sig.inputs().iter().copied(),
244                                        ),
245                                    ],
246                                    Ty::new_tup(interner, &[bound_yield_ty, bound_return_ty]),
247                                    sig.c_variadic(),
248                                    sig.safety(),
249                                    sig.abi(),
250                                )
251                            }),
252                        ),
253                        tupled_upvars_ty,
254                        coroutine_captures_by_ref_ty,
255                    },
256                );
257
258                let coroutine_kind_ty = match expected_kind {
259                    Some(kind) => Ty::from_coroutine_closure_kind(interner, kind),
260
261                    // Create a type variable (for now) to represent the closure kind.
262                    // It will be unified during the upvar inference phase (`upvar.rs`)
263                    None => self.table.next_ty_var(closure_expr.into()),
264                };
265
266                let coroutine_upvars_ty = self.table.next_ty_var(closure_expr.into());
267
268                let coroutine_closure_id = InternedCoroutineClosureId::new(self.db, closure_loc);
269
270                // We need to turn the liberated signature that we got from HIR, which
271                // looks something like `|Args...| -> T`, into a signature that is suitable
272                // for type checking the inner body of the closure, which always returns a
273                // coroutine. To do so, we use the `CoroutineClosureSignature` to compute
274                // the coroutine type, filling in the tupled_upvars_ty and kind_ty with infer
275                // vars which will get constrained during upvar analysis.
276                let coroutine_output_ty = closure_args
277                    .coroutine_closure_sig()
278                    .map_bound(|sig| {
279                        sig.to_coroutine(
280                            interner,
281                            parent_args.as_slice(),
282                            coroutine_kind_ty,
283                            interner.coroutine_for_closure(coroutine_closure_id.into()),
284                            coroutine_upvars_ty,
285                        )
286                    })
287                    .skip_binder();
288                liberated_sig = interner.mk_fn_sig(
289                    liberated_sig.inputs().iter().copied(),
290                    coroutine_output_ty,
291                    liberated_sig.c_variadic(),
292                    liberated_sig.safety(),
293                    liberated_sig.abi(),
294                );
295
296                (
297                    Ty::new_coroutine_closure(
298                        interner,
299                        coroutine_closure_id.into(),
300                        closure_args.args,
301                    ),
302                    None,
303                )
304            }
305        };
306
307        self.result.closures_data.insert(
308            closure_expr,
309            ClosureData {
310                liberated_sig: StoredFnSig::new(liberated_sig),
311                fake_reads: Box::default(),
312                min_captures: IndexMap::default(),
313            },
314        );
315
316        // Now go through the argument patterns
317        for (arg_pat, arg_ty) in args.iter().zip(liberated_sig.inputs()) {
318            self.infer_top_pat(*arg_pat, *arg_ty, PatOrigin::Param);
319        }
320
321        // FIXME: lift these out into a struct
322        let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
323        let prev_ret_ty = mem::replace(&mut self.return_ty, liberated_sig.output());
324        let prev_ret_coercion =
325            self.return_coercion.replace(CoerceMany::new(liberated_sig.output()));
326        let prev_resume_yield_tys = mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
327
328        self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
329            this.infer_return(body);
330        });
331
332        self.diverges = prev_diverges;
333        self.return_ty = prev_ret_ty;
334        self.return_coercion = prev_ret_coercion;
335        self.resume_yield_tys = prev_resume_yield_tys;
336
337        closure_ty
338    }
339
340    fn fn_trait_kind_from_def_id(&self, trait_id: TraitId) -> Option<rustc_type_ir::ClosureKind> {
341        match trait_id {
342            _ if self.lang_items.Fn == Some(trait_id) => Some(rustc_type_ir::ClosureKind::Fn),
343            _ if self.lang_items.FnMut == Some(trait_id) => Some(rustc_type_ir::ClosureKind::FnMut),
344            _ if self.lang_items.FnOnce == Some(trait_id) => {
345                Some(rustc_type_ir::ClosureKind::FnOnce)
346            }
347            _ => None,
348        }
349    }
350
351    fn async_fn_trait_kind_from_def_id(
352        &self,
353        trait_id: TraitId,
354    ) -> Option<rustc_type_ir::ClosureKind> {
355        match trait_id {
356            _ if self.lang_items.AsyncFn == Some(trait_id) => Some(rustc_type_ir::ClosureKind::Fn),
357            _ if self.lang_items.AsyncFnMut == Some(trait_id) => {
358                Some(rustc_type_ir::ClosureKind::FnMut)
359            }
360            _ if self.lang_items.AsyncFnOnce == Some(trait_id) => {
361                Some(rustc_type_ir::ClosureKind::FnOnce)
362            }
363            _ => None,
364        }
365    }
366
367    /// Given the expected type, figures out what it can about this closure we
368    /// are about to type check:
369    fn deduce_closure_signature(
370        &mut self,
371        closure_expr: ExprId,
372        expected_ty: Ty<'db>,
373        closure_kind: ClosureKind,
374    ) -> (Option<PolyFnSig<'db>>, Option<rustc_type_ir::ClosureKind>) {
375        match expected_ty.kind() {
376            TyKind::Alias(AliasTy { kind: rustc_type_ir::Opaque { def_id }, args, .. }) => self
377                .deduce_closure_signature_from_predicates(
378                    closure_expr,
379                    expected_ty,
380                    closure_kind,
381                    def_id
382                        .0
383                        .predicates(self.db)
384                        .iter_instantiated_copied(self.interner(), args.as_slice())
385                        .map(Unnormalized::skip_norm_wip)
386                        .map(|clause| clause.as_predicate()),
387                ),
388            TyKind::Dynamic(object_type, ..) => {
389                let sig = object_type.projection_bounds().into_iter().find_map(|pb| {
390                    let pb = pb.with_self_ty(self.interner(), Ty::new_unit(self.interner()));
391                    self.deduce_sig_from_projection(closure_expr, closure_kind, pb)
392                });
393                let kind = object_type
394                    .principal_def_id()
395                    .and_then(|did| self.fn_trait_kind_from_def_id(did.0));
396                (sig, kind)
397            }
398            TyKind::Infer(rustc_type_ir::TyVar(vid)) => self
399                .deduce_closure_signature_from_predicates(
400                    closure_expr,
401                    Ty::new_var(self.interner(), self.table.infer_ctxt.root_var(vid)),
402                    closure_kind,
403                    self.table.obligations_for_self_ty(vid).into_iter().map(|obl| obl.predicate),
404                ),
405            TyKind::FnPtr(sig_tys, hdr) => match closure_kind {
406                ClosureKind::Closure => {
407                    let expected_sig = sig_tys.with(hdr);
408                    (Some(expected_sig), Some(rustc_type_ir::ClosureKind::Fn))
409                }
410                ClosureKind::OldCoroutine(_)
411                | ClosureKind::Coroutine { .. }
412                | ClosureKind::CoroutineClosure(_) => (None, None),
413            },
414            _ => (None, None),
415        }
416    }
417
418    fn deduce_closure_signature_from_predicates(
419        &mut self,
420        closure_expr: ExprId,
421        expected_ty: Ty<'db>,
422        closure_kind: ClosureKind,
423        predicates: impl DoubleEndedIterator<Item = Predicate<'db>>,
424    ) -> (Option<PolyFnSig<'db>>, Option<rustc_type_ir::ClosureKind>) {
425        let mut expected_sig = None;
426        let mut expected_kind = None;
427
428        for pred in rustc_type_ir::elaborate::elaborate(
429            self.interner(),
430            // Reverse the obligations here, since `elaborate_*` uses a stack,
431            // and we want to keep inference generally in the same order of
432            // the registered obligations.
433            predicates.rev(),
434        )
435        // We only care about self bounds
436        .filter_only_self()
437        {
438            debug!(?pred);
439            let bound_predicate = pred.kind();
440
441            // Given a Projection predicate, we can potentially infer
442            // the complete signature.
443            if expected_sig.is_none()
444                && let PredicateKind::Clause(ClauseKind::Projection(proj_predicate)) =
445                    bound_predicate.skip_binder()
446            {
447                let inferred_sig = self.deduce_sig_from_projection(
448                    closure_expr,
449                    closure_kind,
450                    bound_predicate.rebind(proj_predicate),
451                );
452
453                // Make sure that we didn't infer a signature that mentions itself.
454                // This can happen when we elaborate certain supertrait bounds that
455                // mention projections containing the `Self` type. See #105401.
456                struct MentionsTy<'db> {
457                    expected_ty: Ty<'db>,
458                }
459                impl<'db> TypeVisitor<DbInterner<'db>> for MentionsTy<'db> {
460                    type Result = ControlFlow<()>;
461
462                    fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result {
463                        if t == self.expected_ty {
464                            ControlFlow::Break(())
465                        } else {
466                            t.super_visit_with(self)
467                        }
468                    }
469                }
470
471                // Don't infer a closure signature from a goal that names the closure type as this will
472                // (almost always) lead to occurs check errors later in type checking.
473                if let Some(inferred_sig) = inferred_sig {
474                    // In the new solver it is difficult to explicitly normalize the inferred signature as we
475                    // would have to manually handle universes and rewriting bound vars and placeholders back
476                    // and forth.
477                    //
478                    // Instead we take advantage of the fact that we relating an inference variable with an alias
479                    // will only instantiate the variable if the alias is rigid(*not quite). Concretely we:
480                    // - Create some new variable `?sig`
481                    // - Equate `?sig` with the unnormalized signature, e.g. `fn(<Foo<?x> as Trait>::Assoc)`
482                    // - Depending on whether `<Foo<?x> as Trait>::Assoc` is rigid, ambiguous or normalizeable,
483                    //   we will either wind up with `?sig=<Foo<?x> as Trait>::Assoc/?y/ConcreteTy` respectively.
484                    //
485                    // *: In cases where there are ambiguous aliases in the signature that make use of bound vars
486                    //    they will wind up present in `?sig` even though they are non-rigid.
487                    //
488                    //    This is a bit weird and means we may wind up discarding the goal due to it naming `expected_ty`
489                    //    even though the normalized form may not name `expected_ty`. However, this matches the existing
490                    //    behaviour of the old solver and would be technically a breaking change to fix.
491                    let generalized_fnptr_sig = self.table.next_ty_var(closure_expr.into());
492                    let inferred_fnptr_sig = Ty::new_fn_ptr(self.interner(), inferred_sig);
493                    // FIXME: Report diagnostics.
494                    _ = self
495                        .table
496                        .infer_ctxt
497                        .at(&ObligationCause::new(closure_expr), self.table.param_env)
498                        .eq(inferred_fnptr_sig, generalized_fnptr_sig)
499                        .map(|infer_ok| self.table.register_infer_ok(infer_ok));
500
501                    let resolved_sig = self.resolve_vars_if_possible(generalized_fnptr_sig);
502
503                    if resolved_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
504                        expected_sig = Some(resolved_sig.fn_sig(self.interner()));
505                    }
506                } else if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
507                    expected_sig = inferred_sig;
508                }
509            }
510
511            // Even if we can't infer the full signature, we may be able to
512            // infer the kind. This can occur when we elaborate a predicate
513            // like `F : Fn<A>`. Note that due to subtyping we could encounter
514            // many viable options, so pick the most restrictive.
515            let trait_def_id = match bound_predicate.skip_binder() {
516                PredicateKind::Clause(ClauseKind::Projection(data)) => {
517                    Some(data.projection_term.trait_def_id(self.interner()).0)
518                }
519                PredicateKind::Clause(ClauseKind::Trait(data)) => Some(data.def_id().0),
520                _ => None,
521            };
522
523            if let Some(trait_def_id) = trait_def_id {
524                let found_kind = match closure_kind {
525                    ClosureKind::Closure | ClosureKind::CoroutineClosure(CoroutineKind::Gen) => {
526                        self.fn_trait_kind_from_def_id(trait_def_id)
527                    }
528                    ClosureKind::CoroutineClosure(CoroutineKind::Async) => self
529                        .async_fn_trait_kind_from_def_id(trait_def_id)
530                        .or_else(|| self.fn_trait_kind_from_def_id(trait_def_id)),
531                    _ => None,
532                };
533
534                if let Some(found_kind) = found_kind {
535                    // always use the closure kind that is more permissive.
536                    match (expected_kind, found_kind) {
537                        (None, _) => expected_kind = Some(found_kind),
538                        (
539                            Some(rustc_type_ir::ClosureKind::FnMut),
540                            rustc_type_ir::ClosureKind::Fn,
541                        ) => expected_kind = Some(rustc_type_ir::ClosureKind::Fn),
542                        (
543                            Some(rustc_type_ir::ClosureKind::FnOnce),
544                            rustc_type_ir::ClosureKind::Fn | rustc_type_ir::ClosureKind::FnMut,
545                        ) => expected_kind = Some(found_kind),
546                        _ => {}
547                    }
548                }
549            }
550        }
551
552        (expected_sig, expected_kind)
553    }
554
555    /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
556    /// everything we need to know about a closure or coroutine.
557    ///
558    /// The `cause_span` should be the span that caused us to
559    /// have this expected signature, or `None` if we can't readily
560    /// know that.
561    fn deduce_sig_from_projection(
562        &mut self,
563        closure_expr: ExprId,
564        closure_kind: ClosureKind,
565        projection: PolyProjectionPredicate<'db>,
566    ) -> Option<PolyFnSig<'db>> {
567        let SolverDefId::TypeAliasId(def_id) = projection.item_def_id() else { unreachable!() };
568
569        // For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
570        // for closures and async closures, respectively.
571        match closure_kind {
572            ClosureKind::Closure if Some(def_id) == self.lang_items.FnOnceOutput => {
573                self.extract_sig_from_projection(projection)
574            }
575            ClosureKind::CoroutineClosure(CoroutineKind::Async)
576                if Some(def_id) == self.lang_items.AsyncFnOnceOutput =>
577            {
578                self.extract_sig_from_projection(projection)
579            }
580            // It's possible we've passed the closure to a (somewhat out-of-fashion)
581            // `F: FnOnce() -> Fut, Fut: Future<Output = T>` style bound. Let's still
582            // guide inference here, since it's beneficial for the user.
583            ClosureKind::CoroutineClosure(CoroutineKind::Async)
584                if Some(def_id) == self.lang_items.FnOnceOutput =>
585            {
586                self.extract_sig_from_projection_and_future_bound(closure_expr, projection)
587            }
588            _ => None,
589        }
590    }
591
592    /// Given an `FnOnce::Output` or `AsyncFn::Output` projection, extract the args
593    /// and return type to infer a `PolyFnSig` for the closure.
594    fn extract_sig_from_projection(
595        &self,
596        projection: PolyProjectionPredicate<'db>,
597    ) -> Option<PolyFnSig<'db>> {
598        let projection = self.resolve_vars_if_possible(projection);
599
600        let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
601        debug!(?arg_param_ty);
602
603        let TyKind::Tuple(input_tys) = arg_param_ty.kind() else {
604            return None;
605        };
606
607        // Since this is a return parameter type it is safe to unwrap.
608        let ret_param_ty = projection.skip_binder().term.expect_type();
609        debug!(?ret_param_ty);
610
611        let sig =
612            projection.rebind(self.interner().mk_fn_sig_safe_rust_abi(input_tys, ret_param_ty));
613
614        Some(sig)
615    }
616
617    /// When an async closure is passed to a function that has a "two-part" `Fn`
618    /// and `Future` trait bound, like:
619    ///
620    /// ```rust
621    /// use std::future::Future;
622    ///
623    /// fn not_exactly_an_async_closure<F, Fut>(_f: F)
624    /// where
625    ///     F: FnOnce(String, u32) -> Fut,
626    ///     Fut: Future<Output = i32>,
627    /// {}
628    /// ```
629    ///
630    /// The we want to be able to extract the signature to guide inference in the async
631    /// closure. We will have two projection predicates registered in this case. First,
632    /// we identify the `FnOnce<Args, Output = ?Fut>` bound, and if the output type is
633    /// an inference variable `?Fut`, we check if that is bounded by a `Future<Output = Ty>`
634    /// projection.
635    ///
636    /// This function is actually best-effort with the return type; if we don't find a
637    /// `Future` projection, we still will return arguments that we extracted from the `FnOnce`
638    /// projection, and the output will be an unconstrained type variable instead.
639    fn extract_sig_from_projection_and_future_bound(
640        &mut self,
641        closure_expr: ExprId,
642        projection: PolyProjectionPredicate<'db>,
643    ) -> Option<PolyFnSig<'db>> {
644        let projection = self.resolve_vars_if_possible(projection);
645
646        let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
647        debug!(?arg_param_ty);
648
649        let TyKind::Tuple(input_tys) = arg_param_ty.kind() else {
650            return None;
651        };
652
653        // If the return type is a type variable, look for bounds on it.
654        // We could theoretically support other kinds of return types here,
655        // but none of them would be useful, since async closures return
656        // concrete anonymous future types, and their futures are not coerced
657        // into any other type within the body of the async closure.
658        let TyKind::Infer(rustc_type_ir::TyVar(return_vid)) =
659            projection.skip_binder().term.expect_type().kind()
660        else {
661            return None;
662        };
663
664        // FIXME: We may want to elaborate here, though I assume this will be exceedingly rare.
665        let mut return_ty = None;
666        for bound in self.table.obligations_for_self_ty(return_vid) {
667            if let PredicateKind::Clause(ClauseKind::Projection(ret_projection)) =
668                bound.predicate.kind().skip_binder()
669                && let ret_projection = bound.predicate.kind().rebind(ret_projection)
670                && let Some(ret_projection) = ret_projection.no_bound_vars()
671                && let TermId::TypeAliasId(assoc_type) = ret_projection.def_id().0
672                && Some(assoc_type) == self.lang_items.FutureOutput
673            {
674                return_ty = Some(ret_projection.term.expect_type());
675                break;
676            }
677        }
678
679        // SUBTLE: If we didn't find a `Future<Output = ...>` bound for the return
680        // vid, we still want to attempt to provide inference guidance for the async
681        // closure's arguments. Instantiate a new vid to plug into the output type.
682        //
683        // You may be wondering, what if it's higher-ranked? Well, given that we
684        // found a type variable for the `FnOnce::Output` projection above, we know
685        // that the output can't mention any of the vars.
686        //
687        // Also note that we use a fresh var here for the signature since the signature
688        // records the output of the *future*, and `return_vid` above is the type
689        // variable of the future, not its output.
690        //
691        // FIXME: We probably should store this signature inference output in a way
692        // that does not misuse a `FnSig` type, but that can be done separately.
693        let return_ty = return_ty.unwrap_or_else(|| self.table.next_ty_var(closure_expr.into()));
694
695        let sig = projection.rebind(self.interner().mk_fn_sig_safe_rust_abi(input_tys, return_ty));
696
697        Some(sig)
698    }
699
700    fn sig_of_closure(
701        &mut self,
702        closure_expr: ExprId,
703        decl_inputs: &[PatId],
704        decl_input_tys: &[Option<TypeRefId>],
705        decl_output_ty: Option<TypeRefId>,
706        expected_sig: Option<PolyFnSig<'db>>,
707        closure_kind: ClosureKind,
708    ) -> ClosureSignatures<'db> {
709        if let Some(e) = expected_sig {
710            self.sig_of_closure_with_expectation(
711                closure_expr,
712                decl_inputs,
713                decl_input_tys,
714                decl_output_ty,
715                e,
716                closure_kind,
717            )
718        } else {
719            self.sig_of_closure_no_expectation(
720                closure_expr,
721                decl_input_tys,
722                decl_output_ty,
723                closure_kind,
724            )
725        }
726    }
727
728    /// If there is no expected signature, then we will convert the
729    /// types that the user gave into a signature.
730    fn sig_of_closure_no_expectation(
731        &mut self,
732        closure_expr: ExprId,
733        decl_inputs: &[Option<TypeRefId>],
734        decl_output: Option<TypeRefId>,
735        closure_kind: ClosureKind,
736    ) -> ClosureSignatures<'db> {
737        let bound_sig =
738            self.supplied_sig_of_closure(closure_expr, decl_inputs, decl_output, closure_kind);
739
740        self.closure_sigs(bound_sig)
741    }
742
743    /// Invoked to compute the signature of a closure expression. This
744    /// combines any user-provided type annotations (e.g., `|x: u32|
745    /// -> u32 { .. }`) with the expected signature.
746    ///
747    /// The approach is as follows:
748    ///
749    /// - Let `S` be the (higher-ranked) signature that we derive from the user's annotations.
750    /// - Let `E` be the (higher-ranked) signature that we derive from the expectations, if any.
751    ///   - If we have no expectation `E`, then the signature of the closure is `S`.
752    ///   - Otherwise, the signature of the closure is E. Moreover:
753    ///     - Skolemize the late-bound regions in `E`, yielding `E'`.
754    ///     - Instantiate all the late-bound regions bound in the closure within `S`
755    ///       with fresh (existential) variables, yielding `S'`
756    ///     - Require that `E' = S'`
757    ///       - We could use some kind of subtyping relationship here,
758    ///         I imagine, but equality is easier and works fine for
759    ///         our purposes.
760    ///
761    /// The key intuition here is that the user's types must be valid
762    /// from "the inside" of the closure, but the expectation
763    /// ultimately drives the overall signature.
764    ///
765    /// # Examples
766    ///
767    /// ```ignore (illustrative)
768    /// fn with_closure<F>(_: F)
769    ///   where F: Fn(&u32) -> &u32 { .. }
770    ///
771    /// with_closure(|x: &u32| { ... })
772    /// ```
773    ///
774    /// Here:
775    /// - E would be `fn(&u32) -> &u32`.
776    /// - S would be `fn(&u32) -> ?T`
777    /// - E' is `&'!0 u32 -> &'!0 u32`
778    /// - S' is `&'?0 u32 -> ?T`
779    ///
780    /// S' can be unified with E' with `['?0 = '!0, ?T = &'!10 u32]`.
781    ///
782    /// # Arguments
783    ///
784    /// - `expr_def_id`: the `LocalDefId` of the closure expression
785    /// - `decl`: the HIR declaration of the closure
786    /// - `body`: the body of the closure
787    /// - `expected_sig`: the expected signature (if any). Note that
788    ///   this is missing a binder: that is, there may be late-bound
789    ///   regions with depth 1, which are bound then by the closure.
790    fn sig_of_closure_with_expectation(
791        &mut self,
792        closure_expr: ExprId,
793        decl_inputs: &[PatId],
794        decl_input_tys: &[Option<TypeRefId>],
795        decl_output_ty: Option<TypeRefId>,
796        expected_sig: PolyFnSig<'db>,
797        closure_kind: ClosureKind,
798    ) -> ClosureSignatures<'db> {
799        // Watch out for some surprises and just ignore the
800        // expectation if things don't see to match up with what we
801        // expect.
802        if expected_sig.c_variadic() {
803            return self.sig_of_closure_no_expectation(
804                closure_expr,
805                decl_input_tys,
806                decl_output_ty,
807                closure_kind,
808            );
809        } else if expected_sig.skip_binder().inputs_and_output.len() != decl_input_tys.len() + 1 {
810            return self.sig_of_closure_with_mismatched_number_of_arguments(
811                decl_input_tys,
812                decl_output_ty,
813            );
814        }
815
816        // Create a `PolyFnSig`. Note the oddity that late bound
817        // regions appearing free in `expected_sig` are now bound up
818        // in this binder we are creating.
819        assert!(!expected_sig.skip_binder().has_vars_bound_above(rustc_type_ir::INNERMOST));
820        let bound_sig = expected_sig.map_bound(|sig| {
821            self.interner().mk_fn_sig(
822                sig.inputs().iter().copied(),
823                sig.output(),
824                sig.c_variadic(),
825                Safety::Safe,
826                ExternAbi::RustCall,
827            )
828        });
829
830        // `deduce_expectations_from_expected_type` introduces
831        // late-bound lifetimes defined elsewhere, which we now
832        // anonymize away, so as not to confuse the user.
833        let bound_sig = self.interner().anonymize_bound_vars(bound_sig);
834
835        let closure_sigs = self.closure_sigs(bound_sig);
836
837        // Up till this point, we have ignored the annotations that the user
838        // gave. This function will check that they unify successfully.
839        // Along the way, it also writes out entries for types that the user
840        // wrote into our typeck results, which are then later used by the privacy
841        // check.
842        match self.merge_supplied_sig_with_expectation(
843            closure_expr,
844            decl_inputs,
845            decl_input_tys,
846            decl_output_ty,
847            closure_sigs,
848            closure_kind,
849        ) {
850            Ok(infer_ok) => self.table.register_infer_ok(infer_ok),
851            Err(_) => self.sig_of_closure_no_expectation(
852                closure_expr,
853                decl_input_tys,
854                decl_output_ty,
855                closure_kind,
856            ),
857        }
858    }
859
860    fn sig_of_closure_with_mismatched_number_of_arguments(
861        &mut self,
862        decl_inputs: &[Option<TypeRefId>],
863        decl_output: Option<TypeRefId>,
864    ) -> ClosureSignatures<'db> {
865        let error_sig = self.error_sig_of_closure(decl_inputs, decl_output);
866
867        self.closure_sigs(error_sig)
868    }
869
870    /// Enforce the user's types against the expectation. See
871    /// `sig_of_closure_with_expectation` for details on the overall
872    /// strategy.
873    fn merge_supplied_sig_with_expectation(
874        &mut self,
875        closure_expr: ExprId,
876        decl_inputs: &[PatId],
877        decl_input_tys: &[Option<TypeRefId>],
878        decl_output_ty: Option<TypeRefId>,
879        mut expected_sigs: ClosureSignatures<'db>,
880        closure_kind: ClosureKind,
881    ) -> InferResult<'db, ClosureSignatures<'db>> {
882        // Get the signature S that the user gave.
883        //
884        // (See comment on `sig_of_closure_with_expectation` for the
885        // meaning of these letters.)
886        let supplied_sig = self.supplied_sig_of_closure(
887            closure_expr,
888            decl_input_tys,
889            decl_output_ty,
890            closure_kind,
891        );
892
893        debug!(?supplied_sig);
894
895        // FIXME(#45727): As discussed in [this comment][c1], naively
896        // forcing equality here actually results in suboptimal error
897        // messages in some cases. For now, if there would have been
898        // an obvious error, we fallback to declaring the type of the
899        // closure to be the one the user gave, which allows other
900        // error message code to trigger.
901        //
902        // However, I think [there is potential to do even better
903        // here][c2], since in *this* code we have the precise span of
904        // the type parameter in question in hand when we report the
905        // error.
906        //
907        // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
908        // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
909        self.table.commit_if_ok(|table| {
910            let mut all_obligations = PredicateObligations::new();
911            let supplied_sig = table.infer_ctxt.instantiate_binder_with_fresh_vars(
912                closure_expr.into(),
913                BoundRegionConversionTime::FnCall,
914                supplied_sig,
915            );
916
917            // The liberated version of this signature should be a subtype
918            // of the liberated form of the expectation.
919            for ((decl_input, supplied_ty), expected_ty) in iter::zip(
920                iter::zip(decl_inputs, supplied_sig.inputs().iter().copied()),
921                expected_sigs.liberated_sig.inputs().iter().copied(),
922            ) {
923                // Check that E' = S'.
924                let cause = ObligationCause::new(*decl_input);
925                let InferOk { value: (), obligations } =
926                    table.infer_ctxt.at(&cause, table.param_env).eq(expected_ty, supplied_ty)?;
927                all_obligations.extend(obligations);
928            }
929
930            let supplied_output_ty = supplied_sig.output();
931            let cause = ObligationCause::new(
932                decl_output_ty.map(Span::TypeRefId).unwrap_or(closure_expr.into()),
933            );
934            let InferOk { value: (), obligations } =
935                table
936                    .infer_ctxt
937                    .at(&cause, table.param_env)
938                    .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
939            all_obligations.extend(obligations);
940
941            let inputs =
942                supplied_sig.inputs().iter().copied().map(|ty| table.resolve_vars_if_possible(ty));
943
944            expected_sigs.liberated_sig = table.interner().mk_fn_sig(
945                inputs,
946                supplied_output_ty,
947                expected_sigs.liberated_sig.c_variadic(),
948                Safety::Safe,
949                ExternAbi::RustCall,
950            );
951
952            Ok(InferOk { value: expected_sigs, obligations: all_obligations })
953        })
954    }
955
956    /// If there is no expected signature, then we will convert the
957    /// types that the user gave into a signature.
958    ///
959    /// Also, record this closure signature for later.
960    fn supplied_sig_of_closure(
961        &mut self,
962        closure_expr: ExprId,
963        decl_inputs: &[Option<TypeRefId>],
964        decl_output: Option<TypeRefId>,
965        closure_kind: ClosureKind,
966    ) -> PolyFnSig<'db> {
967        let interner = self.interner();
968
969        let supplied_return = match decl_output {
970            Some(output) => self.make_body_ty(output),
971            None => match closure_kind {
972                // In the case of the async block that we create for a function body,
973                // we expect the return type of the block to match that of the enclosing
974                // function.
975                ClosureKind::Coroutine {
976                    kind: CoroutineKind::Async,
977                    source: CoroutineSource::Fn,
978                } => {
979                    debug!("closure is async fn body");
980                    self.deduce_future_output_from_obligations(closure_expr).unwrap_or_else(|| {
981                        // AFAIK, deducing the future output
982                        // always succeeds *except* in error cases
983                        // like #65159. I'd like to return Error
984                        // here, but I can't because I can't
985                        // easily (and locally) prove that we
986                        // *have* reported an
987                        // error. --nikomatsakis
988                        self.table.next_ty_var(closure_expr.into())
989                    })
990                }
991                // All `gen {}` and `async gen {}` must return unit.
992                ClosureKind::Coroutine {
993                    kind: CoroutineKind::Gen | CoroutineKind::AsyncGen,
994                    ..
995                } => self.types.types.unit,
996
997                // For async blocks, we just fall back to `_` here.
998                // For closures/coroutines, we know nothing about the return
999                // type unless it was supplied.
1000                ClosureKind::Coroutine { kind: CoroutineKind::Async, .. }
1001                | ClosureKind::OldCoroutine(_)
1002                | ClosureKind::Closure
1003                | ClosureKind::CoroutineClosure(_) => self.table.next_ty_var(closure_expr.into()),
1004            },
1005        };
1006        // First, convert the types that the user supplied (if any).
1007        let supplied_arguments = decl_inputs.iter().map(|&input| match input {
1008            Some(input) => self.make_body_ty(input),
1009            None => self.table.next_ty_var(closure_expr.into()),
1010        });
1011
1012        Binder::dummy(interner.mk_fn_sig(
1013            supplied_arguments,
1014            supplied_return,
1015            false,
1016            Safety::Safe,
1017            ExternAbi::RustCall,
1018        ))
1019    }
1020
1021    /// Invoked when we are translating the coroutine that results
1022    /// from desugaring an `async fn`. Returns the "sugared" return
1023    /// type of the `async fn` -- that is, the return type that the
1024    /// user specified. The "desugared" return type is an `impl
1025    /// Future<Output = T>`, so we do this by searching through the
1026    /// obligations to extract the `T`.
1027    #[instrument(skip(self), level = "debug", ret)]
1028    fn deduce_future_output_from_obligations(&mut self, body_def_id: ExprId) -> Option<Ty<'db>> {
1029        let ret_coercion = self
1030            .return_coercion
1031            .as_ref()
1032            .unwrap_or_else(|| panic!("async fn coroutine outside of a fn"));
1033
1034        let ret_ty = ret_coercion.expected_ty();
1035        let ret_ty = self.table.resolve_vars_with_obligations(ret_ty);
1036
1037        let get_future_output = |predicate: Predicate<'db>| {
1038            // Search for a pending obligation like
1039            //
1040            // `<R as Future>::Output = T`
1041            //
1042            // where R is the return type we are expecting. This type `T`
1043            // will be our output.
1044            let bound_predicate = predicate.kind();
1045            if let PredicateKind::Clause(ClauseKind::Projection(proj_predicate)) =
1046                bound_predicate.skip_binder()
1047            {
1048                self.deduce_future_output_from_projection(bound_predicate.rebind(proj_predicate))
1049            } else {
1050                None
1051            }
1052        };
1053
1054        let output_ty = match ret_ty.kind() {
1055            TyKind::Infer(InferTy::TyVar(ret_vid)) => self
1056                .table
1057                .obligations_for_self_ty(ret_vid)
1058                .into_iter()
1059                .find_map(|obligation| get_future_output(obligation.predicate))?,
1060            TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { .. }, .. }) => {
1061                return Some(self.types.types.error);
1062            }
1063            TyKind::Alias(AliasTy { kind: AliasTyKind::Opaque { def_id }, args, .. }) => def_id
1064                .0
1065                .predicates(self.db)
1066                .iter_instantiated_copied(self.interner(), &args)
1067                .map(Unnormalized::skip_norm_wip)
1068                .find_map(|p| get_future_output(p.as_predicate()))?,
1069            TyKind::Error(_) => return Some(ret_ty),
1070            _ => {
1071                panic!("invalid async fn coroutine return type: {ret_ty:?}")
1072            }
1073        };
1074
1075        Some(output_ty)
1076    }
1077
1078    /// Given a projection like
1079    ///
1080    /// `<X as Future>::Output = T`
1081    ///
1082    /// where `X` is some type that has no late-bound regions, returns
1083    /// `Some(T)`. If the projection is for some other trait, returns
1084    /// `None`.
1085    fn deduce_future_output_from_projection(
1086        &self,
1087        predicate: PolyProjectionPredicate<'db>,
1088    ) -> Option<Ty<'db>> {
1089        debug!("deduce_future_output_from_projection(predicate={:?})", predicate);
1090
1091        // We do not expect any bound regions in our predicate, so
1092        // skip past the bound vars.
1093        let Some(predicate) = predicate.no_bound_vars() else {
1094            debug!("deduce_future_output_from_projection: has late-bound regions");
1095            return None;
1096        };
1097
1098        // Check that this is a projection from the `Future` trait.
1099        let trait_def_id = predicate.projection_term.trait_def_id(self.interner()).0;
1100        if Some(trait_def_id) != self.lang_items.Future {
1101            debug!("deduce_future_output_from_projection: not a future");
1102            return None;
1103        }
1104
1105        // The `Future` trait has only one associated item, `Output`,
1106        // so check that this is what we see.
1107        let output_assoc_item = self.lang_items.FutureOutput;
1108        if output_assoc_item.map(Into::into) != Some(predicate.def_id().0) {
1109            panic!(
1110                "projecting associated item `{:?}` from future, which is not Output `{:?}`",
1111                predicate.projection_term.kind(self.interner()),
1112                output_assoc_item,
1113            );
1114        }
1115
1116        // Extract the type from the projection. Note that there can
1117        // be no bound variables in this type because the "self type"
1118        // does not have any regions in it.
1119        let output_ty = self.resolve_vars_if_possible(predicate.term);
1120        debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
1121        // This is a projection on a Fn trait so will always be a type.
1122        Some(output_ty.expect_type())
1123    }
1124
1125    /// Converts the types that the user supplied, in case that doing
1126    /// so should yield an error, but returns back a signature where
1127    /// all parameters are of type `ty::Error`.
1128    fn error_sig_of_closure(
1129        &mut self,
1130        decl_inputs: &[Option<TypeRefId>],
1131        decl_output: Option<TypeRefId>,
1132    ) -> PolyFnSig<'db> {
1133        let interner = self.interner();
1134        let err_ty = Ty::new_error(interner, ErrorGuaranteed);
1135
1136        if let Some(output) = decl_output {
1137            self.make_body_ty(output);
1138        }
1139        let supplied_arguments = decl_inputs.iter().map(|&input| match input {
1140            Some(input) => {
1141                self.make_body_ty(input);
1142                err_ty
1143            }
1144            None => err_ty,
1145        });
1146
1147        let result = Binder::dummy(interner.mk_fn_sig(
1148            supplied_arguments,
1149            err_ty,
1150            false,
1151            Safety::Safe,
1152            ExternAbi::RustCall,
1153        ));
1154
1155        debug!("supplied_sig_of_closure: result={:?}", result);
1156
1157        result
1158    }
1159
1160    fn closure_sigs(&self, bound_sig: PolyFnSig<'db>) -> ClosureSignatures<'db> {
1161        // TODO: def id needs to be changed?
1162        let liberated_sig =
1163            self.interner().liberate_late_bound_regions(self.owner.into(), bound_sig);
1164        ClosureSignatures { bound_sig, liberated_sig }
1165    }
1166}