Skip to content

Commit 2616581

Browse files
committed
Refactor helper routines to be less tied to match syntax
1 parent dcd8490 commit 2616581

File tree

1 file changed

+64
-53
lines changed

1 file changed

+64
-53
lines changed

src/librustc/middle/trans/_match.rs

Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,10 +1124,10 @@ pub fn compare_values(cx: block,
11241124
}
11251125
}
11261126

1127-
pub fn store_non_ref_bindings(bcx: block,
1128-
data: &ArmData,
1129-
opt_temp_cleanups: Option<&mut ~[ValueRef]>)
1130-
-> block
1127+
fn store_non_ref_bindings(bcx: block,
1128+
bindings_map: &BindingsMap,
1129+
mut opt_temp_cleanups: Option<&mut ~[ValueRef]>)
1130+
-> block
11311131
{
11321132
/*!
11331133
*
@@ -1139,8 +1139,7 @@ pub fn store_non_ref_bindings(bcx: block,
11391139
*/
11401140

11411141
let mut bcx = bcx;
1142-
let mut opt_temp_cleanups = opt_temp_cleanups;
1143-
for data.bindings_map.each_value |&binding_info| {
1142+
for bindings_map.each_value |&binding_info| {
11441143
match binding_info.trmode {
11451144
TrByValue(is_move, lldest) => {
11461145
let llval = Load(bcx, binding_info.llmatch); // get a T*
@@ -1166,16 +1165,22 @@ pub fn store_non_ref_bindings(bcx: block,
11661165
return bcx;
11671166
}
11681167

1169-
pub fn insert_lllocals(bcx: block,
1170-
data: &ArmData,
1171-
add_cleans: bool) -> block {
1168+
fn insert_lllocals(bcx: block,
1169+
bindings_map: &BindingsMap,
1170+
binding_mode: IrrefutablePatternBindingMode,
1171+
add_cleans: bool) -> block {
11721172
/*!
1173-
*
11741173
* For each binding in `data.bindings_map`, adds an appropriate entry into
11751174
* the `fcx.lllocals` map. If add_cleans is true, then adds cleanups for
1176-
* the bindings. */
1175+
* the bindings.
1176+
*/
11771177

1178-
for data.bindings_map.each_value |&binding_info| {
1178+
let llmap = match binding_mode {
1179+
BindLocal => bcx.fcx.lllocals,
1180+
BindArgument => bcx.fcx.llargs
1181+
};
1182+
1183+
for bindings_map.each_value |&binding_info| {
11791184
let llval = match binding_info.trmode {
11801185
// By value bindings: use the stack slot that we
11811186
// copied/moved the value into
@@ -1193,8 +1198,10 @@ pub fn insert_lllocals(bcx: block,
11931198
}
11941199
};
11951200

1196-
bcx.fcx.lllocals.insert(binding_info.id,
1197-
local_mem(llval));
1201+
debug!("binding %? to %s",
1202+
binding_info.id,
1203+
val_str(bcx.ccx().tn, llval));
1204+
llmap.insert(binding_info.id, local_mem(llval));
11981205
}
11991206
return bcx;
12001207
}
@@ -1215,8 +1222,8 @@ pub fn compile_guard(bcx: block,
12151222

12161223
let mut bcx = bcx;
12171224
let mut temp_cleanups = ~[];
1218-
bcx = store_non_ref_bindings(bcx, data, Some(&mut temp_cleanups));
1219-
bcx = insert_lllocals(bcx, data, false);
1225+
bcx = store_non_ref_bindings(bcx, &data.bindings_map, Some(&mut temp_cleanups));
1226+
bcx = insert_lllocals(bcx, &data.bindings_map, BindLocal, false);
12201227

12211228
let val = unpack_result!(bcx, {
12221229
do with_scope_result(bcx, guard_expr.info(),
@@ -1613,6 +1620,42 @@ pub fn trans_match(bcx: block,
16131620
}
16141621
}
16151622

1623+
fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap {
1624+
// Create the bindings map, which is a mapping from each binding name
1625+
// to an alloca() that will be the value for that local variable.
1626+
// Note that we use the names because each binding will have many ids
1627+
// from the various alternatives.
1628+
let ccx = bcx.ccx();
1629+
let tcx = bcx.tcx();
1630+
let mut bindings_map = HashMap::new();
1631+
do pat_bindings(tcx.def_map, pat) |bm, p_id, _s, path| {
1632+
let ident = path_to_ident(path);
1633+
let variable_ty = node_id_type(bcx, p_id);
1634+
let llvariable_ty = type_of::type_of(ccx, variable_ty);
1635+
1636+
let llmatch, trmode;
1637+
match bm {
1638+
ast::bind_by_copy | ast::bind_infer => {
1639+
// in this case, the final type of the variable will be T,
1640+
// but during matching we need to store a *T as explained
1641+
// above
1642+
let is_move = ccx.maps.moves_map.contains(&p_id);
1643+
llmatch = alloca(bcx, T_ptr(llvariable_ty));
1644+
trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
1645+
}
1646+
ast::bind_by_ref(_) => {
1647+
llmatch = alloca(bcx, llvariable_ty);
1648+
trmode = TrByRef;
1649+
}
1650+
};
1651+
bindings_map.insert(ident, BindingInfo {
1652+
llmatch: llmatch, trmode: trmode,
1653+
id: p_id, ty: variable_ty
1654+
});
1655+
}
1656+
return bindings_map;
1657+
}
1658+
16161659
pub fn trans_match_inner(scope_cx: block,
16171660
discr_expr: @ast::expr,
16181661
arms: &[ast::arm],
@@ -1629,41 +1672,9 @@ pub fn trans_match_inner(scope_cx: block,
16291672
}
16301673

16311674
let mut arm_datas = ~[], matches = ~[];
1632-
for arms.each |arm| {
1633-
let body = scope_block(bcx, arm.body.info(), "case_body");
1634-
1635-
// Create the bindings map, which is a mapping from each binding name
1636-
// to an alloca() that will be the value for that local variable.
1637-
// Note that we use the names because each binding will have many ids
1638-
// from the various alternatives.
1639-
let mut bindings_map = HashMap::new();
1640-
do pat_bindings(tcx.def_map, arm.pats[0]) |bm, p_id, _s, path| {
1641-
let ident = path_to_ident(path);
1642-
let variable_ty = node_id_type(bcx, p_id);
1643-
let llvariable_ty = type_of::type_of(bcx.ccx(), variable_ty);
1644-
1645-
let llmatch, trmode;
1646-
match bm {
1647-
ast::bind_by_copy | ast::bind_infer => {
1648-
// in this case, the final type of the variable will be T,
1649-
// but during matching we need to store a *T as explained
1650-
// above
1651-
let is_move =
1652-
scope_cx.ccx().maps.moves_map.contains(&p_id);
1653-
llmatch = alloca(bcx, T_ptr(llvariable_ty));
1654-
trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
1655-
}
1656-
ast::bind_by_ref(_) => {
1657-
llmatch = alloca(bcx, llvariable_ty);
1658-
trmode = TrByRef;
1659-
}
1660-
};
1661-
bindings_map.insert(ident, BindingInfo {
1662-
llmatch: llmatch, trmode: trmode,
1663-
id: p_id, ty: variable_ty
1664-
});
1665-
}
1666-
1675+
for vec::each(arms) |arm| {
1676+
let body = scope_block(bcx, arm.body.info(), ~"case_body");
1677+
let bindings_map = create_bindings_map(bcx, arm.pats[0]);
16671678
let arm_data = @ArmData {bodycx: body,
16681679
arm: arm,
16691680
bindings_map: bindings_map};
@@ -1697,11 +1708,11 @@ pub fn trans_match_inner(scope_cx: block,
16971708
// is just to reduce code space. See extensive comment at the start
16981709
// of the file for more details.
16991710
if arm_data.arm.guard.is_none() {
1700-
bcx = store_non_ref_bindings(bcx, *arm_data, None);
1711+
bcx = store_non_ref_bindings(bcx, &arm_data.bindings_map, None);
17011712
}
17021713

17031714
// insert bindings into the lllocals map and add cleanups
1704-
bcx = insert_lllocals(bcx, *arm_data, true);
1715+
bcx = insert_lllocals(bcx, &arm_data.bindings_map, BindLocal, true);
17051716

17061717
bcx = controlflow::trans_block(bcx, &arm_data.arm.body, dest);
17071718
bcx = trans_block_cleanups(bcx, block_cleanups(arm_data.bodycx));

0 commit comments

Comments
 (0)