Skip to content

Commit f4b8854

Browse files
committed
Pointers to bound variables are stored after all patterns are matched.
Pointers to bound variables shouldn't be stored before checking pattern, otherwise piped patterns can conflict with each other (issue #6338). Closes #6338.
1 parent 6365c4a commit f4b8854

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

src/librustc/middle/trans/_match.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,17 @@ struct ArmData<'self> {
399399
bindings_map: @BindingsMap
400400
}
401401

402+
/**
403+
* Info about Match.
404+
* If all `pats` are matched then arm `data` will be executed.
405+
* As we proceed `bound_ptrs` are filled with pointers to values to be bound,
406+
* these pointers are stored in llmatch variables just before executing `data` arm.
407+
*/
402408
#[deriving(Clone)]
403409
struct Match<'self> {
404410
pats: ~[@ast::pat],
405-
data: ArmData<'self>
411+
data: ArmData<'self>,
412+
bound_ptrs: ~[(ident, ValueRef)]
406413
}
407414

408415
impl<'self> Repr for Match<'self> {
@@ -447,14 +454,13 @@ fn expand_nested_bindings<'r>(bcx: @mut Block,
447454
br.pats.slice(col + 1u,
448455
br.pats.len())));
449456

450-
let binding_info =
451-
br.data.bindings_map.get(&path_to_ident(path));
452-
453-
Store(bcx, val, binding_info.llmatch);
454-
Match {
457+
let mut res = Match {
455458
pats: pats,
456-
data: br.data.clone()
457-
}
459+
data: br.data.clone(),
460+
bound_ptrs: br.bound_ptrs.clone()
461+
};
462+
res.bound_ptrs.push((path_to_ident(path), val));
463+
res
458464
}
459465
_ => (*br).clone(),
460466
}
@@ -496,21 +502,20 @@ fn enter_match<'r>(bcx: @mut Block,
496502
br.pats.slice(col + 1u, br.pats.len()));
497503

498504
let this = br.pats[col];
505+
let mut bound_ptrs = br.bound_ptrs.clone();
499506
match this.node {
500507
ast::pat_ident(_, ref path, None) => {
501508
if pat_is_binding(dm, this) {
502-
let binding_info =
503-
br.data.bindings_map.get(
504-
&path_to_ident(path));
505-
Store(bcx, val, binding_info.llmatch);
509+
bound_ptrs.push((path_to_ident(path), val));
506510
}
507511
}
508512
_ => {}
509513
}
510514

511515
result.push(Match {
512516
pats: pats,
513-
data: br.data.clone()
517+
data: br.data.clone(),
518+
bound_ptrs: bound_ptrs
514519
});
515520
}
516521
None => ()
@@ -1414,6 +1419,10 @@ fn compile_submatch(bcx: @mut Block,
14141419
}
14151420
if m[0].pats.len() == 0u {
14161421
let data = &m[0].data;
1422+
for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
1423+
let llmatch = data.bindings_map.get(ident).llmatch;
1424+
Store(bcx, *value_ptr, llmatch);
1425+
}
14171426
match data.arm.guard {
14181427
Some(guard_expr) => {
14191428
bcx = compile_guard(bcx,
@@ -1839,6 +1848,7 @@ fn trans_match_inner(scope_cx: @mut Block,
18391848
matches.push(Match {
18401849
pats: ~[*p],
18411850
data: arm_data.clone(),
1851+
bound_ptrs: ~[],
18421852
});
18431853
}
18441854
}

src/test/run-pass/match-pipe-binding.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// xfail-test
12-
1311
fn test1() {
1412
// from issue 6338
1513
match ((1, ~"a"), (2, ~"b")) {

0 commit comments

Comments
 (0)