Skip to content

Commit 4e5666e

Browse files
committed
Fix missing entries in upvar borrows map for capture-by-ref unboxed closures
This prevents a later ICE in borrowck. Closes issue #17655
1 parent a70a037 commit 4e5666e

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

src/librustc/middle/typeck/check/regionck.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
844844
// has static lifetime.
845845
} else {
846846
// Variables being referenced must outlive closure.
847-
constrain_free_variables_in_stack_closure(
847+
constrain_free_variables_in_by_ref_closure(
848848
rcx, bounds.region_bound, expr, freevars);
849849

850850
// Closure is stack allocated and hence cannot
@@ -856,20 +856,17 @@ fn check_expr_fn_block(rcx: &mut Rcx,
856856
});
857857
}
858858
ty::ty_unboxed_closure(_, region) => {
859-
ty::with_freevars(tcx, expr.id, |freevars| {
860-
// No free variables means that there is no environment and
861-
// hence the closure has static lifetime. Otherwise, the
862-
// closure must not outlive the variables it closes over
863-
// by-reference.
864-
//
865-
// NDM -- this seems wrong, discuss with pcwalton, should
866-
// be straightforward enough.
867-
if !freevars.is_empty() {
868-
let bounds = ty::region_existential_bound(region);
869-
ensure_free_variable_types_outlive_closure_bound(
870-
rcx, bounds, expr, freevars);
871-
}
872-
})
859+
let bounds = ty::region_existential_bound(region);
860+
if tcx.capture_modes.borrow().get_copy(&expr.id) == ast::CaptureByRef {
861+
ty::with_freevars(tcx, expr.id, |freevars| {
862+
if !freevars.is_empty() {
863+
// Variables being referenced must be constrained and registered
864+
// in the upvar borrow map
865+
constrain_free_variables_in_by_ref_closure(
866+
rcx, bounds.region_bound, expr, freevars);
867+
}
868+
})
869+
}
873870
}
874871
_ => { }
875872
}
@@ -884,6 +881,13 @@ fn check_expr_fn_block(rcx: &mut Rcx,
884881
propagate_upupvar_borrow_kind(rcx, expr, freevars);
885882
})
886883
}
884+
ty::ty_unboxed_closure(..) => {
885+
if tcx.capture_modes.borrow().get_copy(&expr.id) == ast::CaptureByRef {
886+
ty::with_freevars(tcx, expr.id, |freevars| {
887+
propagate_upupvar_borrow_kind(rcx, expr, freevars);
888+
});
889+
}
890+
}
887891
_ => {}
888892
}
889893

@@ -893,6 +897,12 @@ fn check_expr_fn_block(rcx: &mut Rcx,
893897
ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
894898
})
895899
}
900+
ty::ty_unboxed_closure(_, region) => {
901+
ty::with_freevars(tcx, expr.id, |freevars| {
902+
let bounds = ty::region_existential_bound(region);
903+
ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
904+
})
905+
}
896906
_ => {}
897907
}
898908

@@ -959,7 +969,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
959969
}
960970
}
961971

962-
fn constrain_free_variables_in_stack_closure(
972+
fn constrain_free_variables_in_by_ref_closure(
963973
rcx: &mut Rcx,
964974
region_bound: ty::Region,
965975
expr: &ast::Expr,

0 commit comments

Comments
 (0)