diff options
| author | Brian Koropoff <bkoropoff@gmail.com> | 2014-10-01 22:24:10 -0700 |
|---|---|---|
| committer | Brian Koropoff <bkoropoff@gmail.com> | 2014-10-02 21:08:08 -0700 |
| commit | 4e5666eace14651539ca2a1f5eed8cdf0ccfb130 (patch) | |
| tree | 8474f371f54e52da8181f089f70f814e55da38bc /src | |
| parent | a70a0374e24c146e714b0beb4437e571a488be4f (diff) | |
| download | rust-4e5666eace14651539ca2a1f5eed8cdf0ccfb130.tar.gz rust-4e5666eace14651539ca2a1f5eed8cdf0ccfb130.zip | |
Fix missing entries in upvar borrows map for capture-by-ref unboxed closures
This prevents a later ICE in borrowck. Closes issue #17655
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/typeck/check/regionck.rs | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 9e20028569b..3a14b90f789 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -844,7 +844,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, // has static lifetime. } else { // Variables being referenced must outlive closure. - constrain_free_variables_in_stack_closure( + constrain_free_variables_in_by_ref_closure( rcx, bounds.region_bound, expr, freevars); // Closure is stack allocated and hence cannot @@ -856,20 +856,17 @@ fn check_expr_fn_block(rcx: &mut Rcx, }); } ty::ty_unboxed_closure(_, region) => { - ty::with_freevars(tcx, expr.id, |freevars| { - // No free variables means that there is no environment and - // hence the closure has static lifetime. Otherwise, the - // closure must not outlive the variables it closes over - // by-reference. - // - // NDM -- this seems wrong, discuss with pcwalton, should - // be straightforward enough. - if !freevars.is_empty() { - let bounds = ty::region_existential_bound(region); - ensure_free_variable_types_outlive_closure_bound( - rcx, bounds, expr, freevars); - } - }) + let bounds = ty::region_existential_bound(region); + if tcx.capture_modes.borrow().get_copy(&expr.id) == ast::CaptureByRef { + ty::with_freevars(tcx, expr.id, |freevars| { + if !freevars.is_empty() { + // Variables being referenced must be constrained and registered + // in the upvar borrow map + constrain_free_variables_in_by_ref_closure( + rcx, bounds.region_bound, expr, freevars); + } + }) + } } _ => { } } @@ -884,6 +881,13 @@ fn check_expr_fn_block(rcx: &mut Rcx, propagate_upupvar_borrow_kind(rcx, expr, freevars); }) } + ty::ty_unboxed_closure(..) => { + if tcx.capture_modes.borrow().get_copy(&expr.id) == ast::CaptureByRef { + ty::with_freevars(tcx, expr.id, |freevars| { + propagate_upupvar_borrow_kind(rcx, expr, freevars); + }); + } + } _ => {} } @@ -893,6 +897,12 @@ fn check_expr_fn_block(rcx: &mut Rcx, ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars); }) } + ty::ty_unboxed_closure(_, region) => { + ty::with_freevars(tcx, expr.id, |freevars| { + let bounds = ty::region_existential_bound(region); + ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars); + }) + } _ => {} } @@ -959,7 +969,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, } } - fn constrain_free_variables_in_stack_closure( + fn constrain_free_variables_in_by_ref_closure( rcx: &mut Rcx, region_bound: ty::Region, expr: &ast::Expr, |
