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}