From b414db041be115d877e5b17bc86ea019420b672c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 31 Jul 2012 19:25:24 -0700 Subject: rustc: Parse by-reference pattern bindings with the "ref" keyword --- src/rustc/middle/borrowck/gather_loans.rs | 6 +++-- src/rustc/middle/check_alt.rs | 42 ++++++++++++++++--------------- src/rustc/middle/pat_util.rs | 4 +-- src/rustc/middle/region.rs | 2 +- src/rustc/middle/resolve3.rs | 30 +++++++++++----------- src/rustc/middle/trans/alt.rs | 28 +++++++++++++-------- src/rustc/middle/trans/base.rs | 2 +- src/rustc/middle/trans/debuginfo.rs | 2 +- src/rustc/middle/typeck/check.rs | 6 ++--- src/rustc/middle/typeck/check/alt.rs | 4 +-- src/rustc/middle/typeck/check/regionck.rs | 2 +- 11 files changed, 70 insertions(+), 58 deletions(-) (limited to 'src/rustc') diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs index 4b9015eec67..f08a06f3419 100644 --- a/src/rustc/middle/borrowck/gather_loans.rs +++ b/src/rustc/middle/borrowck/gather_loans.rs @@ -473,11 +473,13 @@ impl methods for gather_loan_ctxt { } } - ast::pat_ident(_, none) if self.pat_is_variant(pat) { + ast::pat_ident(_, _, none) if self.pat_is_variant(pat) { // nullary variant debug!{"nullary variant"}; } - ast::pat_ident(id, o_pat) { + ast::pat_ident(_, id, o_pat) { + // XXX: Needs to take by-ref/by-val into account. + // x or x @ p --- `x` must remain valid for the scope of the alt debug!{"defines identifier %s", pprust::path_to_str(id)}; diff --git a/src/rustc/middle/check_alt.rs b/src/rustc/middle/check_alt.rs index 4d62f2818ee..4093c0fcc6e 100644 --- a/src/rustc/middle/check_alt.rs +++ b/src/rustc/middle/check_alt.rs @@ -71,8 +71,8 @@ fn check_arms(tcx: ty::ctxt, arms: ~[arm]) { fn raw_pat(p: @pat) -> @pat { alt p.node { - pat_ident(_, some(s)) { raw_pat(s) } - _ { p } + pat_ident(_, _, some(s)) => { raw_pat(s) } + _ => { p } } } @@ -199,32 +199,34 @@ fn is_useful_specialized(tcx: ty::ctxt, m: matrix, v: ~[@pat], ctor: ctor, fn pat_ctor_id(tcx: ty::ctxt, p: @pat) -> option { let pat = raw_pat(p); alt pat.node { - pat_wild { none } - pat_ident(_, _) | pat_enum(_, _) { + pat_wild => { none } + pat_ident(_, _, _) | pat_enum(_, _) => { alt tcx.def_map.find(pat.id) { some(def_variant(_, id)) { some(variant(id)) } _ { none } } } - pat_lit(expr) { some(val(eval_const_expr(tcx, expr))) } - pat_range(lo, hi) { + pat_lit(expr) => { some(val(eval_const_expr(tcx, expr))) } + pat_range(lo, hi) => { some(range(eval_const_expr(tcx, lo), eval_const_expr(tcx, hi))) } - pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) { some(single) } + pat_box(_) | pat_uniq(_) | pat_rec(_, _) | pat_tup(_) => { + some(single) + } } } fn is_wild(tcx: ty::ctxt, p: @pat) -> bool { let pat = raw_pat(p); alt pat.node { - pat_wild { true } - pat_ident(_, _) { + pat_wild => { true } + pat_ident(_, _, _) => { alt tcx.def_map.find(pat.id) { - some(def_variant(_, _)) { false } - _ { true } + some(def_variant(_, _)) => { false } + _ => { true } } } - _ { false } + _ => { false } } } @@ -296,7 +298,7 @@ fn specialize(tcx: ty::ctxt, r: ~[@pat], ctor_id: ctor, arity: uint, alt r0.node { pat_wild { some(vec::append(vec::from_elem(arity, wild()), vec::tail(r))) } - pat_ident(_, _) { + pat_ident(_, _, _) { alt tcx.def_map.find(r0.id) { some(def_variant(_, id)) { if variant(id) == ctor_id { some(vec::tail(r)) } @@ -377,26 +379,26 @@ fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool { } alt pat.node { - pat_box(sub) | pat_uniq(sub) | pat_ident(_, some(sub)) { + pat_box(sub) | pat_uniq(sub) | pat_ident(_, _, some(sub)) => { is_refutable(tcx, sub) } - pat_wild | pat_ident(_, none) { false } - pat_lit(_) | pat_range(_, _) { true } - pat_rec(fields, _) { + pat_wild | pat_ident(_, _, none) => { false } + pat_lit(_) | pat_range(_, _) => { true } + pat_rec(fields, _) => { for fields.each |it| { if is_refutable(tcx, it.pat) { ret true; } } false } - pat_tup(elts) { + pat_tup(elts) => { for elts.each |elt| { if is_refutable(tcx, elt) { ret true; } } false } - pat_enum(_, some(args)) { + pat_enum(_, some(args)) => { for args.each |p| { if is_refutable(tcx, p) { ret true; } }; false } - pat_enum(_,_) { false } + pat_enum(_,_) => { false } } } diff --git a/src/rustc/middle/pat_util.rs b/src/rustc/middle/pat_util.rs index 4056dc137d7..8415b5e1a32 100644 --- a/src/rustc/middle/pat_util.rs +++ b/src/rustc/middle/pat_util.rs @@ -24,7 +24,7 @@ fn pat_id_map(dm: resolve3::DefMap, pat: @pat) -> pat_id_map { fn pat_is_variant(dm: resolve3::DefMap, pat: @pat) -> bool { alt pat.node { pat_enum(_, _) { true } - pat_ident(_, none) { + pat_ident(_, _, none) { alt dm.find(pat.id) { some(def_variant(_, _)) { true } _ { false } @@ -38,7 +38,7 @@ fn pat_bindings(dm: resolve3::DefMap, pat: @pat, it: fn(node_id, span, @path)) { do walk_pat(pat) |p| { alt p.node { - pat_ident(pth, _) if !pat_is_variant(dm, p) { + pat_ident(_, pth, _) if !pat_is_variant(dm, p) { it(p.id, p.span, pth); } _ {} diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index e6b2209b44a..809fd1c6fd6 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -208,7 +208,7 @@ fn resolve_arm(arm: ast::arm, cx: ctxt, visitor: visit::vt) { fn resolve_pat(pat: @ast::pat, cx: ctxt, visitor: visit::vt) { alt pat.node { - ast::pat_ident(path, _) { + ast::pat_ident(_, path, _) { let defn_opt = cx.def_map.find(pat.id); alt defn_opt { some(ast::def_variant(_,_)) { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index b4237d3e841..f66e3925fb0 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -5,11 +5,11 @@ import metadata::cstore::find_use_stmt_cnum; import metadata::decoder::{def_like, dl_def, dl_field, dl_impl}; import middle::lang_items::LanguageItems; import middle::lint::{deny, allow, forbid, level, unused_imports, warn}; -import syntax::ast::{_mod, add, arm, bitand, bitor, bitxor, blk, bound_const}; -import syntax::ast::{bound_copy, bound_owned, bound_send, bound_trait}; -import syntax::ast::{capture_clause, class_ctor, class_dtor, class_member}; -import syntax::ast::{class_method, crate, crate_num, decl_item, def, def_arg}; -import syntax::ast::{def_binding, def_class, def_const, def_fn}; +import syntax::ast::{_mod, add, arm, bind_by_value, bitand, bitor, bitxor}; +import syntax::ast::{blk, bound_const, bound_copy, bound_owned, bound_send}; +import syntax::ast::{bound_trait, capture_clause, class_ctor, class_dtor}; +import syntax::ast::{class_member, class_method, crate, crate_num, decl_item}; +import syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn}; import syntax::ast::{def_foreign_mod, def_id, def_local, def_mod}; import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param, def_typaram_binder}; @@ -3734,8 +3734,8 @@ class Resolver { let pat_id = pattern.id; do walk_pat(pattern) |pattern| { alt pattern.node { - pat_ident(path, _) - if !path.global && path.idents.len() == 1u { + pat_ident(_, path, _) + if !path.global && path.idents.len() == 1u => { // The meaning of pat_ident with no type parameters // depends on whether an enum variant with that name is in @@ -3748,14 +3748,14 @@ class Resolver { let atom = (*self.atom_table).intern(path.idents[0]); alt self.resolve_enum_variant_or_const(atom) { - FoundEnumVariant(def) if mode == RefutableMode { + FoundEnumVariant(def) if mode == RefutableMode => { debug!{"(resolving pattern) resolving `%s` to \ enum variant", *path.idents[0]}; self.record_def(pattern.id, def); } - FoundEnumVariant(_) { + FoundEnumVariant(_) => { self.session.span_err(pattern.span, fmt!{"declaration of `%s` \ shadows an enum \ @@ -3764,13 +3764,13 @@ class Resolver { atom_to_str (atom)}); } - FoundConst { + FoundConst => { self.session.span_err(pattern.span, ~"pattern variable \ conflicts with a constant \ in scope"); } - EnumVariantOrConstNotFound { + EnumVariantOrConstNotFound => { debug!{"(resolving pattern) binding `%s`", *path.idents[0]}; @@ -3836,7 +3836,7 @@ class Resolver { } } - pat_ident(path, _) | pat_enum(path, _) { + pat_ident(_, path, _) | pat_enum(path, _) => { // These two must be enum variants. alt self.resolve_path(path, ValueNS, false, visitor) { some(def @ def_variant(*)) { @@ -3860,16 +3860,16 @@ class Resolver { } } - pat_lit(expr) { + pat_lit(expr) => { self.resolve_expr(expr, visitor); } - pat_range(first_expr, last_expr) { + pat_range(first_expr, last_expr) => { self.resolve_expr(first_expr, visitor); self.resolve_expr(last_expr, visitor); } - _ { + _ => { // Nothing to do. } } diff --git a/src/rustc/middle/trans/alt.rs b/src/rustc/middle/trans/alt.rs index ef957e1c75a..b25aa26066f 100644 --- a/src/rustc/middle/trans/alt.rs +++ b/src/rustc/middle/trans/alt.rs @@ -79,7 +79,12 @@ fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> opt { core::unreachable(); } -type bind_map = ~[{ident: ast::ident, val: ValueRef}]; +type bind_map = ~[{ + ident: ast::ident, + val: ValueRef, + mode: ast::binding_mode +}]; + fn assoc(key: ast::ident, list: bind_map) -> option { for vec::each(list) |elt| { if str::eq(*elt.ident, *key) { ret some(elt.val); } @@ -98,7 +103,7 @@ type match_ = ~[match_branch]; fn has_nested_bindings(m: match_, col: uint) -> bool { for vec::each(m) |br| { alt br.pats[col].node { - ast::pat_ident(_, some(_)) { ret true; } + ast::pat_ident(_, _, some(_)) { ret true; } _ {} } } @@ -109,7 +114,7 @@ fn expand_nested_bindings(m: match_, col: uint, val: ValueRef) -> match_ { let mut result = ~[]; for vec::each(m) |br| { alt br.pats[col].node { - ast::pat_ident(name, some(inner)) { + ast::pat_ident(mode, name, some(inner)) { let pats = vec::append( vec::slice(br.pats, 0u, col), vec::append(~[inner], @@ -118,7 +123,8 @@ fn expand_nested_bindings(m: match_, col: uint, val: ValueRef) -> match_ { @{pats: pats, bound: vec::append( br.bound, ~[{ident: path_to_ident(name), - val: val}]) + val: val, + mode: mode}]) with *br}); } _ { vec::push(result, br); } @@ -140,9 +146,11 @@ fn enter_match(dm: DefMap, m: match_, col: uint, val: ValueRef, vec::view(br.pats, col + 1u, br.pats.len())); let self = br.pats[col]; let bound = alt self.node { - ast::pat_ident(name, none) if !pat_is_variant(dm, self) { + ast::pat_ident(mode, name, none) if !pat_is_variant(dm, self) { vec::append(br.bound, - ~[{ident: path_to_ident(name), val: val}]) + ~[{ident: path_to_ident(name), + val: val, + mode: mode}]) } _ { br.bound } }; @@ -158,7 +166,7 @@ fn enter_default(dm: DefMap, m: match_, col: uint, val: ValueRef) -> match_ { do enter_match(dm, m, col, val) |p| { alt p.node { ast::pat_wild | ast::pat_rec(_, _) | ast::pat_tup(_) { some(~[]) } - ast::pat_ident(_, none) if !pat_is_variant(dm, p) { + ast::pat_ident(_, _, none) if !pat_is_variant(dm, p) { some(~[]) } _ { none } @@ -177,7 +185,7 @@ fn enter_opt(tcx: ty::ctxt, m: match_, opt: opt, col: uint, vec::from_elem(variant_size, dummy))) } else { none } } - ast::pat_ident(_, none) if pat_is_variant(tcx.def_map, p) { + ast::pat_ident(_, _, none) if pat_is_variant(tcx.def_map, p) { if opt_eq(tcx, variant_opt(tcx, p.id), opt) { some(~[]) } else { none } } @@ -359,7 +367,7 @@ fn pick_col(m: match_) -> uint { fn score(p: @ast::pat) -> uint { alt p.node { ast::pat_lit(_) | ast::pat_enum(_, _) | ast::pat_range(_, _) { 1u } - ast::pat_ident(_, some(p)) { score(p) } + ast::pat_ident(_, _, some(p)) { score(p) } _ { 0u } } } @@ -725,7 +733,7 @@ fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef, // Necessary since bind_irrefutable_pat is called outside trans_alt alt pat.node { - ast::pat_ident(_,inner) { + ast::pat_ident(_, _,inner) { if pat_is_variant(bcx.tcx().def_map, pat) { ret bcx; } if make_copy { let ty = node_id_type(bcx, pat.id); diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 5960b7657f4..ef92891418a 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -4380,7 +4380,7 @@ fn alloc_local(cx: block, local: @ast::local) -> block { let _icx = cx.insn_ctxt(~"alloc_local"); let t = node_id_type(cx, local.node.id); let simple_name = alt local.node.pat.node { - ast::pat_ident(pth, none) { some(path_to_ident(pth)) } + ast::pat_ident(_, pth, none) { some(path_to_ident(pth)) } _ { none } }; let val = alloc_ty(cx, t); diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index 3197dc00884..98e7129abba 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -646,7 +646,7 @@ fn create_local_var(bcx: block, local: @ast::local) } let name = alt local.node.pat.node { - ast::pat_ident(pth, _) { ast_util::path_to_ident(pth) } + ast::pat_ident(_, pth, _) { ast_util::path_to_ident(pth) } // FIXME this should be handled (#2533) _ { fail ~"no single variable name for local"; } }; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index db9084cbad1..d8dd6bf0542 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -320,14 +320,14 @@ fn check_fn(ccx: @crate_ctxt, // Add pattern bindings. let visit_pat = fn@(p: @ast::pat, &&e: (), v: visit::vt<()>) { alt p.node { - ast::pat_ident(path, _) - if !pat_util::pat_is_variant(fcx.ccx.tcx.def_map, p) { + ast::pat_ident(_, path, _) + if !pat_util::pat_is_variant(fcx.ccx.tcx.def_map, p) => { assign(p.id, none); debug!{"Pattern binding %s is assigned to %s", *path.idents[0], fcx.locals.get(p.id).to_str()}; } - _ {} + _ => {} } visit::visit_pat(p, e, v); }; diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs index db35398a49c..5cc8a953722 100644 --- a/src/rustc/middle/typeck/check/alt.rs +++ b/src/rustc/middle/typeck/check/alt.rs @@ -155,7 +155,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { } fcx.write_ty(pat.id, b_ty); } - ast::pat_ident(name, sub) if !pat_is_variant(tcx.def_map, pat) { + ast::pat_ident(_, name, sub) if !pat_is_variant(tcx.def_map, pat) { let vid = lookup_local(fcx, pat.span, pat.id); let mut typ = ty::mk_var(tcx, vid); demand::suptype(fcx, pat.span, expected, typ); @@ -171,7 +171,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { _ {} } } - ast::pat_ident(path, c) { + ast::pat_ident(_, path, c) { check_pat_variant(pcx, pat, path, some(~[]), expected); } ast::pat_enum(path, subpats) { diff --git a/src/rustc/middle/typeck/check/regionck.rs b/src/rustc/middle/typeck/check/regionck.rs index 06307c1c70c..50e2d5db973 100644 --- a/src/rustc/middle/typeck/check/regionck.rs +++ b/src/rustc/middle/typeck/check/regionck.rs @@ -105,7 +105,7 @@ fn visit_local(l: @ast::local, &&rcx: @rcx, v: rvt) { fn visit_pat(p: @ast::pat, &&rcx: @rcx, v: rvt) { let fcx = rcx.fcx; alt p.node { - ast::pat_ident(path, _) + ast::pat_ident(_, path, _) if !pat_util::pat_is_variant(fcx.ccx.tcx.def_map, p) { debug!{"visit_pat binding=%s", *path.idents[0]}; visit_node(p.id, p.span, rcx); -- cgit 1.4.1-3-g733a5