diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2013-03-15 15:24:24 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2013-04-30 06:59:32 -0400 |
| commit | a896440ca1b93cc5dc6edd827ea2ae89602bfa9e (patch) | |
| tree | c6945d51bf84faeb9be6ac32247c8ffa2cd39226 /src/libsyntax | |
| parent | b5a7e8b35322869b1cf51bd1b35a86e9e721da54 (diff) | |
| download | rust-a896440ca1b93cc5dc6edd827ea2ae89602bfa9e.tar.gz rust-a896440ca1b93cc5dc6edd827ea2ae89602bfa9e.zip | |
new borrow checker (mass squash)
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast_map.rs | 69 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/codemap.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 108 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/liveness.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/proto.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/print/pp.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/util/interner.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
11 files changed, 141 insertions, 111 deletions
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index f9828ad2b9e..eb131b17c2f 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -19,6 +19,7 @@ use diagnostic::span_handler; use parse::token::ident_interner; use print::pprust; use visit; +use syntax::parse::token::special_idents; use core::hashmap::HashMap; @@ -89,14 +90,13 @@ pub enum ast_node { node_variant(variant, @item, @path), node_expr(@expr), node_stmt(@stmt), - // Locals are numbered, because the alias analysis needs to know in which - // order they are introduced. - node_arg(arg, uint), - node_local(uint), + node_arg, + node_local(ident), // Destructor for a struct node_dtor(Generics, @struct_dtor, def_id, @path), node_block(blk), node_struct_ctor(@struct_def, @item, @path), + node_callee_scope(@expr) } pub type map = @mut HashMap<node_id, ast_node>; @@ -104,7 +104,6 @@ pub type map = @mut HashMap<node_id, ast_node>; pub struct Ctx { map: map, path: path, - local_id: uint, diag: @span_handler, } @@ -120,9 +119,8 @@ pub fn mk_ast_map_visitor() -> vt { visit_expr: map_expr, visit_stmt: map_stmt, visit_fn: map_fn, - visit_local: map_local, - visit_arm: map_arm, visit_block: map_block, + visit_pat: map_pat, .. *visit::default_visitor() }); } @@ -131,7 +129,6 @@ pub fn map_crate(diag: @span_handler, c: @crate) -> map { let cx = @mut Ctx { map: @mut HashMap::new(), path: ~[], - local_id: 0u, diag: diag, }; visit::visit_crate(c, cx, mk_ast_map_visitor()); @@ -154,7 +151,6 @@ pub fn map_decoded_item(diag: @span_handler, let cx = @mut Ctx { map: map, path: copy path, - local_id: 0, diag: diag, }; let v = mk_ast_map_visitor(); @@ -189,9 +185,7 @@ pub fn map_fn( v: visit::vt<@mut Ctx> ) { for decl.inputs.each |a| { - cx.map.insert(a.id, - node_arg(/* FIXME (#2543) */ copy *a, cx.local_id)); - cx.local_id += 1u; + cx.map.insert(a.id, node_arg); } match *fk { visit::fk_dtor(generics, ref attrs, self_id, parent_id) => { @@ -222,33 +216,22 @@ pub fn map_block(b: &blk, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { visit::visit_block(b, cx, v); } -pub fn number_pat(cx: @mut Ctx, pat: @pat) { - do ast_util::walk_pat(pat) |p| { - match p.node { - pat_ident(*) => { - cx.map.insert(p.id, node_local(cx.local_id)); - cx.local_id += 1u; - } - _ => () +pub fn map_pat(pat: @pat, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { + match pat.node { + pat_ident(_, path, _) => { + // Note: this is at least *potentially* a pattern... + cx.map.insert(pat.id, node_local(ast_util::path_to_ident(path))); } - }; -} - -pub fn map_local(loc: @local, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { - number_pat(cx, loc.node.pat); - visit::visit_local(loc, cx, v); -} + _ => () + } -pub fn map_arm(arm: &arm, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { - number_pat(cx, arm.pats[0]); - visit::visit_arm(arm, cx, v); + visit::visit_pat(pat, cx, v); } pub fn map_method(impl_did: def_id, impl_path: @path, m: @method, cx: @mut Ctx) { cx.map.insert(m.id, node_method(m, impl_did, impl_path)); - cx.map.insert(m.self_id, node_local(cx.local_id)); - cx.local_id += 1u; + cx.map.insert(m.self_id, node_local(special_idents::self_)); } pub fn map_item(i: @item, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { @@ -317,6 +300,7 @@ pub fn map_item(i: @item, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { } _ => () } + match i.node { item_mod(_) | item_foreign_mod(_) => { cx.path.push(path_mod(i.ident)); @@ -352,6 +336,18 @@ pub fn map_struct_def( pub fn map_expr(ex: @expr, cx: @mut Ctx, v: visit::vt<@mut Ctx>) { cx.map.insert(ex.id, node_expr(ex)); + match ex.node { + // Expressions which are or might be calls: + ast::expr_call(*) | + ast::expr_method_call(*) | + ast::expr_index(*) | + ast::expr_binary(*) | + ast::expr_assign_op(*) | + ast::expr_unary(*) => { + cx.map.insert(ex.callee_id, node_callee_scope(ex)); + } + _ => {} + } visit::visit_expr(ex, cx, v); } @@ -401,15 +397,18 @@ pub fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { Some(&node_expr(expr)) => { fmt!("expr %s (id=%?)", pprust::expr_to_str(expr, itr), id) } + Some(&node_callee_scope(expr)) => { + fmt!("callee_scope %s (id=%?)", pprust::expr_to_str(expr, itr), id) + } Some(&node_stmt(stmt)) => { fmt!("stmt %s (id=%?)", pprust::stmt_to_str(stmt, itr), id) } - Some(&node_arg(_, _)) => { // add more info here + Some(&node_arg) => { fmt!("arg (id=%?)", id) } - Some(&node_local(_)) => { // add more info here - fmt!("local (id=%?)", id) + Some(&node_local(ident)) => { + fmt!("local (id=%?, name=%s)", id, *itr.get(ident)) } Some(&node_dtor(*)) => { // add more info here fmt!("node_dtor (id=%?)", id) diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 148b713a4f5..7e24adabdb0 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -388,8 +388,20 @@ pub struct id_range { max: node_id, } -pub fn empty(range: id_range) -> bool { - range.min >= range.max +pub impl id_range { + fn max() -> id_range { + id_range {min: int::max_value, + max: int::min_value} + } + + fn empty(&self) -> bool { + self.min >= self.max + } + + fn add(&mut self, id: node_id) { + self.min = int::min(self.min, id); + self.max = int::max(self.max, id + 1); + } } pub fn id_visitor(vfn: @fn(node_id)) -> visit::vt<()> { @@ -493,13 +505,11 @@ pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(node_id)) { } pub fn compute_id_range(visit_ids_fn: &fn(@fn(node_id))) -> id_range { - let min = @mut int::max_value; - let max = @mut int::min_value; + let result = @mut id_range::max(); do visit_ids_fn |id| { - *min = int::min(*min, id); - *max = int::max(*max, id + 1); + result.add(id); } - id_range { min: *min, max: *max } + *result } pub fn compute_id_range_for_inlined_item(item: &inlined_item) -> id_range { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 1194506a887..7facc181eff 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -246,7 +246,7 @@ pub impl FileMap { // the new charpos must be > the last one (or it's the first one). let lines = &mut *self.lines; assert!((lines.len() == 0) || (lines[lines.len() - 1] < pos)); - self.lines.push(pos); + lines.push(pos); } // get a line from the list of pre-computed line-beginnings @@ -308,7 +308,7 @@ pub impl CodeMap { multibyte_chars: @mut ~[], }; - self.files.push(filemap); + files.push(filemap); return filemap; } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 5bad9ecae3e..7d058f22e4c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -210,29 +210,29 @@ pub fn syntax_expander_table() -> SyntaxEnv { // when a macro expansion occurs, the resulting nodes have the backtrace() // -> expn_info of their expansion context stored into their span. pub trait ext_ctxt { - fn codemap(@mut self) -> @CodeMap; - fn parse_sess(@mut self) -> @mut parse::ParseSess; - fn cfg(@mut self) -> ast::crate_cfg; - fn call_site(@mut self) -> span; - fn print_backtrace(@mut self); - fn backtrace(@mut self) -> Option<@ExpnInfo>; - fn mod_push(@mut self, mod_name: ast::ident); - fn mod_pop(@mut self); - fn mod_path(@mut self) -> ~[ast::ident]; - fn bt_push(@mut self, ei: codemap::ExpnInfo); - fn bt_pop(@mut self); - fn span_fatal(@mut self, sp: span, msg: &str) -> !; - fn span_err(@mut self, sp: span, msg: &str); - fn span_warn(@mut self, sp: span, msg: &str); - fn span_unimpl(@mut self, sp: span, msg: &str) -> !; - fn span_bug(@mut self, sp: span, msg: &str) -> !; - fn bug(@mut self, msg: &str) -> !; - fn next_id(@mut self) -> ast::node_id; - fn trace_macros(@mut self) -> bool; - fn set_trace_macros(@mut self, x: bool); + fn codemap(&self) -> @CodeMap; + fn parse_sess(&self) -> @mut parse::ParseSess; + fn cfg(&self) -> ast::crate_cfg; + fn call_site(&self) -> span; + fn print_backtrace(&self); + fn backtrace(&self) -> Option<@ExpnInfo>; + fn mod_push(&self, mod_name: ast::ident); + fn mod_pop(&self); + fn mod_path(&self) -> ~[ast::ident]; + fn bt_push(&self, ei: codemap::ExpnInfo); + fn bt_pop(&self); + fn span_fatal(&self, sp: span, msg: &str) -> !; + fn span_err(&self, sp: span, msg: &str); + fn span_warn(&self, sp: span, msg: &str); + fn span_unimpl(&self, sp: span, msg: &str) -> !; + fn span_bug(&self, sp: span, msg: &str) -> !; + fn bug(&self, msg: &str) -> !; + fn next_id(&self) -> ast::node_id; + fn trace_macros(&self) -> bool; + fn set_trace_macros(&self, x: bool); /* for unhygienic identifier transformation */ - fn str_of(@mut self, id: ast::ident) -> ~str; - fn ident_of(@mut self, st: ~str) -> ast::ident; + fn str_of(&self, id: ast::ident) -> ~str; + fn ident_of(&self, st: ~str) -> ast::ident; } pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) @@ -241,25 +241,31 @@ pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg, backtrace: @mut Option<@ExpnInfo>, - mod_path: ~[ast::ident], - trace_mac: bool + + // These two @mut's should really not be here, + // but the self types for CtxtRepr are all wrong + // and there are bugs in the code for object + // types that make this hard to get right at the + // moment. - nmatsakis + mod_path: @mut ~[ast::ident], + trace_mac: @mut bool } impl ext_ctxt for CtxtRepr { - fn codemap(@mut self) -> @CodeMap { self.parse_sess.cm } - fn parse_sess(@mut self) -> @mut parse::ParseSess { self.parse_sess } - fn cfg(@mut self) -> ast::crate_cfg { copy self.cfg } - fn call_site(@mut self) -> span { + fn codemap(&self) -> @CodeMap { self.parse_sess.cm } + fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess } + fn cfg(&self) -> ast::crate_cfg { copy self.cfg } + fn call_site(&self) -> span { match *self.backtrace { Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs, None => self.bug(~"missing top span") } } - fn print_backtrace(@mut self) { } - fn backtrace(@mut self) -> Option<@ExpnInfo> { *self.backtrace } - fn mod_push(@mut self, i: ast::ident) { self.mod_path.push(i); } - fn mod_pop(@mut self) { self.mod_path.pop(); } - fn mod_path(@mut self) -> ~[ast::ident] { copy self.mod_path } - fn bt_push(@mut self, ei: codemap::ExpnInfo) { + fn print_backtrace(&self) { } + fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace } + fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); } + fn mod_pop(&self) { self.mod_path.pop(); } + fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path } + fn bt_push(&self, ei: codemap::ExpnInfo) { match ei { ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => { *self.backtrace = @@ -270,7 +276,7 @@ pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) } } } - fn bt_pop(@mut self) { + fn bt_pop(&self) { match *self.backtrace { Some(@ExpandedFrom(CallInfo { call_site: span {expn_info: prev, _}, _ @@ -280,52 +286,52 @@ pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) _ => self.bug(~"tried to pop without a push") } } - fn span_fatal(@mut self, sp: span, msg: &str) -> ! { + fn span_fatal(&self, sp: span, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.span_fatal(sp, msg); } - fn span_err(@mut self, sp: span, msg: &str) { + fn span_err(&self, sp: span, msg: &str) { self.print_backtrace(); self.parse_sess.span_diagnostic.span_err(sp, msg); } - fn span_warn(@mut self, sp: span, msg: &str) { + fn span_warn(&self, sp: span, msg: &str) { self.print_backtrace(); self.parse_sess.span_diagnostic.span_warn(sp, msg); } - fn span_unimpl(@mut self, sp: span, msg: &str) -> ! { + fn span_unimpl(&self, sp: span, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.span_unimpl(sp, msg); } - fn span_bug(@mut self, sp: span, msg: &str) -> ! { + fn span_bug(&self, sp: span, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.span_bug(sp, msg); } - fn bug(@mut self, msg: &str) -> ! { + fn bug(&self, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.handler().bug(msg); } - fn next_id(@mut self) -> ast::node_id { + fn next_id(&self) -> ast::node_id { return parse::next_node_id(self.parse_sess); } - fn trace_macros(@mut self) -> bool { - self.trace_mac + fn trace_macros(&self) -> bool { + *self.trace_mac } - fn set_trace_macros(@mut self, x: bool) { - self.trace_mac = x + fn set_trace_macros(&self, x: bool) { + *self.trace_mac = x } - fn str_of(@mut self, id: ast::ident) -> ~str { + fn str_of(&self, id: ast::ident) -> ~str { copy *self.parse_sess.interner.get(id) } - fn ident_of(@mut self, st: ~str) -> ast::ident { + fn ident_of(&self, st: ~str) -> ast::ident { self.parse_sess.interner.intern(@/*bad*/ copy st) } } - let imp: @mut CtxtRepr = @mut CtxtRepr { + let imp: @CtxtRepr = @CtxtRepr { parse_sess: parse_sess, cfg: cfg, backtrace: @mut None, - mod_path: ~[], - trace_mac: false + mod_path: @mut ~[], + trace_mac: @mut false }; ((imp) as @ext_ctxt) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index fde5a259422..841f64e0b05 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -27,6 +27,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv, fld: @ast_fold, orig: @fn(&expr_, span, @ast_fold) -> (expr_, span)) -> (expr_, span) { + let mut cx = cx; match *e { // expr_mac should really be expr_ext or something; it's the // entry-point for all syntax extensions. @@ -112,6 +113,8 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv, fld: @ast_fold, orig: @fn(&ast::_mod, @ast_fold) -> ast::_mod) -> ast::_mod { + let mut cx = cx; + // Fold the contents first: let module_ = orig(module_, fld); diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index 4597dab89cb..7843db55789 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -38,11 +38,11 @@ updating the states using rule (2) until there are no changes. */ use ext::base::ext_ctxt; -use ext::pipes::proto::protocol; +use ext::pipes::proto::{protocol_}; use std::bitv::Bitv; -pub fn analyze(proto: protocol, _cx: @ext_ctxt) { +pub fn analyze(proto: &mut protocol_, _cx: @ext_ctxt) { debug!("initializing colive analysis"); let num_states = proto.num_states(); let mut colive = do (copy proto.states).map_to_vec |state| { diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 79072a2f577..ffb55ee50d9 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -138,26 +138,26 @@ pub struct protocol_ { pub impl protocol_ { /// Get a state. - fn get_state(&mut self, name: ~str) -> state { + fn get_state(&self, name: ~str) -> state { self.states.find(|i| i.name == name).get() } - fn get_state_by_id(&mut self, id: uint) -> state { self.states[id] } + fn get_state_by_id(&self, id: uint) -> state { self.states[id] } - fn has_state(&mut self, name: ~str) -> bool { + fn has_state(&self, name: ~str) -> bool { self.states.find(|i| i.name == name).is_some() } - fn filename(&mut self) -> ~str { + fn filename(&self) -> ~str { ~"proto://" + self.name } - fn num_states(&mut self) -> uint { + fn num_states(&self) -> uint { let states = &mut *self.states; states.len() } - fn has_ty_params(&mut self) -> bool { + fn has_ty_params(&self) -> bool { for self.states.each |s| { if s.generics.ty_params.len() > 0 { return true; @@ -165,7 +165,7 @@ pub impl protocol_ { } false } - fn is_bounded(&mut self) -> bool { + fn is_bounded(&self) -> bool { let bounded = self.bounded.get(); bounded } @@ -179,7 +179,7 @@ pub impl protocol_ { generics: ast::Generics) -> state { let messages = @mut ~[]; - let states = &*self.states; + let states = &mut *self.states; let state = @state_ { id: states.len(), @@ -192,7 +192,7 @@ pub impl protocol_ { proto: self }; - self.states.push(state); + states.push(state); state } } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index e2ad5becb12..c1acee8e2cd 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -491,9 +491,9 @@ pub impl Printer { } END => { debug!("print END -> pop END"); - let print_stack = &*self.print_stack; + let print_stack = &mut *self.print_stack; assert!((print_stack.len() != 0u)); - self.print_stack.pop(); + print_stack.pop(); } BREAK(b) => { let top = self.get_top(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d5645ada929..ff8259e8996 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -72,6 +72,12 @@ pub fn end(s: @ps) { } pub fn rust_printer(writer: @io::Writer, intr: @ident_interner) -> @ps { + return rust_printer_annotated(writer, intr, no_ann()); +} + +pub fn rust_printer_annotated(writer: @io::Writer, + intr: @ident_interner, + ann: pp_ann) -> @ps { return @ps { s: pp::mk_printer(writer, default_columns), cm: None::<@CodeMap>, @@ -83,7 +89,7 @@ pub fn rust_printer(writer: @io::Writer, intr: @ident_interner) -> @ps { cur_lit: 0 }, boxes: @mut ~[], - ann: no_ann() + ann: ann }; } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 9ab7d4bc443..e3a87277622 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -44,10 +44,10 @@ pub impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> { None => (), } - let vect = &*self.vect; + let vect = &mut *self.vect; let new_idx = vect.len(); self.map.insert(val, new_idx); - self.vect.push(val); + vect.push(val); new_idx } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 80df8fb91a5..a42f640a175 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -22,6 +22,12 @@ use opt_vec::OptVec; // children (potentially passing in different contexts to each), call // visit::visit_* to apply the default traversal algorithm (again, it can // override the context), or prevent deeper traversal by doing nothing. +// +// Note: it is an important invariant that the default visitor walks the body +// of a function in "execution order" (more concretely, reverse post-order +// with respect to the CFG implied by the AST), meaning that if AST node A may +// execute before AST node B, then A is visited first. The borrow checker in +// particular relies on this property. // Our typesystem doesn't do circular types, so the visitor record can not // hold functions that take visitors. A vt enum is used to break the cycle. |
