parent
e9f5a099df
commit
53ce42dc4f
13 changed files with 88 additions and 18 deletions
|
@ -360,6 +360,7 @@ enum pat_ {
|
||||||
pat_tup(~[@pat]),
|
pat_tup(~[@pat]),
|
||||||
pat_box(@pat),
|
pat_box(@pat),
|
||||||
pat_uniq(@pat),
|
pat_uniq(@pat),
|
||||||
|
pat_region(@pat), // borrowed pointer pattern
|
||||||
pat_lit(@expr),
|
pat_lit(@expr),
|
||||||
pat_range(@expr, @expr),
|
pat_range(@expr, @expr),
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,7 +595,7 @@ fn walk_pat(pat: @pat, it: fn(@pat)) {
|
||||||
pat_enum(_, Some(s)) | pat_tup(s) => for s.each |p| {
|
pat_enum(_, Some(s)) | pat_tup(s) => for s.each |p| {
|
||||||
walk_pat(p, it)
|
walk_pat(p, it)
|
||||||
},
|
},
|
||||||
pat_box(s) | pat_uniq(s) => walk_pat(s, it),
|
pat_box(s) | pat_uniq(s) | pat_region(s) => walk_pat(s, it),
|
||||||
pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _)
|
pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _)
|
||||||
| pat_enum(_, _) => ()
|
| pat_enum(_, _) => ()
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,6 +384,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
|
||||||
pat_tup(elts) => pat_tup(vec::map(elts, |x| fld.fold_pat(x))),
|
pat_tup(elts) => pat_tup(vec::map(elts, |x| fld.fold_pat(x))),
|
||||||
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)),
|
pat_uniq(inner) => pat_uniq(fld.fold_pat(inner)),
|
||||||
|
pat_region(inner) => pat_region(fld.fold_pat(inner)),
|
||||||
pat_range(e1, e2) => {
|
pat_range(e1, e2) => {
|
||||||
pat_range(fld.fold_expr(e1), fld.fold_expr(e2))
|
pat_range(fld.fold_expr(e1), fld.fold_expr(e2))
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
|
||||||
mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq,
|
mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq,
|
||||||
match_tok, method, mode, module_ns, mt, mul, mutability,
|
match_tok, method, mode, module_ns, mt, mul, mutability,
|
||||||
named_field, neg, noreturn, not, pat, pat_box, pat_enum,
|
named_field, neg, noreturn, not, pat, pat_box, pat_enum,
|
||||||
pat_ident, pat_lit, pat_range, pat_rec, pat_struct, pat_tup,
|
pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct,
|
||||||
pat_uniq, pat_wild, path, private, proto, proto_bare,
|
pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare,
|
||||||
proto_block, proto_box, proto_uniq, provided, public, pure_fn,
|
proto_block, proto_box, proto_uniq, provided, public, pure_fn,
|
||||||
purity, re_anon, re_named, region, rem, required, ret_style,
|
purity, re_anon, re_named, region, rem, required, ret_style,
|
||||||
return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
|
return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
|
||||||
|
@ -1844,6 +1844,25 @@ struct parser {
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
token::BINOP(token::AND) => {
|
||||||
|
let lo = self.span.lo;
|
||||||
|
self.bump();
|
||||||
|
let sub = self.parse_pat(refutable);
|
||||||
|
hi = sub.span.hi;
|
||||||
|
// HACK: parse &"..." as a literal of a borrowed str
|
||||||
|
pat = match sub.node {
|
||||||
|
pat_lit(e@@{
|
||||||
|
node: expr_lit(@{node: lit_str(_), span: _}), _
|
||||||
|
}) => {
|
||||||
|
let vst = @{id: self.get_id(), callee_id: self.get_id(),
|
||||||
|
node: expr_vstore(e,
|
||||||
|
vstore_slice(self.region_from_name(None))),
|
||||||
|
span: mk_sp(lo, hi)};
|
||||||
|
pat_lit(vst)
|
||||||
|
}
|
||||||
|
_ => pat_region(sub)
|
||||||
|
};
|
||||||
|
}
|
||||||
token::LBRACE => {
|
token::LBRACE => {
|
||||||
self.bump();
|
self.bump();
|
||||||
let (fields, etc) = self.parse_pat_fields(refutable);
|
let (fields, etc) = self.parse_pat_fields(refutable);
|
||||||
|
|
|
@ -1537,6 +1537,10 @@ fn print_pat(s: ps, &&pat: @ast::pat) {
|
||||||
}
|
}
|
||||||
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); }
|
ast::pat_uniq(inner) => { word(s.s, ~"~"); print_pat(s, inner); }
|
||||||
|
ast::pat_region(inner) => {
|
||||||
|
word(s.s, ~"&");
|
||||||
|
print_pat(s, inner);
|
||||||
|
}
|
||||||
ast::pat_lit(e) => print_expr(s, e),
|
ast::pat_lit(e) => print_expr(s, e),
|
||||||
ast::pat_range(begin, end) => {
|
ast::pat_range(begin, end) => {
|
||||||
print_expr(s, begin);
|
print_expr(s, begin);
|
||||||
|
|
|
@ -237,7 +237,8 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
|
||||||
pat_tup(elts) => for elts.each |elt| {
|
pat_tup(elts) => for elts.each |elt| {
|
||||||
v.visit_pat(elt, e, v)
|
v.visit_pat(elt, e, v)
|
||||||
},
|
},
|
||||||
pat_box(inner) | pat_uniq(inner) => v.visit_pat(inner, e, v),
|
pat_box(inner) | pat_uniq(inner) | pat_region(inner) =>
|
||||||
|
v.visit_pat(inner, e, v),
|
||||||
pat_ident(_, path, inner) => {
|
pat_ident(_, path, inner) => {
|
||||||
visit_path(path, e, v);
|
visit_path(path, e, v);
|
||||||
do option::iter(inner) |subpat| { v.visit_pat(subpat, e, v)};
|
do option::iter(inner) |subpat| { v.visit_pat(subpat, e, v)};
|
||||||
|
|
|
@ -235,7 +235,7 @@ fn pat_ctor_id(tcx: ty::ctxt, p: @pat) -> Option<ctor> {
|
||||||
pat_range(lo, hi) => {
|
pat_range(lo, hi) => {
|
||||||
Some(range(eval_const_expr(tcx, lo), eval_const_expr(tcx, hi)))
|
Some(range(eval_const_expr(tcx, lo), eval_const_expr(tcx, hi)))
|
||||||
}
|
}
|
||||||
pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) |
|
pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) | pat_region(*) |
|
||||||
pat_struct(*) => {
|
pat_struct(*) => {
|
||||||
Some(single)
|
Some(single)
|
||||||
}
|
}
|
||||||
|
@ -258,8 +258,8 @@ fn is_wild(tcx: ty::ctxt, p: @pat) -> bool {
|
||||||
|
|
||||||
fn missing_ctor(tcx: ty::ctxt, m: matrix, left_ty: ty::t) -> Option<ctor> {
|
fn missing_ctor(tcx: ty::ctxt, m: matrix, left_ty: ty::t) -> Option<ctor> {
|
||||||
match ty::get(left_ty).struct {
|
match ty::get(left_ty).struct {
|
||||||
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_tup(_) | ty::ty_rec(_) |
|
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) |
|
||||||
ty::ty_class(*) => {
|
ty::ty_rec(_) | ty::ty_class(*) => {
|
||||||
for m.each |r| {
|
for m.each |r| {
|
||||||
if !is_wild(tcx, r[0]) { return None; }
|
if !is_wild(tcx, r[0]) { return None; }
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ fn ctor_arity(tcx: ty::ctxt, ctor: ctor, ty: ty::t) -> uint {
|
||||||
match ty::get(ty).struct {
|
match ty::get(ty).struct {
|
||||||
ty::ty_tup(fs) => fs.len(),
|
ty::ty_tup(fs) => fs.len(),
|
||||||
ty::ty_rec(fs) => fs.len(),
|
ty::ty_rec(fs) => fs.len(),
|
||||||
ty::ty_box(_) | ty::ty_uniq(_) => 1u,
|
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u,
|
||||||
ty::ty_enum(eid, _) => {
|
ty::ty_enum(eid, _) => {
|
||||||
let id = match ctor { variant(id) => id,
|
let id = match ctor { variant(id) => id,
|
||||||
_ => fail ~"impossible case" };
|
_ => fail ~"impossible case" };
|
||||||
|
@ -386,7 +386,8 @@ fn specialize(tcx: ty::ctxt, r: ~[@pat], ctor_id: ctor, arity: uint,
|
||||||
Some(vec::append(args, vec::tail(r)))
|
Some(vec::append(args, vec::tail(r)))
|
||||||
}
|
}
|
||||||
pat_tup(args) => Some(vec::append(args, vec::tail(r))),
|
pat_tup(args) => Some(vec::append(args, vec::tail(r))),
|
||||||
pat_box(a) | pat_uniq(a) => Some(vec::append(~[a], vec::tail(r))),
|
pat_box(a) | pat_uniq(a) | pat_region(a) =>
|
||||||
|
Some(vec::append(~[a], vec::tail(r))),
|
||||||
pat_lit(expr) => {
|
pat_lit(expr) => {
|
||||||
let e_v = eval_const_expr(tcx, expr);
|
let e_v = eval_const_expr(tcx, expr);
|
||||||
let match_ = match ctor_id {
|
let match_ = match ctor_id {
|
||||||
|
@ -440,7 +441,8 @@ fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
match pat.node {
|
match pat.node {
|
||||||
pat_box(sub) | pat_uniq(sub) | pat_ident(_, _, Some(sub)) => {
|
pat_box(sub) | pat_uniq(sub) | pat_region(sub) |
|
||||||
|
pat_ident(_, _, Some(sub)) => {
|
||||||
is_refutable(tcx, sub)
|
is_refutable(tcx, sub)
|
||||||
}
|
}
|
||||||
pat_wild | pat_ident(_, _, None) => { false }
|
pat_wild | pat_ident(_, _, None) => { false }
|
||||||
|
|
|
@ -898,8 +898,9 @@ impl &mem_categorization_ctxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::pat_box(subpat) | ast::pat_uniq(subpat) => {
|
ast::pat_box(subpat) | ast::pat_uniq(subpat) |
|
||||||
// @p1, ~p1
|
ast::pat_region(subpat) => {
|
||||||
|
// @p1, ~p1, &p1
|
||||||
match self.cat_deref(subpat, cmt, 0u, true) {
|
match self.cat_deref(subpat, cmt, 0u, true) {
|
||||||
Some(subcmt) => {
|
Some(subcmt) => {
|
||||||
self.cat_pattern(subcmt, subpat, op);
|
self.cat_pattern(subcmt, subpat, op);
|
||||||
|
|
|
@ -914,12 +914,8 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
|
||||||
bcx = bind_irrefutable_pat(bcx, elem, fldptr, make_copy);
|
bcx = bind_irrefutable_pat(bcx, elem, fldptr, make_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::pat_box(inner) => {
|
ast::pat_box(inner) | ast::pat_uniq(inner) |
|
||||||
let llbox = Load(bcx, val);
|
ast::pat_region(inner) => {
|
||||||
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
|
|
||||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
|
||||||
}
|
|
||||||
ast::pat_uniq(inner) => {
|
|
||||||
let llbox = Load(bcx, val);
|
let llbox = Load(bcx, val);
|
||||||
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
|
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
|
||||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
bcx = bind_irrefutable_pat(bcx, inner, unboxed, true);
|
||||||
|
|
|
@ -447,6 +447,22 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast::pat_region(inner) => {
|
||||||
|
match structure_of(fcx, pat.span, expected) {
|
||||||
|
ty::ty_rptr(_, e_inner) => {
|
||||||
|
check_pat(pcx, inner, e_inner.ty);
|
||||||
|
fcx.write_ty(pat.id, expected);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
tcx.sess.span_fatal(
|
||||||
|
pat.span,
|
||||||
|
~"mismatched types: expected `" +
|
||||||
|
fcx.infcx().ty_to_str(expected) +
|
||||||
|
~"` found borrowed pointer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/test/run-pass/borrowed-ptr-pattern-2.rs
Normal file
10
src/test/run-pass/borrowed-ptr-pattern-2.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
fn foo<T>(s: &str) {
|
||||||
|
match s {
|
||||||
|
&"kitty" => fail ~"cat",
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
10
src/test/run-pass/borrowed-ptr-pattern-3.rs
Normal file
10
src/test/run-pass/borrowed-ptr-pattern-3.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
fn foo<T>(s: &r/uint) {
|
||||||
|
match s {
|
||||||
|
&3 => fail ~"oh",
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
9
src/test/run-pass/borrowed-ptr-pattern.rs
Normal file
9
src/test/run-pass/borrowed-ptr-pattern.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
fn foo<T>(x: &T) {
|
||||||
|
match x {
|
||||||
|
&a => fail #fmt("%?", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue