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, unify::UseSubtyping};
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 = interner.liberate_late_bound_regions(
277                    self.owner.into(),
278                    closure_args.coroutine_closure_sig().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                );
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
404                        .obligations_for_self_ty(vid, UseSubtyping::No)
405                        .into_iter()
406                        .map(|obl| obl.predicate),
407                ),
408            TyKind::FnPtr(sig_tys, hdr) => match closure_kind {
409                ClosureKind::Closure => {
410                    let expected_sig = sig_tys.with(hdr);
411                    (Some(expected_sig), Some(rustc_type_ir::ClosureKind::Fn))
412                }
413                ClosureKind::OldCoroutine(_)
414                | ClosureKind::Coroutine { .. }
415                | ClosureKind::CoroutineClosure(_) => (None, None),
416            },
417            _ => (None, None),
418        }
419    }
420
421    fn deduce_closure_signature_from_predicates(
422        &mut self,
423        closure_expr: ExprId,
424        expected_ty: Ty<'db>,
425        closure_kind: ClosureKind,
426        predicates: impl DoubleEndedIterator<Item = Predicate<'db>>,
427    ) -> (Option<PolyFnSig<'db>>, Option<rustc_type_ir::ClosureKind>) {
428        let mut expected_sig = None;
429        let mut expected_kind = None;
430
431        for pred in rustc_type_ir::elaborate::elaborate(
432            self.interner(),
433            // Reverse the obligations here, since `elaborate_*` uses a stack,
434            // and we want to keep inference generally in the same order of
435            // the registered obligations.
436            predicates.rev(),
437        )
438        // We only care about self bounds
439        .filter_only_self()
440        {
441            debug!(?pred);
442            let bound_predicate = pred.kind();
443
444            // Given a Projection predicate, we can potentially infer
445            // the complete signature.
446            if expected_sig.is_none()
447                && let PredicateKind::Clause(ClauseKind::Projection(proj_predicate)) =
448                    bound_predicate.skip_binder()
449            {
450                let inferred_sig = self.deduce_sig_from_projection(
451                    closure_expr,
452                    closure_kind,
453                    bound_predicate.rebind(proj_predicate),
454                );
455
456                // Make sure that we didn't infer a signature that mentions itself.
457                // This can happen when we elaborate certain supertrait bounds that
458                // mention projections containing the `Self` type. See #105401.
459                struct MentionsTy<'db> {
460                    expected_ty: Ty<'db>,
461                }
462                impl<'db> TypeVisitor<DbInterner<'db>> for MentionsTy<'db> {
463                    type Result = ControlFlow<()>;
464
465                    fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result {
466                        if t == self.expected_ty {
467                            ControlFlow::Break(())
468                        } else {
469                            t.super_visit_with(self)
470                        }
471                    }
472                }
473
474                // Don't infer a closure signature from a goal that names the closure type as this will
475                // (almost always) lead to occurs check errors later in type checking.
476                if let Some(inferred_sig) = inferred_sig {
477                    // In the new solver it is difficult to explicitly normalize the inferred signature as we
478                    // would have to manually handle universes and rewriting bound vars and placeholders back
479                    // and forth.
480                    //
481                    // Instead we take advantage of the fact that we relating an inference variable with an alias
482                    // will only instantiate the variable if the alias is rigid(*not quite). Concretely we:
483                    // - Create some new variable `?sig`
484                    // - Equate `?sig` with the unnormalized signature, e.g. `fn(<Foo<?x> as Trait>::Assoc)`
485                    // - Depending on whether `<Foo<?x> as Trait>::Assoc` is rigid, ambiguous or normalizeable,
486                    //   we will either wind up with `?sig=<Foo<?x> as Trait>::Assoc/?y/ConcreteTy` respectively.
487                    //
488                    // *: In cases where there are ambiguous aliases in the signature that make use of bound vars
489                    //    they will wind up present in `?sig` even though they are non-rigid.
490                    //
491                    //    This is a bit weird and means we may wind up discarding the goal due to it naming `expected_ty`
492                    //    even though the normalized form may not name `expected_ty`. However, this matches the existing
493                    //    behaviour of the old solver and would be technically a breaking change to fix.
494                    let generalized_fnptr_sig = self.table.next_ty_var(closure_expr.into());
495                    let inferred_fnptr_sig = Ty::new_fn_ptr(self.interner(), inferred_sig);
496                    // FIXME: Report diagnostics.
497                    _ = self
498                        .table
499                        .infer_ctxt
500                        .at(&ObligationCause::new(closure_expr), self.table.param_env)
501                        .eq(inferred_fnptr_sig, generalized_fnptr_sig)
502                        .map(|infer_ok| self.table.register_infer_ok(infer_ok));
503
504                    let resolved_sig = self.resolve_vars_if_possible(generalized_fnptr_sig);
505
506                    if resolved_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
507                        expected_sig = Some(resolved_sig.fn_sig(self.interner()));
508                    }
509                } else if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
510                    expected_sig = inferred_sig;
511                }
512            }
513
514            // Even if we can't infer the full signature, we may be able to
515            // infer the kind. This can occur when we elaborate a predicate
516            // like `F : Fn<A>`. Note that due to subtyping we could encounter
517            // many viable options, so pick the most restrictive.
518            let trait_def_id = match bound_predicate.skip_binder() {
519                PredicateKind::Clause(ClauseKind::Projection(data)) => {
520                    Some(data.projection_term.trait_def_id(self.interner()).0)
521                }
522                PredicateKind::Clause(ClauseKind::Trait(data)) => Some(data.def_id().0),
523                _ => None,
524            };
525
526            if let Some(trait_def_id) = trait_def_id {
527                let found_kind = match closure_kind {
528                    ClosureKind::Closure | ClosureKind::CoroutineClosure(CoroutineKind::Gen) => {
529                        self.fn_trait_kind_from_def_id(trait_def_id)
530                    }
531                    ClosureKind::CoroutineClosure(CoroutineKind::Async) => self
532                        .async_fn_trait_kind_from_def_id(trait_def_id)
533                        .or_else(|| self.fn_trait_kind_from_def_id(trait_def_id)),
534                    _ => None,
535                };
536
537                if let Some(found_kind) = found_kind {
538                    // always use the closure kind that is more permissive.
539                    match (expected_kind, found_kind) {
540                        (None, _) => expected_kind = Some(found_kind),
541                        (
542                            Some(rustc_type_ir::ClosureKind::FnMut),
543                            rustc_type_ir::ClosureKind::Fn,
544                        ) => expected_kind = Some(rustc_type_ir::ClosureKind::Fn),
545                        (
546                            Some(rustc_type_ir::ClosureKind::FnOnce),
547                            rustc_type_ir::ClosureKind::Fn | rustc_type_ir::ClosureKind::FnMut,
548                        ) => expected_kind = Some(found_kind),
549                        _ => {}
550                    }
551                }
552            }
553        }
554
555        (expected_sig, expected_kind)
556    }
557
558    /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
559    /// everything we need to know about a closure or coroutine.
560    ///
561    /// The `cause_span` should be the span that caused us to
562    /// have this expected signature, or `None` if we can't readily
563    /// know that.
564    fn deduce_sig_from_projection(
565        &mut self,
566        closure_expr: ExprId,
567        closure_kind: ClosureKind,
568        projection: PolyProjectionPredicate<'db>,
569    ) -> Option<PolyFnSig<'db>> {
570        let SolverDefId::TypeAliasId(def_id) = projection.item_def_id() else { unreachable!() };
571
572        // For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
573        // for closures and async closures, respectively.
574        match closure_kind {
575            ClosureKind::Closure if Some(def_id) == self.lang_items.FnOnceOutput => {
576                self.extract_sig_from_projection(projection)
577            }
578            ClosureKind::CoroutineClosure(CoroutineKind::Async)
579                if Some(def_id) == self.lang_items.AsyncFnOnceOutput =>
580            {
581                self.extract_sig_from_projection(projection)
582            }
583            // It's possible we've passed the closure to a (somewhat out-of-fashion)
584            // `F: FnOnce() -> Fut, Fut: Future<Output = T>` style bound. Let's still
585            // guide inference here, since it's beneficial for the user.
586            ClosureKind::CoroutineClosure(CoroutineKind::Async)
587                if Some(def_id) == self.lang_items.FnOnceOutput =>
588            {
589                self.extract_sig_from_projection_and_future_bound(closure_expr, projection)
590            }
591            _ => None,
592        }
593    }
594
595    /// Given an `FnOnce::Output` or `AsyncFn::Output` projection, extract the args
596    /// and return type to infer a `PolyFnSig` for the closure.
597    fn extract_sig_from_projection(
598        &self,
599        projection: PolyProjectionPredicate<'db>,
600    ) -> Option<PolyFnSig<'db>> {
601        let projection = self.resolve_vars_if_possible(projection);
602
603        let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
604        debug!(?arg_param_ty);
605
606        let TyKind::Tuple(input_tys) = arg_param_ty.kind() else {
607            return None;
608        };
609
610        // Since this is a return parameter type it is safe to unwrap.
611        let ret_param_ty = projection.skip_binder().term.expect_type();
612        debug!(?ret_param_ty);
613
614        let sig =
615            projection.rebind(self.interner().mk_fn_sig_safe_rust_abi(input_tys, ret_param_ty));
616
617        Some(sig)
618    }
619
620    /// When an async closure is passed to a function that has a "two-part" `Fn`
621    /// and `Future` trait bound, like:
622    ///
623    /// ```rust
624    /// use std::future::Future;
625    ///
626    /// fn not_exactly_an_async_closure<F, Fut>(_f: F)
627    /// where
628    ///     F: FnOnce(String, u32) -> Fut,
629    ///     Fut: Future<Output = i32>,
630    /// {}
631    /// ```
632    ///
633    /// The we want to be able to extract the signature to guide inference in the async
634    /// closure. We will have two projection predicates registered in this case. First,
635    /// we identify the `FnOnce<Args, Output = ?Fut>` bound, and if the output type is
636    /// an inference variable `?Fut`, we check if that is bounded by a `Future<Output = Ty>`
637    /// projection.
638    ///
639    /// This function is actually best-effort with the return type; if we don't find a
640    /// `Future` projection, we still will return arguments that we extracted from the `FnOnce`
641    /// projection, and the output will be an unconstrained type variable instead.
642    fn extract_sig_from_projection_and_future_bound(
643        &mut self,
644        closure_expr: ExprId,
645        projection: PolyProjectionPredicate<'db>,
646    ) -> Option<PolyFnSig<'db>> {
647        let projection = self.resolve_vars_if_possible(projection);
648
649        let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1);
650        debug!(?arg_param_ty);
651
652        let TyKind::Tuple(input_tys) = arg_param_ty.kind() else {
653            return None;
654        };
655
656        // If the return type is a type variable, look for bounds on it.
657        // We could theoretically support other kinds of return types here,
658        // but none of them would be useful, since async closures return
659        // concrete anonymous future types, and their futures are not coerced
660        // into any other type within the body of the async closure.
661        let TyKind::Infer(rustc_type_ir::TyVar(return_vid)) =
662            projection.skip_binder().term.expect_type().kind()
663        else {
664            return None;
665        };
666
667        // FIXME: We may want to elaborate here, though I assume this will be exceedingly rare.
668        let mut return_ty = None;
669        for bound in self.table.obligations_for_self_ty(return_vid, UseSubtyping::No) {
670            if let PredicateKind::Clause(ClauseKind::Projection(ret_projection)) =
671                bound.predicate.kind().skip_binder()
672                && let ret_projection = bound.predicate.kind().rebind(ret_projection)
673                && let Some(ret_projection) = ret_projection.no_bound_vars()
674                && let TermId::TypeAliasId(assoc_type) = ret_projection.def_id().0
675                && Some(assoc_type) == self.lang_items.FutureOutput
676            {
677                return_ty = Some(ret_projection.term.expect_type());
678                break;
679            }
680        }
681
682        // SUBTLE: If we didn't find a `Future<Output = ...>` bound for the return
683        // vid, we still want to attempt to provide inference guidance for the async
684        // closure's arguments. Instantiate a new vid to plug into the output type.
685        //
686        // You may be wondering, what if it's higher-ranked? Well, given that we
687        // found a type variable for the `FnOnce::Output` projection above, we know
688        // that the output can't mention any of the vars.
689        //
690        // Also note that we use a fresh var here for the signature since the signature
691        // records the output of the *future*, and `return_vid` above is the type
692        // variable of the future, not its output.
693        //
694        // FIXME: We probably should store this signature inference output in a way
695        // that does not misuse a `FnSig` type, but that can be done separately.
696        let return_ty = return_ty.unwrap_or_else(|| self.table.next_ty_var(closure_expr.into()));
697
698        let sig = projection.rebind(self.interner().mk_fn_sig_safe_rust_abi(input_tys, return_ty));
699
700        Some(sig)
701    }
702
703    fn sig_of_closure(
704        &mut self,
705        closure_expr: ExprId,
706        decl_inputs: &[PatId],
707        decl_input_tys: &[Option<TypeRefId>],
708        decl_output_ty: Option<TypeRefId>,
709        expected_sig: Option<PolyFnSig<'db>>,
710        closure_kind: ClosureKind,
711    ) -> ClosureSignatures<'db> {
712        if let Some(e) = expected_sig {
713            self.sig_of_closure_with_expectation(
714                closure_expr,
715                decl_inputs,
716                decl_input_tys,
717                decl_output_ty,
718                e,
719                closure_kind,
720            )
721        } else {
722            self.sig_of_closure_no_expectation(
723                closure_expr,
724                decl_input_tys,
725                decl_output_ty,
726                closure_kind,
727            )
728        }
729    }
730
731    /// If there is no expected signature, then we will convert the
732    /// types that the user gave into a signature.
733    fn sig_of_closure_no_expectation(
734        &mut self,
735        closure_expr: ExprId,
736        decl_inputs: &[Option<TypeRefId>],
737        decl_output: Option<TypeRefId>,
738        closure_kind: ClosureKind,
739    ) -> ClosureSignatures<'db> {
740        let bound_sig =
741            self.supplied_sig_of_closure(closure_expr, decl_inputs, decl_output, closure_kind);
742
743        self.closure_sigs(bound_sig)
744    }
745
746    /// Invoked to compute the signature of a closure expression. This
747    /// combines any user-provided type annotations (e.g., `|x: u32|
748    /// -> u32 { .. }`) with the expected signature.
749    ///
750    /// The approach is as follows:
751    ///
752    /// - Let `S` be the (higher-ranked) signature that we derive from the user's annotations.
753    /// - Let `E` be the (higher-ranked) signature that we derive from the expectations, if any.
754    ///   - If we have no expectation `E`, then the signature of the closure is `S`.
755    ///   - Otherwise, the signature of the closure is E. Moreover:
756    ///     - Skolemize the late-bound regions in `E`, yielding `E'`.
757    ///     - Instantiate all the late-bound regions bound in the closure within `S`
758    ///       with fresh (existential) variables, yielding `S'`
759    ///     - Require that `E' = S'`
760    ///       - We could use some kind of subtyping relationship here,
761    ///         I imagine, but equality is easier and works fine for
762    ///         our purposes.
763    ///
764    /// The key intuition here is that the user's types must be valid
765    /// from "the inside" of the closure, but the expectation
766    /// ultimately drives the overall signature.
767    ///
768    /// # Examples
769    ///
770    /// ```ignore (illustrative)
771    /// fn with_closure<F>(_: F)
772    ///   where F: Fn(&u32) -> &u32 { .. }
773    ///
774    /// with_closure(|x: &u32| { ... })
775    /// ```
776    ///
777    /// Here:
778    /// - E would be `fn(&u32) -> &u32`.
779    /// - S would be `fn(&u32) -> ?T`
780    /// - E' is `&'!0 u32 -> &'!0 u32`
781    /// - S' is `&'?0 u32 -> ?T`
782    ///
783    /// S' can be unified with E' with `['?0 = '!0, ?T = &'!10 u32]`.
784    ///
785    /// # Arguments
786    ///
787    /// - `expr_def_id`: the `LocalDefId` of the closure expression
788    /// - `decl`: the HIR declaration of the closure
789    /// - `body`: the body of the closure
790    /// - `expected_sig`: the expected signature (if any). Note that
791    ///   this is missing a binder: that is, there may be late-bound
792    ///   regions with depth 1, which are bound then by the closure.
793    fn sig_of_closure_with_expectation(
794        &mut self,
795        closure_expr: ExprId,
796        decl_inputs: &[PatId],
797        decl_input_tys: &[Option<TypeRefId>],
798        decl_output_ty: Option<TypeRefId>,
799        expected_sig: PolyFnSig<'db>,
800        closure_kind: ClosureKind,
801    ) -> ClosureSignatures<'db> {
802        // Watch out for some surprises and just ignore the
803        // expectation if things don't see to match up with what we
804        // expect.
805        if expected_sig.c_variadic() {
806            return self.sig_of_closure_no_expectation(
807                closure_expr,
808                decl_input_tys,
809                decl_output_ty,
810                closure_kind,
811            );
812        } else if expected_sig.skip_binder().inputs_and_output.len() != decl_input_tys.len() + 1 {
813            return self.sig_of_closure_with_mismatched_number_of_arguments(
814                decl_input_tys,
815                decl_output_ty,
816            );
817        }
818
819        // Create a `PolyFnSig`. Note the oddity that late bound
820        // regions appearing free in `expected_sig` are now bound up
821        // in this binder we are creating.
822        assert!(!expected_sig.skip_binder().has_vars_bound_above(rustc_type_ir::INNERMOST));
823        let bound_sig = expected_sig.map_bound(|sig| {
824            self.interner().mk_fn_sig(
825                sig.inputs().iter().copied(),
826                sig.output(),
827                sig.c_variadic(),
828                Safety::Safe,
829                ExternAbi::RustCall,
830            )
831        });
832
833        // `deduce_expectations_from_expected_type` introduces
834        // late-bound lifetimes defined elsewhere, which we now
835        // anonymize away, so as not to confuse the user.
836        let bound_sig = self.interner().anonymize_bound_vars(bound_sig);
837
838        let closure_sigs = self.closure_sigs(bound_sig);
839
840        // Up till this point, we have ignored the annotations that the user
841        // gave. This function will check that they unify successfully.
842        // Along the way, it also writes out entries for types that the user
843        // wrote into our typeck results, which are then later used by the privacy
844        // check.
845        match self.merge_supplied_sig_with_expectation(
846            closure_expr,
847            decl_inputs,
848            decl_input_tys,
849            decl_output_ty,
850            closure_sigs,
851            closure_kind,
852        ) {
853            Ok(infer_ok) => self.table.register_infer_ok(infer_ok),
854            Err(_) => self.sig_of_closure_no_expectation(
855                closure_expr,
856                decl_input_tys,
857                decl_output_ty,
858                closure_kind,
859            ),
860        }
861    }
862
863    fn sig_of_closure_with_mismatched_number_of_arguments(
864        &mut self,
865        decl_inputs: &[Option<TypeRefId>],
866        decl_output: Option<TypeRefId>,
867    ) -> ClosureSignatures<'db> {
868        let error_sig = self.error_sig_of_closure(decl_inputs, decl_output);
869
870        self.closure_sigs(error_sig)
871    }
872
873    /// Enforce the user's types against the expectation. See
874    /// `sig_of_closure_with_expectation` for details on the overall
875    /// strategy.
876    fn merge_supplied_sig_with_expectation(
877        &mut self,
878        closure_expr: ExprId,
879        decl_inputs: &[PatId],
880        decl_input_tys: &[Option<TypeRefId>],
881        decl_output_ty: Option<TypeRefId>,
882        mut expected_sigs: ClosureSignatures<'db>,
883        closure_kind: ClosureKind,
884    ) -> InferResult<'db, ClosureSignatures<'db>> {
885        // Get the signature S that the user gave.
886        //
887        // (See comment on `sig_of_closure_with_expectation` for the
888        // meaning of these letters.)
889        let supplied_sig = self.supplied_sig_of_closure(
890            closure_expr,
891            decl_input_tys,
892            decl_output_ty,
893            closure_kind,
894        );
895
896        debug!(?supplied_sig);
897
898        // FIXME(#45727): As discussed in [this comment][c1], naively
899        // forcing equality here actually results in suboptimal error
900        // messages in some cases. For now, if there would have been
901        // an obvious error, we fallback to declaring the type of the
902        // closure to be the one the user gave, which allows other
903        // error message code to trigger.
904        //
905        // However, I think [there is potential to do even better
906        // here][c2], since in *this* code we have the precise span of
907        // the type parameter in question in hand when we report the
908        // error.
909        //
910        // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
911        // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
912        self.table.commit_if_ok(|table| {
913            let mut all_obligations = PredicateObligations::new();
914            let supplied_sig = table.infer_ctxt.instantiate_binder_with_fresh_vars(
915                closure_expr.into(),
916                BoundRegionConversionTime::FnCall,
917                supplied_sig,
918            );
919
920            // The liberated version of this signature should be a subtype
921            // of the liberated form of the expectation.
922            for ((decl_input, supplied_ty), expected_ty) in iter::zip(
923                iter::zip(decl_inputs, supplied_sig.inputs().iter().copied()),
924                expected_sigs.liberated_sig.inputs().iter().copied(),
925            ) {
926                // Check that E' = S'.
927                let cause = ObligationCause::new(*decl_input);
928                let InferOk { value: (), obligations } =
929                    table.infer_ctxt.at(&cause, table.param_env).eq(expected_ty, supplied_ty)?;
930                all_obligations.extend(obligations);
931            }
932
933            let supplied_output_ty = supplied_sig.output();
934            let cause = ObligationCause::new(
935                decl_output_ty.map(Span::TypeRefId).unwrap_or(closure_expr.into()),
936            );
937            let InferOk { value: (), obligations } =
938                table
939                    .infer_ctxt
940                    .at(&cause, table.param_env)
941                    .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
942            all_obligations.extend(obligations);
943
944            let inputs =
945                supplied_sig.inputs().iter().copied().map(|ty| table.resolve_vars_if_possible(ty));
946
947            expected_sigs.liberated_sig = table.interner().mk_fn_sig(
948                inputs,
949                supplied_output_ty,
950                expected_sigs.liberated_sig.c_variadic(),
951                Safety::Safe,
952                ExternAbi::RustCall,
953            );
954
955            Ok(InferOk { value: expected_sigs, obligations: all_obligations })
956        })
957    }
958
959    /// If there is no expected signature, then we will convert the
960    /// types that the user gave into a signature.
961    ///
962    /// Also, record this closure signature for later.
963    fn supplied_sig_of_closure(
964        &mut self,
965        closure_expr: ExprId,
966        decl_inputs: &[Option<TypeRefId>],
967        decl_output: Option<TypeRefId>,
968        closure_kind: ClosureKind,
969    ) -> PolyFnSig<'db> {
970        let interner = self.interner();
971
972        let supplied_return = match decl_output {
973            Some(output) => self.make_ty(output),
974            None => match closure_kind {
975                // In the case of the async block that we create for a function body,
976                // we expect the return type of the block to match that of the enclosing
977                // function.
978                ClosureKind::Coroutine {
979                    kind: CoroutineKind::Async,
980                    source: CoroutineSource::Fn,
981                } => {
982                    debug!("closure is async fn body");
983                    self.deduce_future_output_from_obligations(closure_expr).unwrap_or_else(|| {
984                        // AFAIK, deducing the future output
985                        // always succeeds *except* in error cases
986                        // like #65159. I'd like to return Error
987                        // here, but I can't because I can't
988                        // easily (and locally) prove that we
989                        // *have* reported an
990                        // error. --nikomatsakis
991                        self.table.next_ty_var(closure_expr.into())
992                    })
993                }
994                // All `gen {}` and `async gen {}` must return unit.
995                ClosureKind::Coroutine {
996                    kind: CoroutineKind::Gen | CoroutineKind::AsyncGen,
997                    ..
998                } => self.types.types.unit,
999
1000                // For async blocks, we just fall back to `_` here.
1001                // For closures/coroutines, we know nothing about the return
1002                // type unless it was supplied.
1003                ClosureKind::Coroutine { kind: CoroutineKind::Async, .. }
1004                | ClosureKind::OldCoroutine(_)
1005                | ClosureKind::Closure
1006                | ClosureKind::CoroutineClosure(_) => self.table.next_ty_var(closure_expr.into()),
1007            },
1008        };
1009        // First, convert the types that the user supplied (if any).
1010        let supplied_arguments = decl_inputs.iter().map(|&input| match input {
1011            Some(input) => self.make_ty(input),
1012            None => self.table.next_ty_var(closure_expr.into()),
1013        });
1014
1015        Binder::dummy(interner.mk_fn_sig(
1016            supplied_arguments,
1017            supplied_return,
1018            false,
1019            Safety::Safe,
1020            ExternAbi::RustCall,
1021        ))
1022    }
1023
1024    /// Invoked when we are translating the coroutine that results
1025    /// from desugaring an `async fn`. Returns the "sugared" return
1026    /// type of the `async fn` -- that is, the return type that the
1027    /// user specified. The "desugared" return type is an `impl
1028    /// Future<Output = T>`, so we do this by searching through the
1029    /// obligations to extract the `T`.
1030    #[instrument(skip(self), level = "debug", ret)]
1031    fn deduce_future_output_from_obligations(&mut self, body_def_id: ExprId) -> Option<Ty<'db>> {
1032        let ret_coercion = self
1033            .return_coercion
1034            .as_ref()
1035            .unwrap_or_else(|| panic!("async fn coroutine outside of a fn"));
1036
1037        let ret_ty = ret_coercion.expected_ty();
1038        let ret_ty = self.table.resolve_vars_with_obligations(ret_ty);
1039
1040        let get_future_output = |predicate: Predicate<'db>| {
1041            // Search for a pending obligation like
1042            //
1043            // `<R as Future>::Output = T`
1044            //
1045            // where R is the return type we are expecting. This type `T`
1046            // will be our output.
1047            let bound_predicate = predicate.kind();
1048            if let PredicateKind::Clause(ClauseKind::Projection(proj_predicate)) =
1049                bound_predicate.skip_binder()
1050            {
1051                self.deduce_future_output_from_projection(bound_predicate.rebind(proj_predicate))
1052            } else {
1053                None
1054            }
1055        };
1056
1057        let output_ty = match ret_ty.kind() {
1058            TyKind::Infer(InferTy::TyVar(ret_vid)) => self
1059                .table
1060                .obligations_for_self_ty(ret_vid, UseSubtyping::No)
1061                .into_iter()
1062                .find_map(|obligation| get_future_output(obligation.predicate))?,
1063            TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { .. }, .. }) => {
1064                return Some(self.types.types.error);
1065            }
1066            TyKind::Alias(AliasTy { kind: AliasTyKind::Opaque { def_id }, args, .. }) => def_id
1067                .0
1068                .predicates(self.db)
1069                .iter_instantiated_copied(self.interner(), &args)
1070                .map(Unnormalized::skip_norm_wip)
1071                .find_map(|p| get_future_output(p.as_predicate()))?,
1072            TyKind::Error(_) => return Some(ret_ty),
1073            _ => {
1074                panic!("invalid async fn coroutine return type: {ret_ty:?}")
1075            }
1076        };
1077
1078        Some(output_ty)
1079    }
1080
1081    /// Given a projection like
1082    ///
1083    /// `<X as Future>::Output = T`
1084    ///
1085    /// where `X` is some type that has no late-bound regions, returns
1086    /// `Some(T)`. If the projection is for some other trait, returns
1087    /// `None`.
1088    fn deduce_future_output_from_projection(
1089        &self,
1090        predicate: PolyProjectionPredicate<'db>,
1091    ) -> Option<Ty<'db>> {
1092        debug!("deduce_future_output_from_projection(predicate={:?})", predicate);
1093
1094        // We do not expect any bound regions in our predicate, so
1095        // skip past the bound vars.
1096        let Some(predicate) = predicate.no_bound_vars() else {
1097            debug!("deduce_future_output_from_projection: has late-bound regions");
1098            return None;
1099        };
1100
1101        // Check that this is a projection from the `Future` trait.
1102        let trait_def_id = predicate.projection_term.trait_def_id(self.interner()).0;
1103        if Some(trait_def_id) != self.lang_items.Future {
1104            debug!("deduce_future_output_from_projection: not a future");
1105            return None;
1106        }
1107
1108        // The `Future` trait has only one associated item, `Output`,
1109        // so check that this is what we see.
1110        let output_assoc_item = self.lang_items.FutureOutput;
1111        if output_assoc_item.map(Into::into) != Some(predicate.def_id().0) {
1112            panic!(
1113                "projecting associated item `{:?}` from future, which is not Output `{:?}`",
1114                predicate.projection_term.kind(self.interner()),
1115                output_assoc_item,
1116            );
1117        }
1118
1119        // Extract the type from the projection. Note that there can
1120        // be no bound variables in this type because the "self type"
1121        // does not have any regions in it.
1122        let output_ty = self.resolve_vars_if_possible(predicate.term);
1123        debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
1124        // This is a projection on a Fn trait so will always be a type.
1125        Some(output_ty.expect_type())
1126    }
1127
1128    /// Converts the types that the user supplied, in case that doing
1129    /// so should yield an error, but returns back a signature where
1130    /// all parameters are of type `ty::Error`.
1131    fn error_sig_of_closure(
1132        &mut self,
1133        decl_inputs: &[Option<TypeRefId>],
1134        decl_output: Option<TypeRefId>,
1135    ) -> PolyFnSig<'db> {
1136        let interner = self.interner();
1137        let err_ty = Ty::new_error(interner, ErrorGuaranteed);
1138
1139        if let Some(output) = decl_output {
1140            self.make_ty(output);
1141        }
1142        let supplied_arguments = decl_inputs.iter().map(|&input| match input {
1143            Some(input) => {
1144                self.make_ty(input);
1145                err_ty
1146            }
1147            None => err_ty,
1148        });
1149
1150        let result = Binder::dummy(interner.mk_fn_sig(
1151            supplied_arguments,
1152            err_ty,
1153            false,
1154            Safety::Safe,
1155            ExternAbi::RustCall,
1156        ));
1157
1158        debug!("supplied_sig_of_closure: result={:?}", result);
1159
1160        result
1161    }
1162
1163    fn closure_sigs(&self, bound_sig: PolyFnSig<'db>) -> ClosureSignatures<'db> {
1164        // TODO: def id needs to be changed?
1165        let liberated_sig =
1166            self.interner().liberate_late_bound_regions(self.owner.into(), bound_sig);
1167        ClosureSignatures { bound_sig, liberated_sig }
1168    }
1169}