|
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