rustc_hir_typeck/
closure.rs

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