mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
parent
87700adb2f
commit
2082f67765
@ -665,6 +665,13 @@ fn pattern_roots(tcx: ty::ctxt, mut: option::t<unsafe_ty>, pat: @ast::pat)
|
|||||||
};
|
};
|
||||||
walk(tcx, m ? some(contains(ty)) : mut, p, set);
|
walk(tcx, m ? some(contains(ty)) : mut, p, set);
|
||||||
}
|
}
|
||||||
|
ast::pat_uniq(p) {
|
||||||
|
let ty = ty::node_id_to_type(tcx, pat.id);
|
||||||
|
let m = alt ty::struct(tcx, ty) {
|
||||||
|
ty::ty_uniq(mt) { mt.mut != ast::imm }
|
||||||
|
};
|
||||||
|
walk(tcx, m ? some(contains(ty)) : mut, p, set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let set = [];
|
let set = [];
|
||||||
|
@ -98,6 +98,12 @@ fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
|
|||||||
_ { ret pattern_supersedes(tcx, suba, b); }
|
_ { ret pattern_supersedes(tcx, suba, b); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pat_uniq(suba) {
|
||||||
|
alt b.node {
|
||||||
|
pat_uniq(subb) { ret pattern_supersedes(tcx, suba, subb); }
|
||||||
|
_ { ret pattern_supersedes(tcx, suba, b); }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +176,17 @@ fn enter_box(m: match, col: uint, val: ValueRef) -> match {
|
|||||||
ret enter_match(m, col, val, bind e(dummy, _));
|
ret enter_match(m, col, val, bind e(dummy, _));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enter_uniq(m: match, col: uint, val: ValueRef) -> match {
|
||||||
|
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
|
||||||
|
fn e(dummy: @ast::pat, p: @ast::pat) -> option::t<[@ast::pat]> {
|
||||||
|
alt p.node {
|
||||||
|
ast::pat_uniq(sub) { ret some([sub]); }
|
||||||
|
_ { ret some([dummy]); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret enter_match(m, col, val, bind e(dummy, _));
|
||||||
|
}
|
||||||
|
|
||||||
fn get_options(ccx: @crate_ctxt, m: match, col: uint) -> [opt] {
|
fn get_options(ccx: @crate_ctxt, m: match, col: uint) -> [opt] {
|
||||||
fn add_to_set(&set: [opt], val: opt) {
|
fn add_to_set(&set: [opt], val: opt) {
|
||||||
for l: opt in set { if opt_eq(l, val) { ret; } }
|
for l: opt in set { if opt_eq(l, val) { ret; } }
|
||||||
@ -249,6 +260,13 @@ fn any_box_pat(m: match, col: uint) -> bool {
|
|||||||
ret false;
|
ret false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn any_uniq_pat(m: match, col: uint) -> bool {
|
||||||
|
for br: match_branch in m {
|
||||||
|
alt br.pats[col].node { ast::pat_uniq(_) { ret true; } _ { } }
|
||||||
|
}
|
||||||
|
ret false;
|
||||||
|
}
|
||||||
|
|
||||||
fn any_tup_pat(m: match, col: uint) -> bool {
|
fn any_tup_pat(m: match, col: uint) -> bool {
|
||||||
for br: match_branch in m {
|
for br: match_branch in m {
|
||||||
alt br.pats[col].node { ast::pat_tup(_) { ret true; } _ { } }
|
alt br.pats[col].node { ast::pat_tup(_) { ret true; } _ { } }
|
||||||
@ -386,6 +404,13 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
|||||||
ret;
|
ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if any_uniq_pat(m, col) {
|
||||||
|
let unboxed = Load(bcx, val);
|
||||||
|
compile_submatch(bcx, enter_uniq(m, col, val),
|
||||||
|
[unboxed] + vals_left, f, exits);
|
||||||
|
ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Decide what kind of branch we need
|
// Decide what kind of branch we need
|
||||||
let opts = get_options(ccx, m, col);
|
let opts = get_options(ccx, m, col);
|
||||||
tag branch_kind { no_branch; single; switch; compare; }
|
tag branch_kind { no_branch; single; switch; compare; }
|
||||||
|
@ -1435,6 +1435,20 @@ fn check_pat(fcx: @fn_ctxt, map: ast_util::pat_id_map, pat: @ast::pat,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast::pat_uniq(inner) {
|
||||||
|
alt structure_of(fcx, pat.span, expected) {
|
||||||
|
ty::ty_uniq(e_inner) {
|
||||||
|
check_pat(fcx, map, inner, e_inner.ty);
|
||||||
|
write::ty_only_fixup(fcx, pat.id, expected);
|
||||||
|
}
|
||||||
|
_ {
|
||||||
|
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||||
|
"mismatched types: expected " +
|
||||||
|
ty_to_str(fcx.ccx.tcx, expected) +
|
||||||
|
" found uniq");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ tag pat_ {
|
|||||||
pat_rec([field_pat], bool);
|
pat_rec([field_pat], bool);
|
||||||
pat_tup([@pat]);
|
pat_tup([@pat]);
|
||||||
pat_box(@pat);
|
pat_box(@pat);
|
||||||
|
pat_uniq(@pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
tag mutability { mut; imm; maybe_mut; }
|
tag mutability { mut; imm; maybe_mut; }
|
||||||
|
@ -69,6 +69,7 @@ iter pat_bindings(pat: @pat) -> @pat {
|
|||||||
for elt in elts { for each b in pat_bindings(elt) { put b; } }
|
for elt in elts { for each b in pat_bindings(elt) { put b; } }
|
||||||
}
|
}
|
||||||
pat_box(sub) { for each b in pat_bindings(sub) { put b; } }
|
pat_box(sub) { for each b in pat_bindings(sub) { put b; } }
|
||||||
|
pat_uniq(sub) { for each b in pat_bindings(sub) { put b; } }
|
||||||
pat_wild. | pat_lit(_) { }
|
pat_wild. | pat_lit(_) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,6 +291,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
|
|||||||
}
|
}
|
||||||
pat_tup(elts) { pat_tup(vec::map(fld.fold_pat, elts)) }
|
pat_tup(elts) { pat_tup(vec::map(fld.fold_pat, elts)) }
|
||||||
pat_box(inner) { pat_box(fld.fold_pat(inner)) }
|
pat_box(inner) { pat_box(fld.fold_pat(inner)) }
|
||||||
|
pat_uniq(inner) { pat_uniq(fld.fold_pat(inner)) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,6 +1425,12 @@ fn parse_pat(p: parser) -> @ast::pat {
|
|||||||
pat = ast::pat_box(sub);
|
pat = ast::pat_box(sub);
|
||||||
hi = sub.span.hi;
|
hi = sub.span.hi;
|
||||||
}
|
}
|
||||||
|
token::TILDE. {
|
||||||
|
p.bump();
|
||||||
|
let sub = parse_pat(p);
|
||||||
|
pat = ast::pat_uniq(sub);
|
||||||
|
hi = sub.span.hi;
|
||||||
|
}
|
||||||
token::LBRACE. {
|
token::LBRACE. {
|
||||||
p.bump();
|
p.bump();
|
||||||
let fields = [];
|
let fields = [];
|
||||||
|
@ -1113,6 +1113,7 @@ fn print_pat(s: ps, pat: @ast::pat) {
|
|||||||
pclose(s);
|
pclose(s);
|
||||||
}
|
}
|
||||||
ast::pat_box(inner) { word(s.s, "@"); print_pat(s, inner); }
|
ast::pat_box(inner) { word(s.s, "@"); print_pat(s, inner); }
|
||||||
|
ast::pat_uniq(inner) { word(s.s, "~"); print_pat(s, inner); }
|
||||||
}
|
}
|
||||||
s.ann.post(ann_node);
|
s.ann.post(ann_node);
|
||||||
}
|
}
|
||||||
|
10
src/test/run-pass/unique-pat.rs
Normal file
10
src/test/run-pass/unique-pat.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn simple() {
|
||||||
|
alt ~true {
|
||||||
|
~true { }
|
||||||
|
_ { fail; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
simple();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user