1 //! Code for type-checking closure expressions.
3 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}
;
5 use crate::astconv
::AstConv
;
7 use rustc_hir
::def_id
::DefId
;
8 use rustc_hir
::lang_items
::LangItem
;
9 use rustc_infer
::infer
::type_variable
::{TypeVariableOrigin, TypeVariableOriginKind}
;
10 use rustc_infer
::infer
::LateBoundRegionConversionTime
;
11 use rustc_infer
::infer
::{InferOk, InferResult}
;
12 use rustc_middle
::ty
::fold
::TypeFoldable
;
13 use rustc_middle
::ty
::subst
::InternalSubsts
;
14 use rustc_middle
::ty
::{self, Ty}
;
15 use rustc_span
::source_map
::Span
;
16 use rustc_target
::spec
::abi
::Abi
;
17 use rustc_trait_selection
::traits
::error_reporting
::ArgKind
;
18 use rustc_trait_selection
::traits
::error_reporting
::InferCtxtExt
as _
;
22 /// What signature do we *expect* the closure to have from context?
24 struct ExpectedSig
<'tcx
> {
25 /// Span that gave us this expectation, if we know that.
26 cause_span
: Option
<Span
>,
27 sig
: ty
::PolyFnSig
<'tcx
>,
30 struct ClosureSignatures
<'tcx
> {
31 bound_sig
: ty
::PolyFnSig
<'tcx
>,
32 liberated_sig
: ty
::FnSig
<'tcx
>,
35 impl<'a
, 'tcx
> FnCtxt
<'a
, 'tcx
> {
36 #[instrument(skip(self, expr, _capture, decl, body_id), level = "debug")]
37 pub fn check_expr_closure(
40 _capture
: hir
::CaptureBy
,
41 decl
: &'tcx hir
::FnDecl
<'tcx
>,
43 gen
: Option
<hir
::Movability
>,
44 expected
: Expectation
<'tcx
>,
46 trace
!("decl = {:#?}", decl
);
47 trace
!("expr = {:#?}", expr
);
49 // It's always helpful for inference if we know the kind of
50 // closure sooner rather than later, so first examine the expected
51 // type, and see if can glean a closure kind from there.
52 let (expected_sig
, expected_kind
) = match expected
.to_option(self) {
53 Some(ty
) => self.deduce_expectations_from_expected_type(ty
),
56 let body
= self.tcx
.hir().body(body_id
);
57 self.check_closure(expr
, expected_kind
, decl
, body
, gen
, expected_sig
)
60 #[instrument(skip(self, expr, body, decl), level = "debug")]
64 opt_kind
: Option
<ty
::ClosureKind
>,
65 decl
: &'tcx hir
::FnDecl
<'tcx
>,
66 body
: &'tcx hir
::Body
<'tcx
>,
67 gen
: Option
<hir
::Movability
>,
68 expected_sig
: Option
<ExpectedSig
<'tcx
>>,
70 trace
!("decl = {:#?}", decl
);
71 let expr_def_id
= self.tcx
.hir().local_def_id(expr
.hir_id
);
74 let ClosureSignatures { bound_sig, liberated_sig }
=
75 self.sig_of_closure(expr
.hir_id
, expr_def_id
.to_def_id(), decl
, body
, expected_sig
);
77 debug
!(?bound_sig
, ?liberated_sig
);
79 let return_type_pre_known
= !liberated_sig
.output().is_ty_infer();
81 let generator_types
= check_fn(
89 return_type_pre_known
,
93 let parent_substs
= InternalSubsts
::identity_for_item(
95 self.tcx
.closure_base_def_id(expr_def_id
.to_def_id()),
98 let tupled_upvars_ty
= self.infcx
.next_ty_var(TypeVariableOrigin
{
99 kind
: TypeVariableOriginKind
::ClosureSynthetic
,
100 span
: self.tcx
.hir().span(expr
.hir_id
),
103 if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }
) = generator_types
105 let generator_substs
= ty
::GeneratorSubsts
::new(
107 ty
::GeneratorSubstsParts
{
111 return_ty
: liberated_sig
.output(),
117 return self.tcx
.mk_generator(
118 expr_def_id
.to_def_id(),
119 generator_substs
.substs
,
124 // Tuple up the arguments and insert the resulting function type into
125 // the `closures` table.
126 let sig
= bound_sig
.map_bound(|sig
| {
128 iter
::once(self.tcx
.intern_tup(sig
.inputs())),
136 debug
!(?sig
, ?opt_kind
);
138 let closure_kind_ty
= match opt_kind
{
139 Some(kind
) => kind
.to_ty(self.tcx
),
141 // Create a type variable (for now) to represent the closure kind.
142 // It will be unified during the upvar inference phase (`upvar.rs`)
143 None
=> self.infcx
.next_ty_var(TypeVariableOrigin
{
144 // FIXME(eddyb) distinguish closure kind inference variables from the rest.
145 kind
: TypeVariableOriginKind
::ClosureSynthetic
,
150 let closure_substs
= ty
::ClosureSubsts
::new(
152 ty
::ClosureSubstsParts
{
155 closure_sig_as_fn_ptr_ty
: self.tcx
.mk_fn_ptr(sig
),
160 let closure_type
= self.tcx
.mk_closure(expr_def_id
.to_def_id(), closure_substs
.substs
);
162 debug
!(?expr
.hir_id
, ?closure_type
);
167 /// Given the expected type, figures out what it can about this closure we
168 /// are about to type check:
169 #[instrument(skip(self), level = "debug")]
170 fn deduce_expectations_from_expected_type(
172 expected_ty
: Ty
<'tcx
>,
173 ) -> (Option
<ExpectedSig
<'tcx
>>, Option
<ty
::ClosureKind
>) {
174 match *expected_ty
.kind() {
175 ty
::Dynamic(ref object_type
, ..) => {
176 let sig
= object_type
.projection_bounds().find_map(|pb
| {
177 let pb
= pb
.with_self_ty(self.tcx
, self.tcx
.types
.trait_object_dummy_self
);
178 self.deduce_sig_from_projection(None
, pb
)
180 let kind
= object_type
182 .and_then(|did
| self.tcx
.fn_trait_kind_from_lang_item(did
));
185 ty
::Infer(ty
::TyVar(vid
)) => self.deduce_expectations_from_obligations(vid
),
187 let expected_sig
= ExpectedSig { cause_span: None, sig }
;
188 (Some(expected_sig
), Some(ty
::ClosureKind
::Fn
))
194 fn deduce_expectations_from_obligations(
196 expected_vid
: ty
::TyVid
,
197 ) -> (Option
<ExpectedSig
<'tcx
>>, Option
<ty
::ClosureKind
>) {
199 self.obligations_for_self_ty(expected_vid
).find_map(|(_
, obligation
)| {
201 "deduce_expectations_from_obligations: obligation.predicate={:?}",
205 let bound_predicate
= obligation
.predicate
.kind();
206 if let ty
::PredicateKind
::Projection(proj_predicate
) =
207 obligation
.predicate
.kind().skip_binder()
209 // Given a Projection predicate, we can potentially infer
210 // the complete signature.
211 self.deduce_sig_from_projection(
212 Some(obligation
.cause
.span
),
213 bound_predicate
.rebind(proj_predicate
),
220 // Even if we can't infer the full signature, we may be able to
221 // infer the kind. This can occur when we elaborate a predicate
222 // like `F : Fn<A>`. Note that due to subtyping we could encounter
223 // many viable options, so pick the most restrictive.
224 let expected_kind
= self
225 .obligations_for_self_ty(expected_vid
)
226 .filter_map(|(tr
, _
)| self.tcx
.fn_trait_kind_from_lang_item(tr
.def_id()))
227 .fold(None
, |best
, cur
| Some(best
.map_or(cur
, |best
| cmp
::min(best
, cur
))));
229 (expected_sig
, expected_kind
)
232 /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
233 /// everything we need to know about a closure or generator.
235 /// The `cause_span` should be the span that caused us to
236 /// have this expected signature, or `None` if we can't readily
238 fn deduce_sig_from_projection(
240 cause_span
: Option
<Span
>,
241 projection
: ty
::PolyProjectionPredicate
<'tcx
>,
242 ) -> Option
<ExpectedSig
<'tcx
>> {
245 debug
!("deduce_sig_from_projection({:?})", projection
);
247 let trait_def_id
= projection
.trait_def_id(tcx
);
249 let is_fn
= tcx
.fn_trait_kind_from_lang_item(trait_def_id
).is_some();
250 let gen_trait
= tcx
.require_lang_item(LangItem
::Generator
, cause_span
);
251 let is_gen
= gen_trait
== trait_def_id
;
252 if !is_fn
&& !is_gen
{
253 debug
!("deduce_sig_from_projection: not fn or generator");
258 // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
259 // associated item and not yield.
260 let return_assoc_item
=
261 self.tcx
.associated_items(gen_trait
).in_definition_order().nth(1).unwrap().def_id
;
262 if return_assoc_item
!= projection
.projection_def_id() {
263 debug
!("deduce_sig_from_projection: not return assoc item of generator");
268 let input_tys
= if is_fn
{
269 let arg_param_ty
= projection
.skip_binder().projection_ty
.substs
.type_at(1);
270 let arg_param_ty
= self.resolve_vars_if_possible(arg_param_ty
);
271 debug
!("deduce_sig_from_projection: arg_param_ty={:?}", arg_param_ty
);
273 match arg_param_ty
.kind() {
274 ty
::Tuple(tys
) => tys
.into_iter().map(|k
| k
.expect_ty()).collect
::<Vec
<_
>>(),
278 // Generators with a `()` resume type may be defined with 0 or 1 explicit arguments,
279 // else they must have exactly 1 argument. For now though, just give up in this case.
283 let ret_param_ty
= projection
.skip_binder().ty
;
284 let ret_param_ty
= self.resolve_vars_if_possible(ret_param_ty
);
285 debug
!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty
);
287 let sig
= projection
.rebind(self.tcx
.mk_fn_sig(
291 hir
::Unsafety
::Normal
,
294 debug
!("deduce_sig_from_projection: sig={:?}", sig
);
296 Some(ExpectedSig { cause_span, sig }
)
303 decl
: &hir
::FnDecl
<'_
>,
304 body
: &hir
::Body
<'_
>,
305 expected_sig
: Option
<ExpectedSig
<'tcx
>>,
306 ) -> ClosureSignatures
<'tcx
> {
307 if let Some(e
) = expected_sig
{
308 self.sig_of_closure_with_expectation(hir_id
, expr_def_id
, decl
, body
, e
)
310 self.sig_of_closure_no_expectation(hir_id
, expr_def_id
, decl
, body
)
314 /// If there is no expected signature, then we will convert the
315 /// types that the user gave into a signature.
316 #[instrument(skip(self, hir_id, expr_def_id, decl, body), level = "debug")]
317 fn sig_of_closure_no_expectation(
321 decl
: &hir
::FnDecl
<'_
>,
322 body
: &hir
::Body
<'_
>,
323 ) -> ClosureSignatures
<'tcx
> {
324 let bound_sig
= self.supplied_sig_of_closure(hir_id
, expr_def_id
, decl
, body
);
326 self.closure_sigs(expr_def_id
, body
, bound_sig
)
329 /// Invoked to compute the signature of a closure expression. This
330 /// combines any user-provided type annotations (e.g., `|x: u32|
331 /// -> u32 { .. }`) with the expected signature.
333 /// The approach is as follows:
335 /// - Let `S` be the (higher-ranked) signature that we derive from the user's annotations.
336 /// - Let `E` be the (higher-ranked) signature that we derive from the expectations, if any.
337 /// - If we have no expectation `E`, then the signature of the closure is `S`.
338 /// - Otherwise, the signature of the closure is E. Moreover:
339 /// - Skolemize the late-bound regions in `E`, yielding `E'`.
340 /// - Instantiate all the late-bound regions bound in the closure within `S`
341 /// with fresh (existential) variables, yielding `S'`
342 /// - Require that `E' = S'`
343 /// - We could use some kind of subtyping relationship here,
344 /// I imagine, but equality is easier and works fine for
347 /// The key intuition here is that the user's types must be valid
348 /// from "the inside" of the closure, but the expectation
349 /// ultimately drives the overall signature.
354 /// fn with_closure<F>(_: F)
355 /// where F: Fn(&u32) -> &u32 { .. }
357 /// with_closure(|x: &u32| { ... })
361 /// - E would be `fn(&u32) -> &u32`.
362 /// - S would be `fn(&u32) ->
363 /// - E' is `&'!0 u32 -> &'!0 u32`
364 /// - S' is `&'?0 u32 -> ?T`
366 /// S' can be unified with E' with `['?0 = '!0, ?T = &'!10 u32]`.
370 /// - `expr_def_id`: the `DefId` of the closure expression
371 /// - `decl`: the HIR declaration of the closure
372 /// - `body`: the body of the closure
373 /// - `expected_sig`: the expected signature (if any). Note that
374 /// this is missing a binder: that is, there may be late-bound
375 /// regions with depth 1, which are bound then by the closure.
376 #[instrument(skip(self, hir_id, expr_def_id, decl, body), level = "debug")]
377 fn sig_of_closure_with_expectation(
381 decl
: &hir
::FnDecl
<'_
>,
382 body
: &hir
::Body
<'_
>,
383 expected_sig
: ExpectedSig
<'tcx
>,
384 ) -> ClosureSignatures
<'tcx
> {
385 // Watch out for some surprises and just ignore the
386 // expectation if things don't see to match up with what we
388 if expected_sig
.sig
.c_variadic() != decl
.c_variadic
{
389 return self.sig_of_closure_no_expectation(hir_id
, expr_def_id
, decl
, body
);
390 } else if expected_sig
.sig
.skip_binder().inputs_and_output
.len() != decl
.inputs
.len() + 1 {
391 return self.sig_of_closure_with_mismatched_number_of_arguments(
399 // Create a `PolyFnSig`. Note the oddity that late bound
400 // regions appearing free in `expected_sig` are now bound up
401 // in this binder we are creating.
402 assert
!(!expected_sig
.sig
.skip_binder().has_vars_bound_above(ty
::INNERMOST
));
403 let bound_sig
= expected_sig
.sig
.map_bound(|sig
| {
405 sig
.inputs().iter().cloned(),
408 hir
::Unsafety
::Normal
,
413 // `deduce_expectations_from_expected_type` introduces
414 // late-bound lifetimes defined elsewhere, which we now
415 // anonymize away, so as not to confuse the user.
416 let bound_sig
= self.tcx
.anonymize_late_bound_regions(bound_sig
);
418 let closure_sigs
= self.closure_sigs(expr_def_id
, body
, bound_sig
);
420 // Up till this point, we have ignored the annotations that the user
421 // gave. This function will check that they unify successfully.
422 // Along the way, it also writes out entries for types that the user
423 // wrote into our typeck results, which are then later used by the privacy
425 match self.check_supplied_sig_against_expectation(
432 Ok(infer_ok
) => self.register_infer_ok_obligations(infer_ok
),
433 Err(_
) => return self.sig_of_closure_no_expectation(hir_id
, expr_def_id
, decl
, body
),
439 fn sig_of_closure_with_mismatched_number_of_arguments(
442 decl
: &hir
::FnDecl
<'_
>,
443 body
: &hir
::Body
<'_
>,
444 expected_sig
: ExpectedSig
<'tcx
>,
445 ) -> ClosureSignatures
<'tcx
> {
446 let hir
= self.tcx
.hir();
447 let expr_map_node
= hir
.get_if_local(expr_def_id
).unwrap();
448 let expected_args
: Vec
<_
> = expected_sig
453 .map(|ty
| ArgKind
::from_expected_ty(ty
, None
))
455 let (closure_span
, found_args
) = match self.get_fn_like_arguments(expr_map_node
) {
456 Some((sp
, args
)) => (Some(sp
), args
),
457 None
=> (None
, Vec
::new()),
460 expected_sig
.cause_span
.unwrap_or_else(|| hir
.span_if_local(expr_def_id
).unwrap());
461 self.report_arg_count_mismatch(
470 let error_sig
= self.error_sig_of_closure(decl
);
472 self.closure_sigs(expr_def_id
, body
, error_sig
)
475 /// Enforce the user's types against the expectation. See
476 /// `sig_of_closure_with_expectation` for details on the overall
478 fn check_supplied_sig_against_expectation(
482 decl
: &hir
::FnDecl
<'_
>,
483 body
: &hir
::Body
<'_
>,
484 expected_sigs
: &ClosureSignatures
<'tcx
>,
485 ) -> InferResult
<'tcx
, ()> {
486 // Get the signature S that the user gave.
488 // (See comment on `sig_of_closure_with_expectation` for the
489 // meaning of these letters.)
490 let supplied_sig
= self.supplied_sig_of_closure(hir_id
, expr_def_id
, decl
, body
);
492 debug
!("check_supplied_sig_against_expectation: supplied_sig={:?}", supplied_sig
);
494 // FIXME(#45727): As discussed in [this comment][c1], naively
495 // forcing equality here actually results in suboptimal error
496 // messages in some cases. For now, if there would have been
497 // an obvious error, we fallback to declaring the type of the
498 // closure to be the one the user gave, which allows other
499 // error message code to trigger.
501 // However, I think [there is potential to do even better
502 // here][c2], since in *this* code we have the precise span of
503 // the type parameter in question in hand when we report the
506 // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
507 // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
508 self.infcx
.commit_if_ok(|_
| {
509 let mut all_obligations
= vec
![];
511 // The liberated version of this signature should be a subtype
512 // of the liberated form of the expectation.
513 for ((hir_ty
, &supplied_ty
), expected_ty
) in iter
::zip(
516 supplied_sig
.inputs().skip_binder(), // binder moved to (*) below
518 expected_sigs
.liberated_sig
.inputs(), // `liberated_sig` is E'.
520 // Instantiate (this part of..) S to S', i.e., with fresh variables.
521 let (supplied_ty
, _
) = self.infcx
.replace_bound_vars_with_fresh_vars(
523 LateBoundRegionConversionTime
::FnCall
,
524 supplied_sig
.inputs().rebind(supplied_ty
),
525 ); // recreated from (*) above
527 // Check that E' = S'.
528 let cause
= self.misc(hir_ty
.span
);
529 let InferOk { value: (), obligations }
=
530 self.at(&cause
, self.param_env
).eq(*expected_ty
, supplied_ty
)?
;
531 all_obligations
.extend(obligations
);
534 let (supplied_output_ty
, _
) = self.infcx
.replace_bound_vars_with_fresh_vars(
536 LateBoundRegionConversionTime
::FnCall
,
537 supplied_sig
.output(),
539 let cause
= &self.misc(decl
.output
.span());
540 let InferOk { value: (), obligations }
= self
541 .at(cause
, self.param_env
)
542 .eq(expected_sigs
.liberated_sig
.output(), supplied_output_ty
)?
;
543 all_obligations
.extend(obligations
);
545 Ok(InferOk { value: (), obligations: all_obligations }
)
549 /// If there is no expected signature, then we will convert the
550 /// types that the user gave into a signature.
552 /// Also, record this closure signature for later.
553 #[instrument(skip(self, decl, body), level = "debug")]
554 fn supplied_sig_of_closure(
558 decl
: &hir
::FnDecl
<'_
>,
559 body
: &hir
::Body
<'_
>,
560 ) -> ty
::PolyFnSig
<'tcx
> {
561 let astconv
: &dyn AstConv
<'_
> = self;
563 trace
!("decl = {:#?}", decl
);
564 debug
!(?body
.generator_kind
);
566 let bound_vars
= self.tcx
.late_bound_vars(hir_id
);
568 // First, convert the types that the user supplied (if any).
569 let supplied_arguments
= decl
.inputs
.iter().map(|a
| astconv
.ast_ty_to_ty(a
));
570 let supplied_return
= match decl
.output
{
571 hir
::FnRetTy
::Return(ref output
) => astconv
.ast_ty_to_ty(&output
),
572 hir
::FnRetTy
::DefaultReturn(_
) => match body
.generator_kind
{
573 // In the case of the async block that we create for a function body,
574 // we expect the return type of the block to match that of the enclosing
576 Some(hir
::GeneratorKind
::Async(hir
::AsyncGeneratorKind
::Fn
)) => {
577 debug
!("closure is async fn body");
578 self.deduce_future_output_from_obligations(expr_def_id
).unwrap_or_else(|| {
579 // AFAIK, deducing the future output
580 // always succeeds *except* in error cases
581 // like #65159. I'd like to return Error
582 // here, but I can't because I can't
583 // easily (and locally) prove that we
584 // *have* reported an
585 // error. --nikomatsakis
586 astconv
.ty_infer(None
, decl
.output
.span())
590 _
=> astconv
.ty_infer(None
, decl
.output
.span()),
594 let result
= ty
::Binder
::bind_with_vars(
599 hir
::Unsafety
::Normal
,
607 let c_result
= self.inh
.infcx
.canonicalize_response(result
);
608 self.typeck_results
.borrow_mut().user_provided_sigs
.insert(expr_def_id
, c_result
);
613 /// Invoked when we are translating the generator that results
614 /// from desugaring an `async fn`. Returns the "sugared" return
615 /// type of the `async fn` -- that is, the return type that the
616 /// user specified. The "desugared" return type is an `impl
617 /// Future<Output = T>`, so we do this by searching through the
618 /// obligations to extract the `T`.
619 fn deduce_future_output_from_obligations(&self, expr_def_id
: DefId
) -> Option
<Ty
<'tcx
>> {
620 debug
!("deduce_future_output_from_obligations(expr_def_id={:?})", expr_def_id
);
622 let ret_coercion
= self.ret_coercion
.as_ref().unwrap_or_else(|| {
623 span_bug
!(self.tcx
.def_span(expr_def_id
), "async fn generator outside of a fn")
626 // In practice, the return type of the surrounding function is
627 // always a (not yet resolved) inference variable, because it
628 // is the hidden type for an `impl Trait` that we are going to
630 let ret_ty
= ret_coercion
.borrow().expected_ty();
631 let ret_ty
= self.inh
.infcx
.shallow_resolve(ret_ty
);
632 let ret_vid
= match *ret_ty
.kind() {
633 ty
::Infer(ty
::TyVar(ret_vid
)) => ret_vid
,
634 ty
::Error(_
) => return None
,
636 self.tcx
.def_span(expr_def_id
),
637 "async fn generator return type not an inference variable"
641 // Search for a pending obligation like
643 // `<R as Future>::Output = T`
645 // where R is the return type we are expecting. This type `T`
646 // will be our output.
647 let output_ty
= self.obligations_for_self_ty(ret_vid
).find_map(|(_
, obligation
)| {
648 let bound_predicate
= obligation
.predicate
.kind();
649 if let ty
::PredicateKind
::Projection(proj_predicate
) = bound_predicate
.skip_binder() {
650 self.deduce_future_output_from_projection(
651 obligation
.cause
.span
,
652 bound_predicate
.rebind(proj_predicate
),
659 debug
!("deduce_future_output_from_obligations: output_ty={:?}", output_ty
);
663 /// Given a projection like
665 /// `<X as Future>::Output = T`
667 /// where `X` is some type that has no late-bound regions, returns
668 /// `Some(T)`. If the projection is for some other trait, returns
670 fn deduce_future_output_from_projection(
673 predicate
: ty
::PolyProjectionPredicate
<'tcx
>,
674 ) -> Option
<Ty
<'tcx
>> {
675 debug
!("deduce_future_output_from_projection(predicate={:?})", predicate
);
677 // We do not expect any bound regions in our predicate, so
678 // skip past the bound vars.
679 let predicate
= match predicate
.no_bound_vars() {
682 debug
!("deduce_future_output_from_projection: has late-bound regions");
687 // Check that this is a projection from the `Future` trait.
688 let trait_def_id
= predicate
.projection_ty
.trait_def_id(self.tcx
);
689 let future_trait
= self.tcx
.require_lang_item(LangItem
::Future
, Some(cause_span
));
690 if trait_def_id
!= future_trait
{
691 debug
!("deduce_future_output_from_projection: not a future");
695 // The `Future` trait has only one associted item, `Output`,
696 // so check that this is what we see.
697 let output_assoc_item
=
698 self.tcx
.associated_items(future_trait
).in_definition_order().next().unwrap().def_id
;
699 if output_assoc_item
!= predicate
.projection_ty
.item_def_id
{
702 "projecting associated item `{:?}` from future, which is not Output `{:?}`",
703 predicate
.projection_ty
.item_def_id
,
708 // Extract the type from the projection. Note that there can
709 // be no bound variables in this type because the "self type"
710 // does not have any regions in it.
711 let output_ty
= self.resolve_vars_if_possible(predicate
.ty
);
712 debug
!("deduce_future_output_from_projection: output_ty={:?}", output_ty
);
716 /// Converts the types that the user supplied, in case that doing
717 /// so should yield an error, but returns back a signature where
718 /// all parameters are of type `TyErr`.
719 fn error_sig_of_closure(&self, decl
: &hir
::FnDecl
<'_
>) -> ty
::PolyFnSig
<'tcx
> {
720 let astconv
: &dyn AstConv
<'_
> = self;
722 let supplied_arguments
= decl
.inputs
.iter().map(|a
| {
723 // Convert the types that the user supplied (if any), but ignore them.
724 astconv
.ast_ty_to_ty(a
);
728 if let hir
::FnRetTy
::Return(ref output
) = decl
.output
{
729 astconv
.ast_ty_to_ty(&output
);
732 let result
= ty
::Binder
::dummy(self.tcx
.mk_fn_sig(
736 hir
::Unsafety
::Normal
,
740 debug
!("supplied_sig_of_closure: result={:?}", result
);
748 body
: &hir
::Body
<'_
>,
749 bound_sig
: ty
::PolyFnSig
<'tcx
>,
750 ) -> ClosureSignatures
<'tcx
> {
751 let liberated_sig
= self.tcx().liberate_late_bound_regions(expr_def_id
, bound_sig
);
752 let liberated_sig
= self.inh
.normalize_associated_types_in(
758 ClosureSignatures { bound_sig, liberated_sig }