|
13 | 13 | use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; |
14 | 14 |
|
15 | 15 | use astconv::AstConv; |
| 16 | +use middle::region; |
16 | 17 | use rustc::hir::def_id::DefId; |
17 | 18 | use rustc::infer::{InferOk, InferResult}; |
18 | 19 | use rustc::infer::LateBoundRegionConversionTime; |
19 | 20 | use rustc::infer::type_variable::TypeVariableOrigin; |
| 21 | +use rustc::traits::Obligation; |
20 | 22 | use rustc::traits::error_reporting::ArgKind; |
21 | 23 | use rustc::ty::{self, ToPolyTraitRef, Ty, GenericParamDefKind}; |
22 | 24 | use rustc::ty::fold::TypeFoldable; |
@@ -479,7 +481,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { |
479 | 481 | // Along the way, it also writes out entries for types that the user |
480 | 482 | // wrote into our tables, which are then later used by the privacy |
481 | 483 | // check. |
482 | | - match self.check_supplied_sig_against_expectation(expr_def_id, decl, &closure_sigs) { |
| 484 | + match self.check_supplied_sig_against_expectation(expr_def_id, decl, body, &closure_sigs) { |
483 | 485 | Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok), |
484 | 486 | Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body), |
485 | 487 | } |
@@ -523,6 +525,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { |
523 | 525 | &self, |
524 | 526 | expr_def_id: DefId, |
525 | 527 | decl: &hir::FnDecl, |
| 528 | + body: &hir::Body, |
526 | 529 | expected_sigs: &ClosureSignatures<'tcx>, |
527 | 530 | ) -> InferResult<'tcx, ()> { |
528 | 531 | // Get the signature S that the user gave. |
@@ -575,6 +578,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { |
575 | 578 | } = self.at(cause, self.param_env) |
576 | 579 | .eq(*expected_ty, supplied_ty)?; |
577 | 580 | all_obligations.extend(obligations); |
| 581 | + |
| 582 | + // Also, require that the supplied type must outlive |
| 583 | + // the closure body. |
| 584 | + let closure_body_region = self.tcx.mk_region( |
| 585 | + ty::ReScope( |
| 586 | + region::Scope { |
| 587 | + id: body.value.hir_id.local_id, |
| 588 | + data: region::ScopeData::Node, |
| 589 | + }, |
| 590 | + ), |
| 591 | + ); |
| 592 | + all_obligations.push( |
| 593 | + Obligation::new( |
| 594 | + cause.clone(), |
| 595 | + self.param_env, |
| 596 | + ty::Predicate::TypeOutlives( |
| 597 | + ty::Binder::dummy( |
| 598 | + ty::OutlivesPredicate( |
| 599 | + supplied_ty, |
| 600 | + closure_body_region, |
| 601 | + ), |
| 602 | + ), |
| 603 | + ), |
| 604 | + ), |
| 605 | + ); |
578 | 606 | } |
579 | 607 |
|
580 | 608 | let (supplied_output_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var( |
|
0 commit comments