diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-09-07 17:07:32 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-09-07 17:09:07 -0700 |
| commit | 53ce42dc4f4fceaf6881a3026f3dbc8fd81ae626 (patch) | |
| tree | fe06630b44b10afc5708cbebdacb9f8471580ab3 /src | |
| parent | e9f5a099dfcb42c7f2bb38974b57bbde7042ee9c (diff) | |
| download | rust-53ce42dc4f4fceaf6881a3026f3dbc8fd81ae626.tar.gz rust-53ce42dc4f4fceaf6881a3026f3dbc8fd81ae626.zip | |
Implement &-patterns
Closes #2855
Diffstat (limited to 'src')
| -rw-r--r-- | src/libsyntax/ast.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 3 | ||||
| -rw-r--r-- | src/rustc/middle/check_alt.rs | 14 | ||||
| -rw-r--r-- | src/rustc/middle/mem_categorization.rs | 5 | ||||
| -rw-r--r-- | src/rustc/middle/trans/alt.rs | 8 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check/alt.rs | 16 | ||||
| -rw-r--r-- | src/test/run-pass/borrowed-ptr-pattern-2.rs | 10 | ||||
| -rw-r--r-- | src/test/run-pass/borrowed-ptr-pattern-3.rs | 10 | ||||
| -rw-r--r-- | src/test/run-pass/borrowed-ptr-pattern.rs | 9 |
13 files changed, 88 insertions, 18 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 03106f97bc7..b1f54e701ac 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -360,6 +360,7 @@ enum pat_ { pat_tup(~[@pat]), pat_box(@pat), pat_uniq(@pat), + pat_region(@pat), // borrowed pointer pattern pat_lit(@expr), pat_range(@expr, @expr), } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 1ff4728f472..429028b966e 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -595,7 +595,7 @@ fn walk_pat(pat: @pat, it: fn(@pat)) { pat_enum(_, Some(s)) | pat_tup(s) => for s.each |p| { 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_enum(_, _) => () } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 976a57a919c..c7ce86921f6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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_box(inner) => pat_box(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(fld.fold_expr(e1), fld.fold_expr(e2)) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 175247bfaf3..a21d9de7567 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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, match_tok, method, mode, module_ns, mt, mul, mutability, named_field, neg, noreturn, not, pat, pat_box, pat_enum, - pat_ident, pat_lit, pat_range, pat_rec, pat_struct, pat_tup, - pat_uniq, pat_wild, path, private, proto, proto_bare, + pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct, + pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare, proto_block, proto_box, proto_uniq, provided, public, pure_fn, purity, re_anon, re_named, region, rem, required, ret_style, 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 => { self.bump(); let (fields, etc) = self.parse_pat_fields(refutable); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8b17760c7f2..451d5be1a50 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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_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_range(begin, end) => { print_expr(s, begin); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 410108bb8ce..ffe97197f6f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -237,7 +237,8 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) { pat_tup(elts) => for elts.each |elt| { 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) => { visit_path(path, e, v); do option::iter(inner) |subpat| { v.visit_pat(subpat, e, v)}; diff --git a/src/rustc/middle/check_alt.rs b/src/rustc/middle/check_alt.rs index 364cd4890ab..b4a5db2baa4 100644 --- a/src/rustc/middle/check_alt.rs +++ b/src/rustc/middle/check_alt.rs @@ -235,7 +235,7 @@ fn pat_ctor_id(tcx: ty::ctxt, p: @pat) -> Option<ctor> { pat_range(lo, 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(*) => { 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> { match ty::get(left_ty).struct { - ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_tup(_) | ty::ty_rec(_) | - ty::ty_class(*) => { + ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) | + ty::ty_rec(_) | ty::ty_class(*) => { for m.each |r| { 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 { ty::ty_tup(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, _) => { let id = match ctor { variant(id) => id, _ => 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))) } 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) => { let e_v = eval_const_expr(tcx, expr); let match_ = match ctor_id { @@ -440,7 +441,8 @@ fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool { } 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) } pat_wild | pat_ident(_, _, None) => { false } diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs index 7440d37ae5d..75868e6300f 100644 --- a/src/rustc/middle/mem_categorization.rs +++ b/src/rustc/middle/mem_categorization.rs @@ -898,8 +898,9 @@ impl &mem_categorization_ctxt { } } - ast::pat_box(subpat) | ast::pat_uniq(subpat) => { - // @p1, ~p1 + ast::pat_box(subpat) | ast::pat_uniq(subpat) | + ast::pat_region(subpat) => { + // @p1, ~p1, &p1 match self.cat_deref(subpat, cmt, 0u, true) { Some(subcmt) => { self.cat_pattern(subcmt, subpat, op); diff --git a/src/rustc/middle/trans/alt.rs b/src/rustc/middle/trans/alt.rs index fb7c8fae337..e09f9860b58 100644 --- a/src/rustc/middle/trans/alt.rs +++ b/src/rustc/middle/trans/alt.rs @@ -914,12 +914,8 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef, bcx = bind_irrefutable_pat(bcx, elem, fldptr, make_copy); } } - ast::pat_box(inner) => { - let llbox = Load(bcx, val); - let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); - bcx = bind_irrefutable_pat(bcx, inner, unboxed, true); - } - ast::pat_uniq(inner) => { + ast::pat_box(inner) | ast::pat_uniq(inner) | + ast::pat_region(inner) => { let llbox = Load(bcx, val); let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); bcx = bind_irrefutable_pat(bcx, inner, unboxed, true); diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs index 0282a9d78c4..2d49714d7d2 100644 --- a/src/rustc/middle/typeck/check/alt.rs +++ b/src/rustc/middle/typeck/check/alt.rs @@ -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"); + } + } + } + } } diff --git a/src/test/run-pass/borrowed-ptr-pattern-2.rs b/src/test/run-pass/borrowed-ptr-pattern-2.rs new file mode 100644 index 00000000000..8e31bc38e32 --- /dev/null +++ b/src/test/run-pass/borrowed-ptr-pattern-2.rs @@ -0,0 +1,10 @@ +fn foo<T>(s: &str) { + match s { + &"kitty" => fail ~"cat", + _ => () + } +} + +fn main() { + +} \ No newline at end of file diff --git a/src/test/run-pass/borrowed-ptr-pattern-3.rs b/src/test/run-pass/borrowed-ptr-pattern-3.rs new file mode 100644 index 00000000000..844e36ccf3b --- /dev/null +++ b/src/test/run-pass/borrowed-ptr-pattern-3.rs @@ -0,0 +1,10 @@ +fn foo<T>(s: &r/uint) { + match s { + &3 => fail ~"oh", + _ => () + } +} + +fn main() { + +} \ No newline at end of file diff --git a/src/test/run-pass/borrowed-ptr-pattern.rs b/src/test/run-pass/borrowed-ptr-pattern.rs new file mode 100644 index 00000000000..afe1f34fac4 --- /dev/null +++ b/src/test/run-pass/borrowed-ptr-pattern.rs @@ -0,0 +1,9 @@ +fn foo<T>(x: &T) { + match x { + &a => fail #fmt("%?", a) + } +} + +fn main() { + +} \ No newline at end of file |
