]> git.proxmox.com Git - rustc.git/blob - src/librustc_typeck/check/closure.rs
New upstream version 1.26.0+dfsg1
[rustc.git] / src / librustc_typeck / check / closure.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Code for type-checking closure expressions.
12
13 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
14
15 use astconv::AstConv;
16 use rustc::hir::def_id::DefId;
17 use rustc::infer::{InferOk, InferResult};
18 use rustc::infer::LateBoundRegionConversionTime;
19 use rustc::infer::type_variable::TypeVariableOrigin;
20 use rustc::traits::error_reporting::ArgKind;
21 use rustc::ty::{self, ToPolyTraitRef, Ty};
22 use rustc::ty::subst::Substs;
23 use rustc::ty::TypeFoldable;
24 use std::cmp;
25 use std::iter;
26 use syntax::abi::Abi;
27 use syntax::codemap::Span;
28 use rustc::hir;
29
30 /// What signature do we *expect* the closure to have from context?
31 #[derive(Debug)]
32 struct ExpectedSig<'tcx> {
33 /// Span that gave us this expectation, if we know that.
34 cause_span: Option<Span>,
35 sig: ty::FnSig<'tcx>,
36 }
37
38 struct ClosureSignatures<'tcx> {
39 bound_sig: ty::PolyFnSig<'tcx>,
40 liberated_sig: ty::FnSig<'tcx>,
41 }
42
43 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
44 pub fn check_expr_closure(
45 &self,
46 expr: &hir::Expr,
47 _capture: hir::CaptureClause,
48 decl: &'gcx hir::FnDecl,
49 body_id: hir::BodyId,
50 gen: Option<hir::GeneratorMovability>,
51 expected: Expectation<'tcx>,
52 ) -> Ty<'tcx> {
53 debug!(
54 "check_expr_closure(expr={:?},expected={:?})",
55 expr, expected
56 );
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_expectations_from_expected_type(ty),
63 None => (None, None),
64 };
65 let body = self.tcx.hir.body(body_id);
66 self.check_closure(expr, expected_kind, decl, body, gen, expected_sig)
67 }
68
69 fn check_closure(
70 &self,
71 expr: &hir::Expr,
72 opt_kind: Option<ty::ClosureKind>,
73 decl: &'gcx hir::FnDecl,
74 body: &'gcx hir::Body,
75 gen: Option<hir::GeneratorMovability>,
76 expected_sig: Option<ExpectedSig<'tcx>>,
77 ) -> Ty<'tcx> {
78 debug!(
79 "check_closure(opt_kind={:?}, expected_sig={:?})",
80 opt_kind, expected_sig
81 );
82
83 let expr_def_id = self.tcx.hir.local_def_id(expr.id);
84
85 let ClosureSignatures {
86 bound_sig,
87 liberated_sig,
88 } = self.sig_of_closure(expr_def_id, decl, body, expected_sig);
89
90 debug!("check_closure: ty_of_closure returns {:?}", liberated_sig);
91
92 let generator_types = check_fn(
93 self,
94 self.param_env,
95 liberated_sig,
96 decl,
97 expr.id,
98 body,
99 gen,
100 ).1;
101
102 // Create type variables (for now) to represent the transformed
103 // types of upvars. These will be unified during the upvar
104 // inference phase (`upvar.rs`).
105 let base_substs =
106 Substs::identity_for_item(self.tcx, self.tcx.closure_base_def_id(expr_def_id));
107 let substs = base_substs.extend_to(
108 self.tcx,
109 expr_def_id,
110 |_, _| span_bug!(expr.span, "closure has region param"),
111 |_, _| {
112 self.infcx
113 .next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span))
114 },
115 );
116 let substs = ty::ClosureSubsts { substs };
117 let closure_type = self.tcx.mk_closure(expr_def_id, substs);
118
119 if let Some(GeneratorTypes { yield_ty, interior }) = generator_types {
120 self.demand_eqtype(
121 expr.span,
122 yield_ty,
123 substs.generator_yield_ty(expr_def_id, self.tcx),
124 );
125 self.demand_eqtype(
126 expr.span,
127 liberated_sig.output(),
128 substs.generator_return_ty(expr_def_id, self.tcx),
129 );
130 return self.tcx.mk_generator(expr_def_id, substs, interior);
131 }
132
133 debug!(
134 "check_closure: expr.id={:?} closure_type={:?}",
135 expr.id, closure_type
136 );
137
138 // Tuple up the arguments and insert the resulting function type into
139 // the `closures` table.
140 let sig = bound_sig.map_bound(|sig| {
141 self.tcx.mk_fn_sig(
142 iter::once(self.tcx.intern_tup(sig.inputs())),
143 sig.output(),
144 sig.variadic,
145 sig.unsafety,
146 sig.abi,
147 )
148 });
149
150 debug!(
151 "check_closure: expr_def_id={:?}, sig={:?}, opt_kind={:?}",
152 expr_def_id, sig, opt_kind
153 );
154
155 let sig_fn_ptr_ty = self.tcx.mk_fn_ptr(sig);
156 self.demand_eqtype(
157 expr.span,
158 sig_fn_ptr_ty,
159 substs.closure_sig_ty(expr_def_id, self.tcx),
160 );
161
162 if let Some(kind) = opt_kind {
163 self.demand_eqtype(
164 expr.span,
165 kind.to_ty(self.tcx),
166 substs.closure_kind_ty(expr_def_id, self.tcx),
167 );
168 }
169
170 closure_type
171 }
172
173 /// Given the expected type, figures out what it can about this closure we
174 /// are about to type check:
175 fn deduce_expectations_from_expected_type(
176 &self,
177 expected_ty: Ty<'tcx>,
178 ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
179 debug!(
180 "deduce_expectations_from_expected_type(expected_ty={:?})",
181 expected_ty
182 );
183
184 match expected_ty.sty {
185 ty::TyDynamic(ref object_type, ..) => {
186 let sig = object_type
187 .projection_bounds()
188 .filter_map(|pb| {
189 let pb = pb.with_self_ty(self.tcx, self.tcx.types.err);
190 self.deduce_sig_from_projection(None, &pb)
191 })
192 .next();
193 let kind = object_type
194 .principal()
195 .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
196 (sig, kind)
197 }
198 ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
199 ty::TyFnPtr(sig) => {
200 let expected_sig = ExpectedSig {
201 cause_span: None,
202 sig: sig.skip_binder().clone(),
203 };
204 (Some(expected_sig), Some(ty::ClosureKind::Fn))
205 }
206 _ => (None, None),
207 }
208 }
209
210 fn deduce_expectations_from_obligations(
211 &self,
212 expected_vid: ty::TyVid,
213 ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
214 let fulfillment_cx = self.fulfillment_cx.borrow();
215 // Here `expected_ty` is known to be a type inference variable.
216
217 let expected_sig = fulfillment_cx
218 .pending_obligations()
219 .iter()
220 .map(|obligation| &obligation.obligation)
221 .filter_map(|obligation| {
222 debug!(
223 "deduce_expectations_from_obligations: obligation.predicate={:?}",
224 obligation.predicate
225 );
226
227 match obligation.predicate {
228 // Given a Projection predicate, we can potentially infer
229 // the complete signature.
230 ty::Predicate::Projection(ref proj_predicate) => {
231 let trait_ref = proj_predicate.to_poly_trait_ref(self.tcx);
232 self.self_type_matches_expected_vid(trait_ref, expected_vid)
233 .and_then(|_| {
234 self.deduce_sig_from_projection(
235 Some(obligation.cause.span),
236 proj_predicate,
237 )
238 })
239 }
240 _ => None,
241 }
242 })
243 .next();
244
245 // Even if we can't infer the full signature, we may be able to
246 // infer the kind. This can occur if there is a trait-reference
247 // like `F : Fn<A>`. Note that due to subtyping we could encounter
248 // many viable options, so pick the most restrictive.
249 let expected_kind = fulfillment_cx
250 .pending_obligations()
251 .iter()
252 .map(|obligation| &obligation.obligation)
253 .filter_map(|obligation| {
254 let opt_trait_ref = match obligation.predicate {
255 ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)),
256 ty::Predicate::Trait(ref data) => Some(data.to_poly_trait_ref()),
257 ty::Predicate::Subtype(..) => None,
258 ty::Predicate::RegionOutlives(..) => None,
259 ty::Predicate::TypeOutlives(..) => None,
260 ty::Predicate::WellFormed(..) => None,
261 ty::Predicate::ObjectSafe(..) => None,
262 ty::Predicate::ConstEvaluatable(..) => None,
263
264 // NB: This predicate is created by breaking down a
265 // `ClosureType: FnFoo()` predicate, where
266 // `ClosureType` represents some `TyClosure`. It can't
267 // possibly be referring to the current closure,
268 // because we haven't produced the `TyClosure` for
269 // this closure yet; this is exactly why the other
270 // code is looking for a self type of a unresolved
271 // inference variable.
272 ty::Predicate::ClosureKind(..) => None,
273 };
274 opt_trait_ref
275 .and_then(|tr| self.self_type_matches_expected_vid(tr, expected_vid))
276 .and_then(|tr| self.tcx.lang_items().fn_trait_kind(tr.def_id()))
277 })
278 .fold(None, |best, cur| {
279 Some(best.map_or(cur, |best| cmp::min(best, cur)))
280 });
281
282 (expected_sig, expected_kind)
283 }
284
285 /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
286 /// everything we need to know about a closure.
287 ///
288 /// The `cause_span` should be the span that caused us to
289 /// have this expected signature, or `None` if we can't readily
290 /// know that.
291 fn deduce_sig_from_projection(
292 &self,
293 cause_span: Option<Span>,
294 projection: &ty::PolyProjectionPredicate<'tcx>,
295 ) -> Option<ExpectedSig<'tcx>> {
296 let tcx = self.tcx;
297
298 debug!("deduce_sig_from_projection({:?})", projection);
299
300 let trait_ref = projection.to_poly_trait_ref(tcx);
301
302 if tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_none() {
303 return None;
304 }
305
306 let arg_param_ty = trait_ref.substs().type_at(1);
307 let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
308 debug!(
309 "deduce_sig_from_projection: arg_param_ty {:?}",
310 arg_param_ty
311 );
312
313 let input_tys = match arg_param_ty.sty {
314 ty::TyTuple(tys) => tys.into_iter(),
315 _ => {
316 return None;
317 }
318 };
319
320 let ret_param_ty = projection.0.ty;
321 let ret_param_ty = self.resolve_type_vars_if_possible(&ret_param_ty);
322 debug!(
323 "deduce_sig_from_projection: ret_param_ty {:?}",
324 ret_param_ty
325 );
326
327 let sig = self.tcx.mk_fn_sig(
328 input_tys.cloned(),
329 ret_param_ty,
330 false,
331 hir::Unsafety::Normal,
332 Abi::Rust,
333 );
334 debug!("deduce_sig_from_projection: sig {:?}", sig);
335
336 Some(ExpectedSig { cause_span, sig })
337 }
338
339 fn self_type_matches_expected_vid(
340 &self,
341 trait_ref: ty::PolyTraitRef<'tcx>,
342 expected_vid: ty::TyVid,
343 ) -> Option<ty::PolyTraitRef<'tcx>> {
344 let self_ty = self.shallow_resolve(trait_ref.self_ty());
345 debug!(
346 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?})",
347 trait_ref, self_ty
348 );
349 match self_ty.sty {
350 ty::TyInfer(ty::TyVar(v)) if expected_vid == v => Some(trait_ref),
351 _ => None,
352 }
353 }
354
355 fn sig_of_closure(
356 &self,
357 expr_def_id: DefId,
358 decl: &hir::FnDecl,
359 body: &hir::Body,
360 expected_sig: Option<ExpectedSig<'tcx>>,
361 ) -> ClosureSignatures<'tcx> {
362 if let Some(e) = expected_sig {
363 self.sig_of_closure_with_expectation(expr_def_id, decl, body, e)
364 } else {
365 self.sig_of_closure_no_expectation(expr_def_id, decl, body)
366 }
367 }
368
369 /// If there is no expected signature, then we will convert the
370 /// types that the user gave into a signature.
371 fn sig_of_closure_no_expectation(
372 &self,
373 expr_def_id: DefId,
374 decl: &hir::FnDecl,
375 body: &hir::Body,
376 ) -> ClosureSignatures<'tcx> {
377 debug!("sig_of_closure_no_expectation()");
378
379 let bound_sig = self.supplied_sig_of_closure(decl);
380
381 self.closure_sigs(expr_def_id, body, bound_sig)
382 }
383
384 /// Invoked to compute the signature of a closure expression. This
385 /// combines any user-provided type annotations (e.g., `|x: u32|
386 /// -> u32 { .. }`) with the expected signature.
387 ///
388 /// The approach is as follows:
389 ///
390 /// - Let `S` be the (higher-ranked) signature that we derive from the user's annotations.
391 /// - Let `E` be the (higher-ranked) signature that we derive from the expectations, if any.
392 /// - If we have no expectation `E`, then the signature of the closure is `S`.
393 /// - Otherwise, the signature of the closure is E. Moreover:
394 /// - Skolemize the late-bound regions in `E`, yielding `E'`.
395 /// - Instantiate all the late-bound regions bound in the closure within `S`
396 /// with fresh (existential) variables, yielding `S'`
397 /// - Require that `E' = S'`
398 /// - We could use some kind of subtyping relationship here,
399 /// I imagine, but equality is easier and works fine for
400 /// our purposes.
401 ///
402 /// The key intuition here is that the user's types must be valid
403 /// from "the inside" of the closure, but the expectation
404 /// ultimately drives the overall signature.
405 ///
406 /// # Examples
407 ///
408 /// ```
409 /// fn with_closure<F>(_: F)
410 /// where F: Fn(&u32) -> &u32 { .. }
411 ///
412 /// with_closure(|x: &u32| { ... })
413 /// ```
414 ///
415 /// Here:
416 /// - E would be `fn(&u32) -> &u32`.
417 /// - S would be `fn(&u32) ->
418 /// - E' is `&'!0 u32 -> &'!0 u32`
419 /// - S' is `&'?0 u32 -> ?T`
420 ///
421 /// S' can be unified with E' with `['?0 = '!0, ?T = &'!10 u32]`.
422 ///
423 /// # Arguments
424 ///
425 /// - `expr_def_id`: the def-id of the closure expression
426 /// - `decl`: the HIR declaration of the closure
427 /// - `body`: the body of the closure
428 /// - `expected_sig`: the expected signature (if any). Note that
429 /// this is missing a binder: that is, there may be late-bound
430 /// regions with depth 1, which are bound then by the closure.
431 fn sig_of_closure_with_expectation(
432 &self,
433 expr_def_id: DefId,
434 decl: &hir::FnDecl,
435 body: &hir::Body,
436 expected_sig: ExpectedSig<'tcx>,
437 ) -> ClosureSignatures<'tcx> {
438 debug!(
439 "sig_of_closure_with_expectation(expected_sig={:?})",
440 expected_sig
441 );
442
443 // Watch out for some surprises and just ignore the
444 // expectation if things don't see to match up with what we
445 // expect.
446 if expected_sig.sig.variadic != decl.variadic {
447 return self.sig_of_closure_no_expectation(expr_def_id, decl, body);
448 } else if expected_sig.sig.inputs_and_output.len() != decl.inputs.len() + 1 {
449 return self.sig_of_closure_with_mismatched_number_of_arguments(
450 expr_def_id,
451 decl,
452 body,
453 expected_sig,
454 );
455 }
456
457 // Create a `PolyFnSig`. Note the oddity that late bound
458 // regions appearing free in `expected_sig` are now bound up
459 // in this binder we are creating.
460 assert!(!expected_sig.sig.has_regions_escaping_depth(1));
461 let bound_sig = ty::Binder(self.tcx.mk_fn_sig(
462 expected_sig.sig.inputs().iter().cloned(),
463 expected_sig.sig.output(),
464 decl.variadic,
465 hir::Unsafety::Normal,
466 Abi::RustCall,
467 ));
468
469 // `deduce_expectations_from_expected_type` introduces
470 // late-bound lifetimes defined elsewhere, which we now
471 // anonymize away, so as not to confuse the user.
472 let bound_sig = self.tcx.anonymize_late_bound_regions(&bound_sig);
473
474 let closure_sigs = self.closure_sigs(expr_def_id, body, bound_sig);
475
476 // Up till this point, we have ignored the annotations that the user
477 // gave. This function will check that they unify successfully.
478 // Along the way, it also writes out entries for types that the user
479 // wrote into our tables, which are then later used by the privacy
480 // check.
481 match self.check_supplied_sig_against_expectation(decl, &closure_sigs) {
482 Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok),
483 Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body),
484 }
485
486 closure_sigs
487 }
488
489 fn sig_of_closure_with_mismatched_number_of_arguments(
490 &self,
491 expr_def_id: DefId,
492 decl: &hir::FnDecl,
493 body: &hir::Body,
494 expected_sig: ExpectedSig<'tcx>,
495 ) -> ClosureSignatures<'tcx> {
496 let expr_map_node = self.tcx.hir.get_if_local(expr_def_id).unwrap();
497 let expected_args: Vec<_> = expected_sig
498 .sig
499 .inputs()
500 .iter()
501 .map(|ty| ArgKind::from_expected_ty(ty))
502 .collect();
503 let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node);
504 let expected_span = expected_sig.cause_span.unwrap_or(closure_span);
505 self.report_arg_count_mismatch(
506 expected_span,
507 Some(closure_span),
508 expected_args,
509 found_args,
510 true,
511 ).emit();
512
513 let error_sig = self.error_sig_of_closure(decl);
514
515 self.closure_sigs(expr_def_id, body, error_sig)
516 }
517
518 /// Enforce the user's types against the expectation. See
519 /// `sig_of_closure_with_expectation` for details on the overall
520 /// strategy.
521 fn check_supplied_sig_against_expectation(
522 &self,
523 decl: &hir::FnDecl,
524 expected_sigs: &ClosureSignatures<'tcx>,
525 ) -> InferResult<'tcx, ()> {
526 // Get the signature S that the user gave.
527 //
528 // (See comment on `sig_of_closure_with_expectation` for the
529 // meaning of these letters.)
530 let supplied_sig = self.supplied_sig_of_closure(decl);
531
532 debug!(
533 "check_supplied_sig_against_expectation: supplied_sig={:?}",
534 supplied_sig
535 );
536
537 // FIXME(#45727): As discussed in [this comment][c1], naively
538 // forcing equality here actually results in suboptimal error
539 // messages in some cases. For now, if there would have been
540 // an obvious error, we fallback to declaring the type of the
541 // closure to be the one the user gave, which allows other
542 // error message code to trigger.
543 //
544 // However, I think [there is potential to do even better
545 // here][c2], since in *this* code we have the precise span of
546 // the type parameter in question in hand when we report the
547 // error.
548 //
549 // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
550 // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
551 self.infcx.commit_if_ok(|_| {
552 let mut all_obligations = vec![];
553
554 // The liberated version of this signature should be be a subtype
555 // of the liberated form of the expectation.
556 for ((hir_ty, &supplied_ty), expected_ty) in decl.inputs.iter()
557 .zip(*supplied_sig.inputs().skip_binder()) // binder moved to (*) below
558 .zip(expected_sigs.liberated_sig.inputs())
559 // `liberated_sig` is E'.
560 {
561 // Instantiate (this part of..) S to S', i.e., with fresh variables.
562 let (supplied_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var(
563 hir_ty.span,
564 LateBoundRegionConversionTime::FnCall,
565 &ty::Binder(supplied_ty),
566 ); // recreated from (*) above
567
568 // Check that E' = S'.
569 let cause = &self.misc(hir_ty.span);
570 let InferOk {
571 value: (),
572 obligations,
573 } = self.at(cause, self.param_env)
574 .eq(*expected_ty, supplied_ty)?;
575 all_obligations.extend(obligations);
576 }
577
578 let (supplied_output_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var(
579 decl.output.span(),
580 LateBoundRegionConversionTime::FnCall,
581 &supplied_sig.output(),
582 );
583 let cause = &self.misc(decl.output.span());
584 let InferOk {
585 value: (),
586 obligations,
587 } = self.at(cause, self.param_env)
588 .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
589 all_obligations.extend(obligations);
590
591 Ok(InferOk {
592 value: (),
593 obligations: all_obligations,
594 })
595 })
596 }
597
598 /// If there is no expected signature, then we will convert the
599 /// types that the user gave into a signature.
600 fn supplied_sig_of_closure(&self, decl: &hir::FnDecl) -> ty::PolyFnSig<'tcx> {
601 let astconv: &AstConv = self;
602
603 // First, convert the types that the user supplied (if any).
604 let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
605 let supplied_return = match decl.output {
606 hir::Return(ref output) => astconv.ast_ty_to_ty(&output),
607 hir::DefaultReturn(_) => astconv.ty_infer(decl.output.span()),
608 };
609
610 let result = ty::Binder(self.tcx.mk_fn_sig(
611 supplied_arguments,
612 supplied_return,
613 decl.variadic,
614 hir::Unsafety::Normal,
615 Abi::RustCall,
616 ));
617
618 debug!("supplied_sig_of_closure: result={:?}", result);
619
620 result
621 }
622
623 /// Converts the types that the user supplied, in case that doing
624 /// so should yield an error, but returns back a signature where
625 /// all parameters are of type `TyErr`.
626 fn error_sig_of_closure(&self, decl: &hir::FnDecl) -> ty::PolyFnSig<'tcx> {
627 let astconv: &AstConv = self;
628
629 let supplied_arguments = decl.inputs.iter().map(|a| {
630 // Convert the types that the user supplied (if any), but ignore them.
631 astconv.ast_ty_to_ty(a);
632 self.tcx.types.err
633 });
634
635 match decl.output {
636 hir::Return(ref output) => {
637 astconv.ast_ty_to_ty(&output);
638 }
639 hir::DefaultReturn(_) => {}
640 }
641
642 let result = ty::Binder(self.tcx.mk_fn_sig(
643 supplied_arguments,
644 self.tcx.types.err,
645 decl.variadic,
646 hir::Unsafety::Normal,
647 Abi::RustCall,
648 ));
649
650 debug!("supplied_sig_of_closure: result={:?}", result);
651
652 result
653 }
654
655 fn closure_sigs(
656 &self,
657 expr_def_id: DefId,
658 body: &hir::Body,
659 bound_sig: ty::PolyFnSig<'tcx>,
660 ) -> ClosureSignatures<'tcx> {
661 let liberated_sig = self.tcx()
662 .liberate_late_bound_regions(expr_def_id, &bound_sig);
663 let liberated_sig = self.inh.normalize_associated_types_in(
664 body.value.span,
665 body.value.id,
666 self.param_env,
667 &liberated_sig,
668 );
669 ClosureSignatures {
670 bound_sig,
671 liberated_sig,
672 }
673 }
674 }