Properly bind nested pattern bindings when there's more than one
Fixes #15488.
This commit is contained in:
parent
e05ec9a2bf
commit
9f460e7af8
@ -411,14 +411,7 @@ fn is_useful(cx: &MatchCheckCtxt, matrix @ &Matrix(ref rows): &Matrix,
|
||||
return NotUseful;
|
||||
}
|
||||
let real_pat = match rows.iter().find(|r| r.get(0).id != 0) {
|
||||
Some(r) => {
|
||||
match r.get(0).node {
|
||||
// An arm of the form `ref x @ sub_pat` has type
|
||||
// `sub_pat`, not `&sub_pat` as `x` itself does.
|
||||
PatIdent(BindByRef(_), _, Some(sub)) => sub,
|
||||
_ => *r.get(0)
|
||||
}
|
||||
}
|
||||
Some(r) => raw_pat(*r.get(0)),
|
||||
None if v.len() == 0 => return NotUseful,
|
||||
None => v[0]
|
||||
};
|
||||
|
@ -413,25 +413,24 @@ fn expand_nested_bindings<'a, 'b>(
|
||||
let _indenter = indenter();
|
||||
|
||||
m.iter().map(|br| {
|
||||
match br.pats.get(col).node {
|
||||
ast::PatIdent(_, ref path1, Some(inner)) => {
|
||||
let pats = Vec::from_slice(br.pats.slice(0u, col))
|
||||
.append((vec!(inner))
|
||||
.append(br.pats.slice(col + 1u, br.pats.len())).as_slice());
|
||||
let mut bound_ptrs = br.bound_ptrs.clone();
|
||||
let mut pat = *br.pats.get(col);
|
||||
loop {
|
||||
pat = match pat.node {
|
||||
ast::PatIdent(_, ref path, Some(inner)) => {
|
||||
bound_ptrs.push((path.node, val));
|
||||
inner.clone()
|
||||
},
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
|
||||
let mut bound_ptrs = br.bound_ptrs.clone();
|
||||
bound_ptrs.push((path1.node, val));
|
||||
Match {
|
||||
pats: pats,
|
||||
data: &*br.data,
|
||||
bound_ptrs: bound_ptrs
|
||||
}
|
||||
}
|
||||
_ => Match {
|
||||
pats: br.pats.clone(),
|
||||
data: &*br.data,
|
||||
bound_ptrs: br.bound_ptrs.clone()
|
||||
}
|
||||
let mut pats = br.pats.clone();
|
||||
*pats.get_mut(col) = pat;
|
||||
Match {
|
||||
pats: pats,
|
||||
data: &*br.data,
|
||||
bound_ptrs: bound_ptrs
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
38
src/test/run-pass/match-pattern-bindings.rs
Normal file
38
src/test/run-pass/match-pattern-bindings.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
let value = Some(1i);
|
||||
assert_eq!(match value {
|
||||
ref a @ Some(_) => a,
|
||||
ref b @ None => b
|
||||
}, &Some(1i));
|
||||
assert_eq!(match value {
|
||||
ref a @ ref _c @ Some(_) => a,
|
||||
ref b @ None => b
|
||||
}, &Some(1i));
|
||||
assert_eq!(match value {
|
||||
_a @ ref c @ Some(_) => c,
|
||||
ref b @ None => b
|
||||
}, &Some(1i));
|
||||
assert_eq!(match "foobarbaz" {
|
||||
_a @ b @ _ => b
|
||||
}, "foobarbaz");
|
||||
|
||||
let a @ b @ c = "foobarbaz";
|
||||
assert_eq!(a, "foobarbaz");
|
||||
assert_eq!(b, "foobarbaz");
|
||||
assert_eq!(c, "foobarbaz");
|
||||
let value = Some(true);
|
||||
let ref a @ b @ ref c = value;
|
||||
assert_eq!(a, &Some(true));
|
||||
assert_eq!(b, Some(true));
|
||||
assert_eq!(c, &Some(true));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user