diff options
| author | bors <bors@rust-lang.org> | 2014-01-03 22:36:53 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-01-03 22:36:53 -0800 |
| commit | 3dd7c49faf5ae3a9158ab242a264c0f0eb99f657 (patch) | |
| tree | 0393c0b2e10c7579d86c222071bb9c64b0451b60 /src/libsyntax | |
| parent | 0ff6c12ce94993dae702d597a213eee6b969231a (diff) | |
| parent | 80921536343e87d2f7d7f19ad90d63f50b557e06 (diff) | |
| download | rust-3dd7c49faf5ae3a9158ab242a264c0f0eb99f657.tar.gz rust-3dd7c49faf5ae3a9158ab242a264c0f0eb99f657.zip | |
auto merge of #11251 : pcwalton/rust/remove-at-mut, r=pcwalton
r? @nikomatsakis for the borrow checker changes. Write guards are now eliminated.
Diffstat (limited to 'src/libsyntax')
25 files changed, 1261 insertions, 1073 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 51aa7cd4377..3523d63ef60 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -15,6 +15,7 @@ use abi::AbiSet; use opt_vec::OptVec; use parse::token::{interner_get, str_to_ident}; +use std::cell::RefCell; use std::hashmap::HashMap; use std::option::Option; use std::to_str::ToStr; @@ -88,9 +89,9 @@ pub type SyntaxContext = u32; // it should cut down on memory use *a lot*; applying a mark // to a tree containing 50 identifiers would otherwise generate pub struct SCTable { - table : ~[SyntaxContext_], - mark_memo : HashMap<(SyntaxContext,Mrk),SyntaxContext>, - rename_memo : HashMap<(SyntaxContext,Ident,Name),SyntaxContext> + table: RefCell<~[SyntaxContext_]>, + mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>, + rename_memo: RefCell<HashMap<(SyntaxContext,Ident,Name),SyntaxContext>>, } // NB: these must be placed in any SCTable... @@ -414,7 +415,6 @@ pub enum Vstore { pub enum ExprVstore { ExprVstoreUniq, // ~[1,2,3,4] ExprVstoreBox, // @[1,2,3,4] - ExprVstoreMutBox, // @mut [1,2,3,4] ExprVstoreSlice, // &[1,2,3,4] ExprVstoreMutSlice, // &mut [1,2,3,4] } @@ -443,7 +443,7 @@ pub enum BinOp { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum UnOp { - UnBox(Mutability), + UnBox, UnUniq, UnDeref, UnNot, @@ -874,7 +874,7 @@ pub struct TyBareFn { pub enum ty_ { ty_nil, ty_bot, /* bottom type */ - ty_box(mt), + ty_box(P<Ty>), ty_uniq(P<Ty>), ty_vec(P<Ty>), ty_fixed_length_vec(P<Ty>, @Expr), diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 504a51f80a8..8a5a1d2426c 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -23,6 +23,7 @@ use print::pprust; use visit::{Visitor, fn_kind}; use visit; +use std::cell::RefCell; use std::hashmap::HashMap; use std::vec; @@ -94,7 +95,7 @@ pub fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str { fn pretty_ty(ty: &Ty, itr: @ident_interner, out: &mut ~str) { let (prefix, subty) = match ty.node { ty_uniq(ty) => ("$UP$", &*ty), - ty_box(mt { ty, .. }) => ("$SP$", &*ty), + ty_box(ty) => ("$SP$", &*ty), ty_ptr(mt { ty, mutbl }) => (if mutbl == MutMutable {"$RPmut$"} else {"$RP$"}, &*ty), ty_rptr(_, mt { ty, mutbl }) => (if mutbl == MutMutable {"$BPmut$"} else {"$BP$"}, @@ -192,17 +193,17 @@ impl ast_node { } } -pub type map = @mut HashMap<NodeId, ast_node>; +pub type map = @RefCell<HashMap<NodeId, ast_node>>; pub struct Ctx { map: map, - path: path, - diag: @mut SpanHandler, + path: RefCell<path>, + diag: @SpanHandler, } impl Ctx { fn extend(&self, elt: path_elt) -> @path { - @vec::append(self.path.clone(), [elt]) + @vec::append(self.path.get(), [elt]) } fn map_method(&mut self, @@ -215,8 +216,10 @@ impl Ctx { } else { node_method(m, impl_did, impl_path) }; - self.map.insert(m.id, entry); - self.map.insert(m.self_id, node_local(special_idents::self_)); + + let mut map = self.map.borrow_mut(); + map.get().insert(m.id, entry); + map.get().insert(m.self_id, node_local(special_idents::self_)); } fn map_struct_def(&mut self, @@ -231,10 +234,11 @@ impl Ctx { Some(ctor_id) => { match parent_node { node_item(item, _) => { - self.map.insert(ctor_id, - node_struct_ctor(struct_def, - item, - p)); + let mut map = self.map.borrow_mut(); + map.get().insert(ctor_id, + node_struct_ctor(struct_def, + item, + p)); } _ => fail!("struct def parent wasn't an item") } @@ -243,13 +247,17 @@ impl Ctx { } fn map_expr(&mut self, ex: @Expr) { - self.map.insert(ex.id, node_expr(ex)); + { + let mut map = self.map.borrow_mut(); + map.get().insert(ex.id, node_expr(ex)); + } // Expressions which are or might be calls: { let r = ex.get_callee_id(); for callee_id in r.iter() { - self.map.insert(*callee_id, node_callee_scope(ex)); + let mut map = self.map.borrow_mut(); + map.get().insert(*callee_id, node_callee_scope(ex)); } } @@ -263,26 +271,40 @@ impl Ctx { sp: codemap::Span, id: NodeId) { for a in decl.inputs.iter() { - self.map.insert(a.id, node_arg(a.pat)); + let mut map = self.map.borrow_mut(); + map.get().insert(a.id, node_arg(a.pat)); } match *fk { - visit::fk_method(name, _, _) => { self.path.push(path_name(name)) } + visit::fk_method(name, _, _) => { + let mut path = self.path.borrow_mut(); + path.get().push(path_name(name)) + } _ => {} } visit::walk_fn(self, fk, decl, body, sp, id, ()); match *fk { - visit::fk_method(..) => { self.path.pop(); } + visit::fk_method(..) => { + let mut path = self.path.borrow_mut(); + path.get().pop(); + } _ => {} } } fn map_stmt(&mut self, stmt: @Stmt) { - self.map.insert(stmt_id(stmt), node_stmt(stmt)); + { + let mut map = self.map.borrow_mut(); + map.get().insert(stmt_id(stmt), node_stmt(stmt)); + } visit::walk_stmt(self, stmt, ()); } fn map_block(&mut self, b: P<Block>) { - self.map.insert(b.id, node_block(b)); + { + let mut map = self.map.borrow_mut(); + map.get().insert(b.id, node_block(b)); + } + visit::walk_block(self, b, ()); } @@ -290,8 +312,9 @@ impl Ctx { match pat.node { PatIdent(_, ref path, _) => { // Note: this is at least *potentially* a pattern... - self.map.insert(pat.id, - node_local(ast_util::path_to_ident(path))); + let mut map = self.map.borrow_mut(); + map.get().insert(pat.id, + node_local(ast_util::path_to_ident(path))); } _ => () } @@ -303,8 +326,11 @@ impl Ctx { impl Visitor<()> for Ctx { fn visit_item(&mut self, i: @item, _: ()) { // clone is FIXME #2543 - let item_path = @self.path.clone(); - self.map.insert(i.id, node_item(i, item_path)); + let item_path = @self.path.get(); + { + let mut map = self.map.borrow_mut(); + map.get().insert(i.id, node_item(i, item_path)); + } match i.node { item_impl(_, ref maybe_trait, ty, ref ms) => { // Right now the ident on impls is __extensions__ which isn't @@ -318,13 +344,15 @@ impl Visitor<()> for Ctx { self.map_method(impl_did, extended, *m, false) } - self.path.push(elt); + let mut path = self.path.borrow_mut(); + path.get().push(elt); } item_enum(ref enum_definition, _) => { for &v in enum_definition.variants.iter() { let elt = path_name(i.ident); - self.map.insert(v.node.id, - node_variant(v, i, self.extend(elt))); + let mut map = self.map.borrow_mut(); + map.get().insert(v.node.id, + node_variant(v, i, self.extend(elt))); } } item_foreign_mod(ref nm) => { @@ -336,16 +364,17 @@ impl Visitor<()> for Ctx { inherited => i.vis }; - self.map.insert(nitem.id, - node_foreign_item(*nitem, - nm.abis, - visibility, - // FIXME (#2543) + let mut map = self.map.borrow_mut(); + map.get().insert(nitem.id, + node_foreign_item(*nitem, + nm.abis, + visibility, + // FIXME (#2543) // Anonymous extern // mods go in the // parent scope. - @self.path.clone() - )); + @self.path.get() + )); } } item_struct(struct_def, _) => { @@ -355,7 +384,8 @@ impl Visitor<()> for Ctx { } item_trait(_, ref traits, ref methods) => { for p in traits.iter() { - self.map.insert(p.ref_id, node_item(i, item_path)); + let mut map = self.map.borrow_mut(); + map.get().insert(p.ref_id, node_item(i, item_path)); } for tm in methods.iter() { let ext = { self.extend(path_name(i.ident)) }; @@ -364,7 +394,8 @@ impl Visitor<()> for Ctx { required(ref m) => { let entry = node_trait_method(@(*tm).clone(), d_id, ext); - self.map.insert(m.id, entry); + let mut map = self.map.borrow_mut(); + map.get().insert(m.id, entry); } provided(m) => { self.map_method(d_id, ext, m, true); @@ -377,13 +408,19 @@ impl Visitor<()> for Ctx { match i.node { item_mod(_) | item_foreign_mod(_) => { - self.path.push(path_mod(i.ident)); + let mut path = self.path.borrow_mut(); + path.get().push(path_mod(i.ident)); } item_impl(..) => {} // this was guessed above. - _ => self.path.push(path_name(i.ident)) + _ => { + let mut path = self.path.borrow_mut(); + path.get().push(path_name(i.ident)) + } } visit::walk_item(self, i, ()); - self.path.pop(); + + let mut path = self.path.borrow_mut(); + path.get().pop(); } fn visit_pat(&mut self, pat: &Pat, _: ()) { @@ -418,29 +455,29 @@ impl Visitor<()> for Ctx { } } -pub fn map_crate(diag: @mut SpanHandler, c: &Crate) -> map { - let cx = @mut Ctx { - map: @mut HashMap::new(), - path: ~[], +pub fn map_crate(diag: @SpanHandler, c: &Crate) -> map { + let mut cx = Ctx { + map: @RefCell::new(HashMap::new()), + path: RefCell::new(~[]), diag: diag, }; - visit::walk_crate(cx, c, ()); + visit::walk_crate(&mut cx, c, ()); cx.map } // Used for items loaded from external crate that are being inlined into this // crate. The `path` should be the path to the item but should not include // the item itself. -pub fn map_decoded_item(diag: @mut SpanHandler, +pub fn map_decoded_item(diag: @SpanHandler, map: map, path: path, ii: &inlined_item) { // I believe it is ok for the local IDs of inlined items from other crates // to overlap with the local ids from this crate, so just generate the ids // starting from 0. - let cx = @mut Ctx { + let mut cx = Ctx { map: map, - path: path.clone(), + path: RefCell::new(path.clone()), diag: diag, }; @@ -450,10 +487,11 @@ pub fn map_decoded_item(diag: @mut SpanHandler, match *ii { ii_item(..) => {} // fallthrough ii_foreign(i) => { - cx.map.insert(i.id, node_foreign_item(i, - AbiSet::Intrinsic(), - i.vis, // Wrong but OK - @path)); + let mut map = cx.map.borrow_mut(); + map.get().insert(i.id, node_foreign_item(i, + AbiSet::Intrinsic(), + i.vis, // Wrong but OK + @path)); } ii_method(impl_did, is_provided, m) => { cx.map_method(impl_did, @path, m, is_provided); @@ -461,11 +499,12 @@ pub fn map_decoded_item(diag: @mut SpanHandler, } // visit the item / method contents and add those to the map: - ii.accept((), cx); + ii.accept((), &mut cx); } pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str { - match map.find(&id) { + let map = map.borrow(); + match map.get().find(&id) { None => { format!("unknown node (id={})", id) } @@ -529,7 +568,8 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str { pub fn node_item_query<Result>(items: map, id: NodeId, query: |@item| -> Result, error_msg: ~str) -> Result { - match items.find(&id) { + let items = items.borrow(); + match items.get().find(&id) { Some(&node_item(it, _)) => query(it), _ => fail!("{}", error_msg) } @@ -538,7 +578,8 @@ pub fn node_item_query<Result>(items: map, id: NodeId, query: |@item| -> Result, pub fn node_span(items: map, id: ast::NodeId) -> Span { - match items.find(&id) { + let items = items.borrow(); + match items.get().find(&id) { Some(&node_item(item, _)) => item.span, Some(&node_foreign_item(foreign_item, _, _, _)) => foreign_item.span, Some(&node_trait_method(@required(ref type_method), _, _)) => type_method.span, diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index f93eb6754ad..f99fed517b1 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -17,6 +17,7 @@ use parse::token; use visit::Visitor; use visit; +use std::cell::{Cell, RefCell}; use std::hashmap::HashMap; use std::u32; use std::local_data; @@ -136,13 +137,13 @@ pub fn is_shift_binop(b: BinOp) -> bool { } } -pub fn unop_to_str(op: UnOp) -> ~str { +pub fn unop_to_str(op: UnOp) -> &'static str { match op { - UnBox(mt) => if mt == MutMutable { ~"@mut " } else { ~"@" }, - UnUniq => ~"~", - UnDeref => ~"*", - UnNot => ~"!", - UnNeg => ~"-" + UnBox => "@", + UnUniq => "~", + UnDeref => "*", + UnNot => "!", + UnNeg => "-", } } @@ -601,21 +602,23 @@ pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &inlined_item, } struct IdRangeComputingVisitor { - result: @mut id_range, + result: Cell<id_range>, } impl IdVisitingOperation for IdRangeComputingVisitor { fn visit_id(&self, id: NodeId) { - self.result.add(id) + let mut id_range = self.result.get(); + id_range.add(id); + self.result.set(id_range) } } pub fn compute_id_range_for_inlined_item(item: &inlined_item) -> id_range { - let result = @mut id_range::max(); - visit_ids_for_inlined_item(item, &IdRangeComputingVisitor { - result: result, - }); - *result + let visitor = IdRangeComputingVisitor { + result: Cell::new(id_range::max()) + }; + visit_ids_for_inlined_item(item, &visitor); + visitor.result.get() } pub fn is_item_impl(item: @ast::item) -> bool { @@ -709,21 +712,25 @@ pub fn new_mark(m:Mrk, tail:SyntaxContext) -> SyntaxContext { // Extend a syntax context with a given mark and table // FIXME #8215 : currently pub to allow testing -pub fn new_mark_internal(m:Mrk, tail:SyntaxContext,table:&mut SCTable) - -> SyntaxContext { +pub fn new_mark_internal(m: Mrk, tail: SyntaxContext, table: &SCTable) + -> SyntaxContext { let key = (tail,m); // FIXME #5074 : can't use more natural style because we're missing // flow-sensitivity. Results in two lookups on a hash table hit. // also applies to new_rename_internal, below. // let try_lookup = table.mark_memo.find(&key); - match table.mark_memo.contains_key(&key) { + let mut mark_memo = table.mark_memo.borrow_mut(); + match mark_memo.get().contains_key(&key) { false => { - let new_idx = idx_push(&mut table.table,Mark(m,tail)); - table.mark_memo.insert(key,new_idx); + let new_idx = { + let mut table = table.table.borrow_mut(); + idx_push(table.get(), Mark(m,tail)) + }; + mark_memo.get().insert(key,new_idx); new_idx } true => { - match table.mark_memo.find(&key) { + match mark_memo.get().find(&key) { None => fail!("internal error: key disappeared 2013042901"), Some(idxptr) => {*idxptr} } @@ -738,19 +745,26 @@ pub fn new_rename(id:Ident, to:Name, tail:SyntaxContext) -> SyntaxContext { // Extend a syntax context with a given rename and sctable // FIXME #8215 : currently pub to allow testing -pub fn new_rename_internal(id:Ident, to:Name, tail:SyntaxContext, table: &mut SCTable) - -> SyntaxContext { +pub fn new_rename_internal(id: Ident, + to: Name, + tail: SyntaxContext, + table: &SCTable) + -> SyntaxContext { let key = (tail,id,to); // FIXME #5074 //let try_lookup = table.rename_memo.find(&key); - match table.rename_memo.contains_key(&key) { + let mut rename_memo = table.rename_memo.borrow_mut(); + match rename_memo.get().contains_key(&key) { false => { - let new_idx = idx_push(&mut table.table,Rename(id,to,tail)); - table.rename_memo.insert(key,new_idx); + let new_idx = { + let mut table = table.table.borrow_mut(); + idx_push(table.get(), Rename(id,to,tail)) + }; + rename_memo.get().insert(key,new_idx); new_idx } true => { - match table.rename_memo.find(&key) { + match rename_memo.get().find(&key) { None => fail!("internal error: key disappeared 2013042902"), Some(idxptr) => {*idxptr} } @@ -763,18 +777,18 @@ pub fn new_rename_internal(id:Ident, to:Name, tail:SyntaxContext, table: &mut SC // FIXME #8215 : currently pub to allow testing pub fn new_sctable_internal() -> SCTable { SCTable { - table: ~[EmptyCtxt,IllegalCtxt], - mark_memo: HashMap::new(), - rename_memo: HashMap::new() + table: RefCell::new(~[EmptyCtxt,IllegalCtxt]), + mark_memo: RefCell::new(HashMap::new()), + rename_memo: RefCell::new(HashMap::new()), } } // fetch the SCTable from TLS, create one if it doesn't yet exist. -pub fn get_sctable() -> @mut SCTable { - local_data_key!(sctable_key: @@mut SCTable) +pub fn get_sctable() -> @SCTable { + local_data_key!(sctable_key: @@SCTable) match local_data::get(sctable_key, |k| k.map(|k| *k)) { None => { - let new_table = @@mut new_sctable_internal(); + let new_table = @@new_sctable_internal(); local_data::set(sctable_key,new_table); *new_table }, @@ -785,7 +799,8 @@ pub fn get_sctable() -> @mut SCTable { /// print out an SCTable for debugging pub fn display_sctable(table : &SCTable) { error!("SC table:"); - for (idx,val) in table.table.iter().enumerate() { + let table = table.table.borrow(); + for (idx,val) in table.get().iter().enumerate() { error!("{:4u} : {:?}",idx,val); } } @@ -799,7 +814,9 @@ fn idx_push<T>(vec: &mut ~[T], val: T) -> u32 { /// Resolve a syntax object to a name, per MTWT. pub fn mtwt_resolve(id : Ident) -> Name { - resolve_internal(id, get_sctable(), get_resolve_table()) + let resolve_table = get_resolve_table(); + let mut resolve_table = resolve_table.borrow_mut(); + resolve_internal(id, get_sctable(), resolve_table.get()) } // FIXME #8215: must be pub for testing @@ -807,12 +824,12 @@ pub type ResolveTable = HashMap<(Name,SyntaxContext),Name>; // okay, I admit, putting this in TLS is not so nice: // fetch the SCTable from TLS, create one if it doesn't yet exist. -pub fn get_resolve_table() -> @mut ResolveTable { - local_data_key!(resolve_table_key: @@mut ResolveTable) +pub fn get_resolve_table() -> @RefCell<ResolveTable> { + local_data_key!(resolve_table_key: @@RefCell<ResolveTable>) match local_data::get(resolve_table_key, |k| k.map(|k| *k)) { None => { - let new_table = @@mut HashMap::new(); - local_data::set(resolve_table_key,new_table); + let new_table = @@RefCell::new(HashMap::new()); + local_data::set(resolve_table_key, new_table); *new_table }, Some(intr) => *intr @@ -823,13 +840,17 @@ pub fn get_resolve_table() -> @mut ResolveTable { // adding memoization to possibly resolve 500+ seconds in resolve for librustc (!) // FIXME #8215 : currently pub to allow testing pub fn resolve_internal(id : Ident, - table : &mut SCTable, + table : &SCTable, resolve_table : &mut ResolveTable) -> Name { let key = (id.name,id.ctxt); match resolve_table.contains_key(&key) { false => { let resolved = { - match table.table[id.ctxt] { + let result = { + let table = table.table.borrow(); + table.get()[id.ctxt] + }; + match result { EmptyCtxt => id.name, // ignore marks here: Mark(_,subctxt) => @@ -874,7 +895,11 @@ pub fn marksof(ctxt: SyntaxContext, stopname: Name, table: &SCTable) -> ~[Mrk] { let mut result = ~[]; let mut loopvar = ctxt; loop { - match table.table[loopvar] { + let table_entry = { + let table = table.table.borrow(); + table.get()[loopvar] + }; + match table_entry { EmptyCtxt => {return result;}, Mark(mark,tl) => { xorPush(&mut result,mark); @@ -898,7 +923,8 @@ pub fn marksof(ctxt: SyntaxContext, stopname: Name, table: &SCTable) -> ~[Mrk] { /// FAILS when outside is not a mark. pub fn mtwt_outer_mark(ctxt: SyntaxContext) -> Mrk { let sctable = get_sctable(); - match sctable.table[ctxt] { + let table = sctable.table.borrow(); + match table.get()[ctxt] { ast::Mark(mrk,_) => mrk, _ => fail!("can't retrieve outer mark when outside is not a mark") } @@ -1003,7 +1029,7 @@ mod test { // unfold a vector of TestSC values into a SCTable, // returning the resulting index - fn unfold_test_sc(tscs : ~[TestSC], tail: SyntaxContext, table : &mut SCTable) + fn unfold_test_sc(tscs : ~[TestSC], tail: SyntaxContext, table: &SCTable) -> SyntaxContext { tscs.rev_iter().fold(tail, |tail : SyntaxContext, tsc : &TestSC| {match *tsc { @@ -1015,7 +1041,8 @@ mod test { fn refold_test_sc(mut sc: SyntaxContext, table : &SCTable) -> ~[TestSC] { let mut result = ~[]; loop { - match table.table[sc] { + let table = table.table.borrow(); + match table.get()[sc] { EmptyCtxt => {return result;}, Mark(mrk,tail) => { result.push(M(mrk)); @@ -1037,15 +1064,19 @@ mod test { let test_sc = ~[M(3),R(id(101,0),14),M(9)]; assert_eq!(unfold_test_sc(test_sc.clone(),EMPTY_CTXT,&mut t),4); - assert_eq!(t.table[2],Mark(9,0)); - assert_eq!(t.table[3],Rename(id(101,0),14,2)); - assert_eq!(t.table[4],Mark(3,3)); + { + let table = t.table.borrow(); + assert_eq!(table.get()[2],Mark(9,0)); + assert_eq!(table.get()[3],Rename(id(101,0),14,2)); + assert_eq!(table.get()[4],Mark(3,3)); + } assert_eq!(refold_test_sc(4,&t),test_sc); } // extend a syntax context with a sequence of marks given // in a vector. v[0] will be the outermost mark. - fn unfold_marks(mrks:~[Mrk],tail:SyntaxContext,table: &mut SCTable) -> SyntaxContext { + fn unfold_marks(mrks: ~[Mrk], tail: SyntaxContext, table: &SCTable) + -> SyntaxContext { mrks.rev_iter().fold(tail, |tail:SyntaxContext, mrk:&Mrk| {new_mark_internal(*mrk,tail,table)}) } @@ -1054,8 +1085,11 @@ mod test { let mut t = new_sctable_internal(); assert_eq!(unfold_marks(~[3,7],EMPTY_CTXT,&mut t),3); - assert_eq!(t.table[2],Mark(7,0)); - assert_eq!(t.table[3],Mark(3,2)); + { + let table = t.table.borrow(); + assert_eq!(table.get()[2],Mark(7,0)); + assert_eq!(table.get()[3],Mark(3,2)); + } } #[test] fn test_marksof () { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 7a3ac0f2f4d..df8b45dbcf5 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -355,8 +355,7 @@ pub fn find_stability<AM: AttrMetaMethods, It: Iterator<AM>>(mut metas: It) -> O None } -pub fn require_unique_names(diagnostic: @mut SpanHandler, - metas: &[@MetaItem]) { +pub fn require_unique_names(diagnostic: @SpanHandler, metas: &[@MetaItem]) { let mut set = HashSet::new(); for meta in metas.iter() { let name = meta.name(); @@ -381,7 +380,7 @@ pub fn require_unique_names(diagnostic: @mut SpanHandler, * present (before fields, if any) with that type; reprensentation * optimizations which would remove it will not be done. */ -pub fn find_repr_attr(diagnostic: @mut SpanHandler, attr: @ast::MetaItem, acc: ReprAttr) +pub fn find_repr_attr(diagnostic: @SpanHandler, attr: @ast::MetaItem, acc: ReprAttr) -> ReprAttr { let mut acc = acc; match attr.node { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index fffcae0bde3..c0aee7fc634 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -21,6 +21,7 @@ source code snippets, etc. */ +use std::cell::RefCell; use std::cmp; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -220,9 +221,9 @@ pub struct FileMap { /// The start position of this source in the CodeMap start_pos: BytePos, /// Locations of lines beginnings in the source code - lines: @mut ~[BytePos], + lines: RefCell<~[BytePos]>, /// Locations of multi-byte characters in the source code - multibyte_chars: @mut ~[MultiByteChar], + multibyte_chars: RefCell<~[MultiByteChar]>, } impl FileMap { @@ -233,14 +234,16 @@ impl FileMap { // about what ends a line between this file and parse.rs pub fn next_line(&self, pos: BytePos) { // 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)) - lines.push(pos); + let mut lines = self.lines.borrow_mut();; + let line_len = lines.get().len(); + assert!(line_len == 0 || (lines.get()[line_len - 1] < pos)) + lines.get().push(pos); } // get a line from the list of pre-computed line-beginnings pub fn get_line(&self, line: int) -> ~str { - let begin: BytePos = self.lines[line] - self.start_pos; + let mut lines = self.lines.borrow_mut(); + let begin: BytePos = lines.get()[line] - self.start_pos; let begin = begin.to_uint(); let slice = self.src.slice_from(begin); match slice.find('\n') { @@ -255,7 +258,8 @@ impl FileMap { pos: pos, bytes: bytes, }; - self.multibyte_chars.push(mbc); + let mut multibyte_chars = self.multibyte_chars.borrow_mut(); + multibyte_chars.get().push(mbc); } pub fn is_real_file(&self) -> bool { @@ -264,13 +268,13 @@ impl FileMap { } pub struct CodeMap { - files: @mut ~[@FileMap] + files: RefCell<~[@FileMap]> } impl CodeMap { pub fn new() -> CodeMap { CodeMap { - files: @mut ~[], + files: RefCell::new(~[]), } } @@ -284,23 +288,23 @@ impl CodeMap { substr: FileSubstr, src: @str) -> @FileMap { - let files = &mut *self.files; - let start_pos = if files.len() == 0 { + let mut files = self.files.borrow_mut(); + let start_pos = if files.get().len() == 0 { 0 } else { - let last_start = files.last().start_pos.to_uint(); - let last_len = files.last().src.len(); + let last_start = files.get().last().start_pos.to_uint(); + let last_len = files.get().last().src.len(); last_start + last_len }; let filemap = @FileMap { name: filename, substr: substr, src: src, start_pos: Pos::from_uint(start_pos), - lines: @mut ~[], - multibyte_chars: @mut ~[], + lines: RefCell::new(~[]), + multibyte_chars: RefCell::new(~[]), }; - files.push(filemap); + files.get().push(filemap); return filemap; } @@ -346,9 +350,11 @@ impl CodeMap { } pub fn span_to_str(&self, sp: Span) -> ~str { - let files = &*self.files; - if files.len() == 0 && sp == DUMMY_SP { - return ~"no-location"; + { + let files = self.files.borrow(); + if files.get().len() == 0 && sp == DUMMY_SP { + return ~"no-location"; + } } let lo = self.lookup_char_pos_adj(sp.lo); @@ -388,7 +394,12 @@ impl CodeMap { } pub fn get_filemap(&self, filename: &str) -> @FileMap { - for fm in self.files.iter() { if filename == fm.name { return *fm; } } + let files = self.files.borrow(); + for fm in files.get().iter() { + if filename == fm.name { + return *fm + } + } //XXjdm the following triggers a mismatched type bug // (or expected function, found _|_) fail!(); // ("asking for " + filename + " which we don't know about"); @@ -397,13 +408,14 @@ impl CodeMap { impl CodeMap { fn lookup_filemap_idx(&self, pos: BytePos) -> uint { - let files = &*self.files; + let files = self.files.borrow(); + let files = files.get(); let len = files.len(); let mut a = 0u; let mut b = len; while b - a > 1u { let m = (a + b) / 2u; - if self.files[m].start_pos > pos { + if files[m].start_pos > pos { b = m; } else { a = m; @@ -419,13 +431,15 @@ impl CodeMap { fn lookup_line(&self, pos: BytePos) -> FileMapAndLine { let idx = self.lookup_filemap_idx(pos); - let f = self.files[idx]; + + let files = self.files.borrow(); + let f = files.get()[idx]; let mut a = 0u; - let lines = &*f.lines; - let mut b = lines.len(); + let mut lines = f.lines.borrow_mut(); + let mut b = lines.get().len(); while b - a > 1u { let m = (a + b) / 2u; - if lines[m] > pos { b = m; } else { a = m; } + if lines.get()[m] > pos { b = m; } else { a = m; } } return FileMapAndLine {fm: f, line: a}; } @@ -434,7 +448,8 @@ impl CodeMap { let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos); let line = a + 1u; // Line numbers start at 1 let chpos = self.bytepos_to_local_charpos(pos); - let linebpos = f.lines[a]; + let mut lines = f.lines.borrow_mut(); + let linebpos = lines.get()[a]; let linechpos = self.bytepos_to_local_charpos(linebpos); debug!("codemap: byte pos {:?} is on the line at byte pos {:?}", pos, linebpos); @@ -452,7 +467,8 @@ impl CodeMap { fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); - let fm = self.files[idx]; + let files = self.files.borrow(); + let fm = files.get()[idx]; let offset = bpos - fm.start_pos; return FileMapAndBytePos {fm: fm, pos: offset}; } @@ -462,12 +478,14 @@ impl CodeMap { fn bytepos_to_local_charpos(&self, bpos: BytePos) -> CharPos { debug!("codemap: converting {:?} to char pos", bpos); let idx = self.lookup_filemap_idx(bpos); - let map = self.files[idx]; + let files = self.files.borrow(); + let map = files.get()[idx]; // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; - for mbc in map.multibyte_chars.iter() { + let multibyte_chars = map.multibyte_chars.borrow(); + for mbc in multibyte_chars.get().iter() { debug!("codemap: {:?}-byte char at {:?}", mbc.bytes, mbc.pos); if mbc.pos < bpos { total_extra_bytes += mbc.bytes; diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index c905281cdb2..76327c27898 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -11,6 +11,7 @@ use codemap::{Pos, Span}; use codemap; +use std::cell::Cell; use std::io; use std::io::stdio::StdWriter; use std::local_data; @@ -30,32 +31,32 @@ pub trait Emitter { // accepts span information for source-location // reporting. pub struct SpanHandler { - handler: @mut Handler, + handler: @Handler, cm: @codemap::CodeMap, } impl SpanHandler { - pub fn span_fatal(@mut self, sp: Span, msg: &str) -> ! { + pub fn span_fatal(@self, sp: Span, msg: &str) -> ! { self.handler.emit(Some((&*self.cm, sp)), msg, fatal); fail!(); } - pub fn span_err(@mut self, sp: Span, msg: &str) { + pub fn span_err(@self, sp: Span, msg: &str) { self.handler.emit(Some((&*self.cm, sp)), msg, error); self.handler.bump_err_count(); } - pub fn span_warn(@mut self, sp: Span, msg: &str) { + pub fn span_warn(@self, sp: Span, msg: &str) { self.handler.emit(Some((&*self.cm, sp)), msg, warning); } - pub fn span_note(@mut self, sp: Span, msg: &str) { + pub fn span_note(@self, sp: Span, msg: &str) { self.handler.emit(Some((&*self.cm, sp)), msg, note); } - pub fn span_bug(@mut self, sp: Span, msg: &str) -> ! { + pub fn span_bug(@self, sp: Span, msg: &str) -> ! { self.span_fatal(sp, ice_msg(msg)); } - pub fn span_unimpl(@mut self, sp: Span, msg: &str) -> ! { + pub fn span_unimpl(@self, sp: Span, msg: &str) -> ! { self.span_bug(sp, ~"unimplemented " + msg); } - pub fn handler(@mut self) -> @mut Handler { + pub fn handler(@self) -> @Handler { self.handler } } @@ -64,53 +65,53 @@ impl SpanHandler { // (fatal, bug, unimpl) may cause immediate exit, // others log errors for later reporting. pub struct Handler { - err_count: uint, + err_count: Cell<uint>, emit: @Emitter, } impl Handler { - pub fn fatal(@mut self, msg: &str) -> ! { + pub fn fatal(@self, msg: &str) -> ! { self.emit.emit(None, msg, fatal); fail!(); } - pub fn err(@mut self, msg: &str) { + pub fn err(@self, msg: &str) { self.emit.emit(None, msg, error); self.bump_err_count(); } - pub fn bump_err_count(@mut self) { - self.err_count += 1u; + pub fn bump_err_count(@self) { + self.err_count.set(self.err_count.get() + 1u); } - pub fn err_count(@mut self) -> uint { - self.err_count + pub fn err_count(@self) -> uint { + self.err_count.get() } - pub fn has_errors(@mut self) -> bool { - self.err_count > 0u + pub fn has_errors(@self) -> bool { + self.err_count.get()> 0u } - pub fn abort_if_errors(@mut self) { + pub fn abort_if_errors(@self) { let s; - match self.err_count { + match self.err_count.get() { 0u => return, 1u => s = ~"aborting due to previous error", _ => { s = format!("aborting due to {} previous errors", - self.err_count); + self.err_count.get()); } } self.fatal(s); } - pub fn warn(@mut self, msg: &str) { + pub fn warn(@self, msg: &str) { self.emit.emit(None, msg, warning); } - pub fn note(@mut self, msg: &str) { + pub fn note(@self, msg: &str) { self.emit.emit(None, msg, note); } - pub fn bug(@mut self, msg: &str) -> ! { + pub fn bug(@self, msg: &str) -> ! { self.fatal(ice_msg(msg)); } - pub fn unimpl(@mut self, msg: &str) -> ! { + pub fn unimpl(@self, msg: &str) -> ! { self.bug(~"unimplemented " + msg); } - pub fn emit(@mut self, + pub fn emit(@self, cmsp: Option<(&codemap::CodeMap, Span)>, msg: &str, lvl: level) { @@ -123,22 +124,22 @@ pub fn ice_msg(msg: &str) -> ~str { \nWe would appreciate a bug report: {}", msg, BUG_REPORT_URL) } -pub fn mk_span_handler(handler: @mut Handler, cm: @codemap::CodeMap) - -> @mut SpanHandler { - @mut SpanHandler { +pub fn mk_span_handler(handler: @Handler, cm: @codemap::CodeMap) + -> @SpanHandler { + @SpanHandler { handler: handler, cm: cm, } } -pub fn mk_handler(emitter: Option<@Emitter>) -> @mut Handler { +pub fn mk_handler(emitter: Option<@Emitter>) -> @Handler { let emit: @Emitter = match emitter { Some(e) => e, None => @DefaultEmitter as @Emitter }; - @mut Handler { - err_count: 0, + @Handler { + err_count: Cell::new(0), emit: emit, } } @@ -327,10 +328,7 @@ fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) { } } -pub fn expect<T:Clone>( - diag: @mut SpanHandler, - opt: Option<T>, - msg: || -> ~str) +pub fn expect<T:Clone>(diag: @SpanHandler, opt: Option<T>, msg: || -> ~str) -> T { match opt { Some(ref t) => (*t).clone(), diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 03e028ea1f1..b4888f1092f 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -284,7 +284,7 @@ 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 struct ExtCtxt { - parse_sess: @mut parse::ParseSess, + parse_sess: @parse::ParseSess, cfg: ast::CrateConfig, backtrace: Option<@ExpnInfo>, @@ -293,7 +293,7 @@ pub struct ExtCtxt { } impl ExtCtxt { - pub fn new(parse_sess: @mut parse::ParseSess, cfg: ast::CrateConfig) + pub fn new(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig) -> ExtCtxt { ExtCtxt { parse_sess: parse_sess, @@ -320,7 +320,7 @@ impl ExtCtxt { } pub fn codemap(&self) -> @CodeMap { self.parse_sess.cm } - pub fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess } + pub fn parse_sess(&self) -> @parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() } pub fn call_site(&self) -> Span { match self.backtrace { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 1a3513ab81c..481472e8f0b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -54,7 +54,7 @@ pub trait AstBuilder { lifetime: Option<ast::Lifetime>, mutbl: ast::Mutability) -> P<ast::Ty>; fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>; - fn ty_box(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty>; + fn ty_box(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>; fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>; fn ty_infer(&self, sp: Span) -> P<ast::Ty>; @@ -311,12 +311,13 @@ impl AstBuilder for ExtCtxt { self.ty(span, ast::ty_rptr(lifetime, self.ty_mt(ty, mutbl))) } + fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> { self.ty(span, ast::ty_uniq(ty)) } - fn ty_box(&self, span: Span, - ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty> { - self.ty(span, ast::ty_box(self.ty_mt(ty, mutbl))) + + fn ty_box(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> { + self.ty(span, ast::ty_box(ty)) } fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> { @@ -494,7 +495,7 @@ impl AstBuilder for ExtCtxt { } fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { - self.expr_unary(sp, ast::UnBox(ast::MutImmutable), e) + self.expr_unary(sp, ast::UnBox, e) } fn expr_field_access(&self, sp: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr { diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 10e07520a84..89bed626c1e 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -24,7 +24,7 @@ use opt_vec::OptVec; /// The types of pointers pub enum PtrTy<'a> { Send, // ~ - Managed(ast::Mutability), // @[mut] + Managed, // @ Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut] } @@ -138,8 +138,8 @@ impl<'a> Ty<'a> { Send => { cx.ty_uniq(span, raw_ty) } - Managed(mutbl) => { - cx.ty_box(span, raw_ty, mutbl) + Managed => { + cx.ty_box(span, raw_ty) } Borrowed(ref lt, mutbl) => { let lt = mk_lifetime(cx, span, lt); @@ -251,7 +251,7 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>) span, match *ptr { Send => ast::sty_uniq(ast::MutImmutable), - Managed(mutbl) => ast::sty_box(mutbl), + Managed => ast::sty_box(ast::MutImmutable), Borrowed(ref lt, mutbl) => { let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s))); ast::sty_region(lt, mutbl) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 1d9620d405f..aa7c26805c3 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -493,13 +493,14 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) let mut name_finder = new_name_finder(~[]); name_finder.visit_pat(expanded_pat,()); // generate fresh names, push them to a new pending list - let new_pending_renames = @mut ~[]; + let mut new_pending_renames = ~[]; for ident in name_finder.ident_accumulator.iter() { let new_name = fresh_name(ident); new_pending_renames.push((*ident,new_name)); } let rewritten_pat = { - let mut rename_fld = renames_to_fold(new_pending_renames); + let mut rename_fld = + renames_to_fold(&mut new_pending_renames); // rewrite the pattern using the new names (the old ones // have already been applied): rename_fld.fold_pat(expanded_pat) @@ -889,7 +890,7 @@ impl ast_fold for Injector { // add a bunch of macros as though they were placed at the head of the // program (ick). This should run before cfg stripping. -pub fn inject_std_macros(parse_sess: @mut parse::ParseSess, +pub fn inject_std_macros(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig, c: Crate) -> Crate { @@ -939,7 +940,7 @@ impl<'a> ast_fold for MacroExpander<'a> { } } -pub fn expand_crate(parse_sess: @mut parse::ParseSess, +pub fn expand_crate(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig, c: Crate) -> Crate { let mut cx = ExtCtxt::new(parse_sess, cfg.clone()); @@ -981,21 +982,6 @@ impl CtxtFn for Renamer { } } -// a renamer that performs a whole bunch of renames -pub struct MultiRenamer { - renames : @mut ~[(ast::Ident,ast::Name)] -} - -impl CtxtFn for MultiRenamer { - fn f(&self, starting_ctxt : ast::SyntaxContext) -> ast::SyntaxContext { - // the individual elements are memoized... it would - // also be possible to memoize on the whole list at once. - self.renames.iter().fold(starting_ctxt,|ctxt,&(from,to)| { - new_rename(from,to,ctxt) - }) - } -} - // a marker adds the given mark to the syntax context pub struct Marker { mark : Mrk } @@ -1306,9 +1292,11 @@ mod test { let a3_name = gensym("a3"); // a context that renames from ("a",empty) to "a2" : let ctxt2 = new_rename(ast::Ident::new(a_name),a2_name,EMPTY_CTXT); - let pending_renames = @mut ~[(ast::Ident::new(a_name),a2_name), - (ast::Ident{name:a_name,ctxt:ctxt2},a3_name)]; - let double_renamed = renames_to_fold(pending_renames).fold_crate(item_ast); + let mut pending_renames = ~[ + (ast::Ident::new(a_name),a2_name), + (ast::Ident{name:a_name,ctxt:ctxt2},a3_name) + ]; + let double_renamed = renames_to_fold(&mut pending_renames).fold_crate(item_ast); let mut path_finder = new_path_finder(~[]); visit::walk_crate(&mut path_finder, &double_renamed, ()); match path_finder.path_accumulator { @@ -1318,11 +1306,11 @@ mod test { } } - fn fake_print_crate(crate: &ast::Crate) { - let out = @mut std::io::stderr() as @mut std::io::Writer; - let s = pprust::rust_printer(out, get_ident_interner()); - pprust::print_crate_(s, crate); - } + //fn fake_print_crate(crate: &ast::Crate) { + // let mut out = ~std::io::stderr() as ~std::io::Writer; + // let mut s = pprust::rust_printer(out, get_ident_interner()); + // pprust::print_crate_(&mut s, crate); + //} fn expand_crate_str(crate_str: @str) -> ast::Crate { let (crate_ast,ps) = string_to_crate_and_sess(crate_str); @@ -1516,8 +1504,12 @@ foo_module!() mtwt_resolve(v.segments[0].identifier)); let table = get_sctable(); println("SC table:"); - for (idx,val) in table.table.iter().enumerate() { - println!("{:4u} : {:?}",idx,val); + + { + let table = table.table.borrow(); + for (idx,val) in table.get().iter().enumerate() { + println!("{:4u} : {:?}",idx,val); + } } } assert_eq!(mtwt_resolve(v.segments[0].identifier),resolved_binding); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 11e7c1c8499..5f634f7f054 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -19,6 +19,7 @@ use parse; use parse::token::{get_ident_interner}; use print::pprust; +use std::cell::RefCell; use std::io; use std::io::File; use std::str; @@ -108,13 +109,14 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) let s = s.to_managed(); // Add this input file to the code map to make it available as // dependency information - cx.parse_sess.cm.files.push(@codemap::FileMap { + let mut files = cx.parse_sess.cm.files.borrow_mut(); + files.get().push(@codemap::FileMap { name: file.display().to_str().to_managed(), substr: codemap::FssNone, src: s, start_pos: codemap::BytePos(0), - lines: @mut ~[], - multibyte_chars: @mut ~[], + lines: RefCell::new(~[]), + multibyte_chars: RefCell::new(~[]), }); base::MRExpr(cx.expr_str(sp, s)) } diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs index 34151377d7b..a7d1d8fb366 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -25,7 +25,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt, let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic, None, tt.to_owned()); - let rdr = tt_rdr as @mut reader; + let rdr = tt_rdr as @reader; let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup()); if rust_parser.is_keyword(keywords::True) { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 4d2923f391e..8b22e32262b 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -188,9 +188,9 @@ pub enum named_match { pub type earley_item = ~MatcherPos; -pub fn nameize(p_s: @mut ParseSess, ms: &[matcher], res: &[@named_match]) +pub fn nameize(p_s: @ParseSess, ms: &[matcher], res: &[@named_match]) -> HashMap<Ident,@named_match> { - fn n_rec(p_s: @mut ParseSess, m: &matcher, res: &[@named_match], + fn n_rec(p_s: @ParseSess, m: &matcher, res: &[@named_match], ret_val: &mut HashMap<Ident, @named_match>) { match *m { codemap::Spanned {node: match_tok(_), .. } => (), @@ -221,12 +221,11 @@ pub enum parse_result { error(codemap::Span, ~str) } -pub fn parse_or_else( - sess: @mut ParseSess, - cfg: ast::CrateConfig, - rdr: @mut reader, - ms: ~[matcher] -) -> HashMap<Ident, @named_match> { +pub fn parse_or_else(sess: @ParseSess, + cfg: ast::CrateConfig, + rdr: @reader, + ms: ~[matcher]) + -> HashMap<Ident, @named_match> { match parse(sess, cfg, rdr, ms) { success(m) => m, failure(sp, str) => sess.span_diagnostic.span_fatal(sp, str), @@ -243,12 +242,11 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { } } -pub fn parse( - sess: @mut ParseSess, - cfg: ast::CrateConfig, - rdr: @mut reader, - ms: &[matcher] -) -> parse_result { +pub fn parse(sess: @ParseSess, + cfg: ast::CrateConfig, + rdr: @reader, + ms: &[matcher]) + -> parse_result { let mut cur_eis = ~[]; cur_eis.push(initial_matcher_pos(ms.to_owned(), None, rdr.peek().sp.lo)); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index c9827fb54bd..32d9ed1238b 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -130,11 +130,7 @@ fn generic_extension(cx: &ExtCtxt, match *lhs { @matched_nonterminal(nt_matchers(ref mtcs)) => { // `none` is because we're not interpolating - let arg_rdr = new_tt_reader( - s_d, - None, - arg.to_owned() - ) as @mut reader; + let arg_rdr = new_tt_reader(s_d, None, arg.to_owned()) as @reader; match parse(cx.parse_sess(), cx.cfg(), arg_rdr, *mtcs) { success(named_matches) => { let rhs = match rhses[i] { @@ -154,10 +150,7 @@ fn generic_extension(cx: &ExtCtxt, // rhs has holes ( `$id` and `$(...)` that need filled) let trncbr = new_tt_reader(s_d, Some(named_matches), rhs); - let p = Parser(cx.parse_sess(), - cx.cfg(), - trncbr as @mut reader); - + let p = Parser(cx.parse_sess(), cx.cfg(), trncbr as @reader); // Let the context choose how to interpret the result. // Weird, but useful for X-macros. return MRAny(@ParserAnyMacro { @@ -218,7 +211,7 @@ pub fn add_new_extension(cx: &mut ExtCtxt, arg.clone()); let argument_map = parse_or_else(cx.parse_sess(), cx.cfg(), - arg_reader as @mut reader, + arg_reader as @reader, argument_gram); // Extract the arguments: diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index cbce5fb16cb..060f6b8a8b9 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -17,65 +17,66 @@ use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident}; use parse::token::{ident_to_str}; use parse::lexer::TokenAndSpan; +use std::cell::{Cell, RefCell}; use std::hashmap::HashMap; use std::option; ///an unzipping of `token_tree`s struct TtFrame { forest: @~[ast::token_tree], - idx: uint, + idx: Cell<uint>, dotdotdoted: bool, sep: Option<Token>, - up: Option<@mut TtFrame>, + up: Option<@TtFrame>, } pub struct TtReader { - sp_diag: @mut SpanHandler, + sp_diag: @SpanHandler, // the unzipped tree: - stack: @mut TtFrame, + priv stack: RefCell<@TtFrame>, /* for MBE-style macro transcription */ - interpolations: HashMap<Ident, @named_match>, - repeat_idx: ~[uint], - repeat_len: ~[uint], + priv interpolations: RefCell<HashMap<Ident, @named_match>>, + priv repeat_idx: RefCell<~[uint]>, + priv repeat_len: RefCell<~[uint]>, /* cached: */ - cur_tok: Token, - cur_span: Span + cur_tok: RefCell<Token>, + cur_span: RefCell<Span>, } /** This can do Macro-By-Example transcription. On the other hand, if * `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and * should) be none. */ -pub fn new_tt_reader(sp_diag: @mut SpanHandler, +pub fn new_tt_reader(sp_diag: @SpanHandler, interp: Option<HashMap<Ident,@named_match>>, src: ~[ast::token_tree]) - -> @mut TtReader { - let r = @mut TtReader { + -> @TtReader { + let r = @TtReader { sp_diag: sp_diag, - stack: @mut TtFrame { + stack: RefCell::new(@TtFrame { forest: @src, - idx: 0u, + idx: Cell::new(0u), dotdotdoted: false, sep: None, up: option::None - }, + }), interpolations: match interp { /* just a convienience */ - None => HashMap::new(), - Some(x) => x + None => RefCell::new(HashMap::new()), + Some(x) => RefCell::new(x), }, - repeat_idx: ~[], - repeat_len: ~[], + repeat_idx: RefCell::new(~[]), + repeat_len: RefCell::new(~[]), /* dummy values, never read: */ - cur_tok: EOF, - cur_span: DUMMY_SP + cur_tok: RefCell::new(EOF), + cur_span: RefCell::new(DUMMY_SP), }; tt_next_token(r); /* get cur_tok and cur_span set up */ return r; } -fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame { - @mut TtFrame { +fn dup_tt_frame(f: @TtFrame) -> @TtFrame { + @TtFrame { forest: @(*f.forest).clone(), - idx: f.idx, + idx: f.idx.clone(), dotdotdoted: f.dotdotdoted, sep: f.sep.clone(), up: match f.up { @@ -85,22 +86,21 @@ fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame { } } -pub fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader { - @mut TtReader { +pub fn dup_tt_reader(r: @TtReader) -> @TtReader { + @TtReader { sp_diag: r.sp_diag, - stack: dup_tt_frame(r.stack), + stack: RefCell::new(dup_tt_frame(r.stack.get())), repeat_idx: r.repeat_idx.clone(), repeat_len: r.repeat_len.clone(), cur_tok: r.cur_tok.clone(), - cur_span: r.cur_span, + cur_span: r.cur_span.clone(), interpolations: r.interpolations.clone(), } } -fn lookup_cur_matched_by_matched(r: &mut TtReader, - start: @named_match) - -> @named_match { +fn lookup_cur_matched_by_matched(r: &TtReader, start: @named_match) + -> @named_match { fn red(ad: @named_match, idx: &uint) -> @named_match { match *ad { matched_nonterminal(_) => { @@ -110,15 +110,21 @@ fn lookup_cur_matched_by_matched(r: &mut TtReader, matched_seq(ref ads, _) => ads[*idx] } } - r.repeat_idx.iter().fold(start, red) + let repeat_idx = r.repeat_idx.borrow(); + repeat_idx.get().iter().fold(start, red) } -fn lookup_cur_matched(r: &mut TtReader, name: Ident) -> @named_match { - match r.interpolations.find_copy(&name) { +fn lookup_cur_matched(r: &TtReader, name: Ident) -> @named_match { + let matched_opt = { + let interpolations = r.interpolations.borrow(); + interpolations.get().find_copy(&name) + }; + match matched_opt { Some(s) => lookup_cur_matched_by_matched(r, s), None => { - r.sp_diag.span_fatal(r.cur_span, format!("unknown macro variable `{}`", - ident_to_str(&name))); + r.sp_diag.span_fatal(r.cur_span.get(), + format!("unknown macro variable `{}`", + ident_to_str(&name))); } } } @@ -130,7 +136,7 @@ enum lis { lis_contradiction(~str), } -fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis { +fn lockstep_iter_size(t: &token_tree, r: &TtReader) -> lis { fn lis_merge(lhs: lis, rhs: lis) -> lis { match lhs { lis_unconstrained => rhs.clone(), @@ -166,46 +172,56 @@ fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis { // return the next token from the TtReader. // EFFECT: advances the reader's token field -pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { +pub fn tt_next_token(r: &TtReader) -> TokenAndSpan { // XXX(pcwalton): Bad copy? let ret_val = TokenAndSpan { - tok: r.cur_tok.clone(), - sp: r.cur_span, + tok: r.cur_tok.get(), + sp: r.cur_span.get(), }; loop { { - let stack = &mut *r.stack; - if stack.idx < stack.forest.len() { + let mut stack = r.stack.borrow_mut(); + if stack.get().idx.get() < stack.get().forest.len() { break; } } /* done with this set; pop or repeat? */ - if ! r.stack.dotdotdoted - || { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } { + if !r.stack.get().dotdotdoted || { + let repeat_idx = r.repeat_idx.borrow(); + let repeat_len = r.repeat_len.borrow(); + *repeat_idx.get().last() == *repeat_len.get().last() - 1 + } { - match r.stack.up { + match r.stack.get().up { None => { - r.cur_tok = EOF; + r.cur_tok.set(EOF); return ret_val; } Some(tt_f) => { - if r.stack.dotdotdoted { - r.repeat_idx.pop(); - r.repeat_len.pop(); + if r.stack.get().dotdotdoted { + { + let mut repeat_idx = r.repeat_idx.borrow_mut(); + let mut repeat_len = r.repeat_len.borrow_mut(); + repeat_idx.get().pop(); + repeat_len.get().pop(); + } } - r.stack = tt_f; - r.stack.idx += 1u; + r.stack.set(tt_f); + r.stack.get().idx.set(r.stack.get().idx.get() + 1u); } } } else { /* repeat */ - r.stack.idx = 0u; - r.repeat_idx[r.repeat_idx.len() - 1u] += 1u; - match r.stack.sep.clone() { + r.stack.get().idx.set(0u); + { + let mut repeat_idx = r.repeat_idx.borrow_mut(); + repeat_idx.get()[repeat_idx.get().len() - 1u] += 1u; + } + match r.stack.get().sep.clone() { Some(tk) => { - r.cur_tok = tk; /* repeat same span, I guess */ + r.cur_tok.set(tk); /* repeat same span, I guess */ return ret_val; } None => () @@ -215,21 +231,21 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { loop { /* because it's easiest, this handles `tt_delim` not starting with a `tt_tok`, even though it won't happen */ // XXX(pcwalton): Bad copy. - match r.stack.forest[r.stack.idx].clone() { + match r.stack.get().forest[r.stack.get().idx.get()].clone() { tt_delim(tts) => { - r.stack = @mut TtFrame { + r.stack.set(@TtFrame { forest: tts, - idx: 0u, + idx: Cell::new(0u), dotdotdoted: false, sep: None, - up: option::Some(r.stack) - }; + up: option::Some(r.stack.get()) + }); // if this could be 0-length, we'd need to potentially recur here } tt_tok(sp, tok) => { - r.cur_span = sp; - r.cur_tok = tok; - r.stack.idx += 1u; + r.cur_span.set(sp); + r.cur_tok.set(tok); + r.stack.get().idx.set(r.stack.get().idx.get() + 1u); return ret_val; } tt_seq(sp, tts, sep, zerok) => { @@ -256,18 +272,22 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { once"); } - r.stack.idx += 1u; + r.stack.get().idx.set(r.stack.get().idx.get() + 1u); return tt_next_token(r); } else { - r.repeat_len.push(len); - r.repeat_idx.push(0u); - r.stack = @mut TtFrame { - forest: tts, - idx: 0u, - dotdotdoted: true, - sep: sep, - up: Some(r.stack) - }; + { + let mut repeat_idx = r.repeat_idx.borrow_mut(); + let mut repeat_len = r.repeat_len.borrow_mut(); + repeat_len.get().push(len); + repeat_idx.get().push(0u); + r.stack.set(@TtFrame { + forest: tts, + idx: Cell::new(0u), + dotdotdoted: true, + sep: sep, + up: Some(r.stack.get()) + }); + } } } } @@ -279,20 +299,21 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { (a) idents can be in lots of places, so it'd be a pain (b) we actually can, since it's a token. */ matched_nonterminal(nt_ident(~sn,b)) => { - r.cur_span = sp; r.cur_tok = IDENT(sn,b); - r.stack.idx += 1u; + r.cur_span.set(sp); + r.cur_tok.set(IDENT(sn,b)); + r.stack.get().idx.set(r.stack.get().idx.get() + 1u); return ret_val; } matched_nonterminal(ref other_whole_nt) => { // XXX(pcwalton): Bad copy. - r.cur_span = sp; - r.cur_tok = INTERPOLATED((*other_whole_nt).clone()); - r.stack.idx += 1u; + r.cur_span.set(sp); + r.cur_tok.set(INTERPOLATED((*other_whole_nt).clone())); + r.stack.get().idx.set(r.stack.get().idx.get() + 1u); return ret_val; } matched_seq(..) => { r.sp_diag.span_fatal( - r.cur_span, /* blame the macro writer */ + r.cur_span.get(), /* blame the macro writer */ format!("variable '{}' is still repeating at this depth", ident_to_str(&ident))); } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4a2adc04fbd..47130a8e355 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -238,7 +238,7 @@ pub trait ast_fold { fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> { let node = match t.node { ty_nil | ty_bot | ty_infer => t.node.clone(), - ty_box(ref mt) => ty_box(fold_mt(mt, self)), + ty_box(ty) => ty_box(self.fold_ty(ty)), ty_uniq(ty) => ty_uniq(self.fold_ty(ty)), ty_vec(ty) => ty_vec(self.fold_ty(ty)), ty_ptr(ref mt) => ty_ptr(fold_mt(mt, self)), @@ -866,7 +866,7 @@ mod test { use super::*; // this version doesn't care about getting comments or docstrings in. - fn fake_print_crate(s: @pprust::ps, crate: &ast::Crate) { + fn fake_print_crate(s: &mut pprust::ps, crate: &ast::Crate) { pprust::print_mod(s, &crate.module, crate.attrs); } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index b1390253d19..e0ab7f1535d 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -135,39 +135,44 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { fail!("not a doc-comment: {}", comment); } -fn read_to_eol(rdr: @mut StringReader) -> ~str { +fn read_to_eol(rdr: @StringReader) -> ~str { let mut val = ~""; - while rdr.curr != '\n' && !is_eof(rdr) { - val.push_char(rdr.curr); + while rdr.curr.get() != '\n' && !is_eof(rdr) { + val.push_char(rdr.curr.get()); bump(rdr); } - if rdr.curr == '\n' { bump(rdr); } + if rdr.curr.get() == '\n' { bump(rdr); } return val; } -fn read_one_line_comment(rdr: @mut StringReader) -> ~str { +fn read_one_line_comment(rdr: @StringReader) -> ~str { let val = read_to_eol(rdr); assert!((val[0] == '/' as u8 && val[1] == '/' as u8) || (val[0] == '#' as u8 && val[1] == '!' as u8)); return val; } -fn consume_non_eol_whitespace(rdr: @mut StringReader) { - while is_whitespace(rdr.curr) && rdr.curr != '\n' && !is_eof(rdr) { +fn consume_non_eol_whitespace(rdr: @StringReader) { + while is_whitespace(rdr.curr.get()) && rdr.curr.get() != '\n' && + !is_eof(rdr) { bump(rdr); } } -fn push_blank_line_comment(rdr: @mut StringReader, comments: &mut ~[cmnt]) { +fn push_blank_line_comment(rdr: @StringReader, comments: &mut ~[cmnt]) { debug!(">>> blank-line comment"); let v: ~[~str] = ~[]; - comments.push(cmnt {style: blank_line, lines: v, pos: rdr.last_pos}); + comments.push(cmnt { + style: blank_line, + lines: v, + pos: rdr.last_pos.get(), + }); } -fn consume_whitespace_counting_blank_lines(rdr: @mut StringReader, +fn consume_whitespace_counting_blank_lines(rdr: @StringReader, comments: &mut ~[cmnt]) { - while is_whitespace(rdr.curr) && !is_eof(rdr) { - if rdr.col == CharPos(0u) && rdr.curr == '\n' { + while is_whitespace(rdr.curr.get()) && !is_eof(rdr) { + if rdr.col.get() == CharPos(0u) && rdr.curr.get() == '\n' { push_blank_line_comment(rdr, &mut *comments); } bump(rdr); @@ -175,10 +180,10 @@ fn consume_whitespace_counting_blank_lines(rdr: @mut StringReader, } -fn read_shebang_comment(rdr: @mut StringReader, code_to_the_left: bool, +fn read_shebang_comment(rdr: @StringReader, code_to_the_left: bool, comments: &mut ~[cmnt]) { debug!(">>> shebang comment"); - let p = rdr.last_pos; + let p = rdr.last_pos.get(); debug!("<<< shebang comment"); comments.push(cmnt { style: if code_to_the_left { trailing } else { isolated }, @@ -187,12 +192,12 @@ fn read_shebang_comment(rdr: @mut StringReader, code_to_the_left: bool, }); } -fn read_line_comments(rdr: @mut StringReader, code_to_the_left: bool, +fn read_line_comments(rdr: @StringReader, code_to_the_left: bool, comments: &mut ~[cmnt]) { debug!(">>> line comments"); - let p = rdr.last_pos; + let p = rdr.last_pos.get(); let mut lines: ~[~str] = ~[]; - while rdr.curr == '/' && nextch(rdr) == '/' { + while rdr.curr.get() == '/' && nextch(rdr) == '/' { let line = read_one_line_comment(rdr); debug!("{}", line); if is_doc_comment(line) { // doc-comments are not put in comments @@ -244,22 +249,22 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str], lines.push(s1); } -fn read_block_comment(rdr: @mut StringReader, +fn read_block_comment(rdr: @StringReader, code_to_the_left: bool, comments: &mut ~[cmnt]) { debug!(">>> block comment"); - let p = rdr.last_pos; + let p = rdr.last_pos.get(); let mut lines: ~[~str] = ~[]; - let col: CharPos = rdr.col; + let col: CharPos = rdr.col.get(); bump(rdr); bump(rdr); let mut curr_line = ~"/*"; // doc-comments are not really comments, they are attributes - if rdr.curr == '*' || rdr.curr == '!' { - while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) { - curr_line.push_char(rdr.curr); + if rdr.curr.get() == '*' || rdr.curr.get() == '!' { + while !(rdr.curr.get() == '*' && nextch(rdr) == '/') && !is_eof(rdr) { + curr_line.push_char(rdr.curr.get()); bump(rdr); } if !is_eof(rdr) { @@ -275,22 +280,22 @@ fn read_block_comment(rdr: @mut StringReader, while level > 0 { debug!("=== block comment level {}", level); if is_eof(rdr) { - (rdr as @mut reader).fatal(~"unterminated block comment"); + (rdr as @reader).fatal(~"unterminated block comment"); } - if rdr.curr == '\n' { + if rdr.curr.get() == '\n' { trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col); curr_line = ~""; bump(rdr); } else { - curr_line.push_char(rdr.curr); - if rdr.curr == '/' && nextch(rdr) == '*' { + curr_line.push_char(rdr.curr.get()); + if rdr.curr.get() == '/' && nextch(rdr) == '*' { bump(rdr); bump(rdr); curr_line.push_char('*'); level += 1; } else { - if rdr.curr == '*' && nextch(rdr) == '/' { + if rdr.curr.get() == '*' && nextch(rdr) == '/' { bump(rdr); bump(rdr); curr_line.push_char('/'); @@ -306,28 +311,28 @@ fn read_block_comment(rdr: @mut StringReader, let mut style = if code_to_the_left { trailing } else { isolated }; consume_non_eol_whitespace(rdr); - if !is_eof(rdr) && rdr.curr != '\n' && lines.len() == 1u { + if !is_eof(rdr) && rdr.curr.get() != '\n' && lines.len() == 1u { style = mixed; } debug!("<<< block comment"); comments.push(cmnt {style: style, lines: lines, pos: p}); } -fn peeking_at_comment(rdr: @mut StringReader) -> bool { - return ((rdr.curr == '/' && nextch(rdr) == '/') || - (rdr.curr == '/' && nextch(rdr) == '*')) || - (rdr.curr == '#' && nextch(rdr) == '!'); +fn peeking_at_comment(rdr: @StringReader) -> bool { + return ((rdr.curr.get() == '/' && nextch(rdr) == '/') || + (rdr.curr.get() == '/' && nextch(rdr) == '*')) || + (rdr.curr.get() == '#' && nextch(rdr) == '!'); } -fn consume_comment(rdr: @mut StringReader, +fn consume_comment(rdr: @StringReader, code_to_the_left: bool, comments: &mut ~[cmnt]) { debug!(">>> consume comment"); - if rdr.curr == '/' && nextch(rdr) == '/' { + if rdr.curr.get() == '/' && nextch(rdr) == '/' { read_line_comments(rdr, code_to_the_left, comments); - } else if rdr.curr == '/' && nextch(rdr) == '*' { + } else if rdr.curr.get() == '/' && nextch(rdr) == '*' { read_block_comment(rdr, code_to_the_left, comments); - } else if rdr.curr == '#' && nextch(rdr) == '!' { + } else if rdr.curr.get() == '#' && nextch(rdr) == '!' { read_shebang_comment(rdr, code_to_the_left, comments); } else { fail!(); } debug!("<<< consume comment"); @@ -342,7 +347,7 @@ pub struct lit { // it appears this function is called only from pprust... that's // probably not a good thing. pub fn gather_comments_and_literals(span_diagnostic: - @mut diagnostic::SpanHandler, + @diagnostic::SpanHandler, path: @str, srdr: &mut io::Reader) -> (~[cmnt], ~[lit]) { @@ -358,7 +363,7 @@ pub fn gather_comments_and_literals(span_diagnostic: loop { let mut code_to_the_left = !first_read; consume_non_eol_whitespace(rdr); - if rdr.curr == '\n' { + if rdr.curr.get() == '\n' { code_to_the_left = false; consume_whitespace_counting_blank_lines(rdr, &mut comments); } @@ -370,7 +375,7 @@ pub fn gather_comments_and_literals(span_diagnostic: } - let bstart = rdr.last_pos; + let bstart = rdr.last_pos.get(); rdr.next_token(); //discard, and look ahead; we're working with internal state let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index be93c962137..3b81b09112b 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -18,6 +18,7 @@ use parse::token; use parse::token::{str_to_ident}; use std::cast::transmute; +use std::cell::{Cell, RefCell}; use std::char; use std::num::from_str_radix; use std::util; @@ -25,12 +26,12 @@ use std::util; pub use ext::tt::transcribe::{TtReader, new_tt_reader}; pub trait reader { - fn is_eof(@mut self) -> bool; - fn next_token(@mut self) -> TokenAndSpan; - fn fatal(@mut self, ~str) -> !; - fn span_diag(@mut self) -> @mut SpanHandler; - fn peek(@mut self) -> TokenAndSpan; - fn dup(@mut self) -> @mut reader; + fn is_eof(@self) -> bool; + fn next_token(@self) -> TokenAndSpan; + fn fatal(@self, ~str) -> !; + fn span_diag(@self) -> @SpanHandler; + fn peek(@self) -> TokenAndSpan; + fn dup(@self) -> @reader; } #[deriving(Clone, Eq)] @@ -40,47 +41,47 @@ pub struct TokenAndSpan { } pub struct StringReader { - span_diagnostic: @mut SpanHandler, + span_diagnostic: @SpanHandler, src: @str, // The absolute offset within the codemap of the next character to read - pos: BytePos, + pos: Cell<BytePos>, // The absolute offset within the codemap of the last character read(curr) - last_pos: BytePos, + last_pos: Cell<BytePos>, // The column of the next character to read - col: CharPos, + col: Cell<CharPos>, // The last character to be read - curr: char, + curr: Cell<char>, filemap: @codemap::FileMap, /* cached: */ - peek_tok: token::Token, - peek_span: Span + peek_tok: RefCell<token::Token>, + peek_span: RefCell<Span>, } -pub fn new_string_reader(span_diagnostic: @mut SpanHandler, +pub fn new_string_reader(span_diagnostic: @SpanHandler, filemap: @codemap::FileMap) - -> @mut StringReader { + -> @StringReader { let r = new_low_level_string_reader(span_diagnostic, filemap); string_advance_token(r); /* fill in peek_* */ return r; } /* For comments.rs, which hackily pokes into 'pos' and 'curr' */ -pub fn new_low_level_string_reader(span_diagnostic: @mut SpanHandler, +pub fn new_low_level_string_reader(span_diagnostic: @SpanHandler, filemap: @codemap::FileMap) - -> @mut StringReader { + -> @StringReader { // Force the initial reader bump to start on a fresh line let initial_char = '\n'; - let r = @mut StringReader { + let r = @StringReader { span_diagnostic: span_diagnostic, src: filemap.src, - pos: filemap.start_pos, - last_pos: filemap.start_pos, - col: CharPos(0), - curr: initial_char, + pos: Cell::new(filemap.start_pos), + last_pos: Cell::new(filemap.start_pos), + col: Cell::new(CharPos(0)), + curr: Cell::new(initial_char), filemap: filemap, /* dummy values; not read */ - peek_tok: token::EOF, - peek_span: codemap::DUMMY_SP + peek_tok: RefCell::new(token::EOF), + peek_span: RefCell::new(codemap::DUMMY_SP), }; bump(r); return r; @@ -89,78 +90,84 @@ pub fn new_low_level_string_reader(span_diagnostic: @mut SpanHandler, // duplicating the string reader is probably a bad idea, in // that using them will cause interleaved pushes of line // offsets to the underlying filemap... -fn dup_string_reader(r: @mut StringReader) -> @mut StringReader { - @mut StringReader { +fn dup_string_reader(r: @StringReader) -> @StringReader { + @StringReader { span_diagnostic: r.span_diagnostic, src: r.src, - pos: r.pos, - last_pos: r.last_pos, - col: r.col, - curr: r.curr, + pos: Cell::new(r.pos.get()), + last_pos: Cell::new(r.last_pos.get()), + col: Cell::new(r.col.get()), + curr: Cell::new(r.curr.get()), filemap: r.filemap, peek_tok: r.peek_tok.clone(), - peek_span: r.peek_span + peek_span: r.peek_span.clone(), } } impl reader for StringReader { - fn is_eof(@mut self) -> bool { is_eof(self) } + fn is_eof(@self) -> bool { is_eof(self) } // return the next token. EFFECT: advances the string_reader. - fn next_token(@mut self) -> TokenAndSpan { - let ret_val = TokenAndSpan { - tok: util::replace(&mut self.peek_tok, token::UNDERSCORE), - sp: self.peek_span, + fn next_token(@self) -> TokenAndSpan { + let ret_val = { + let mut peek_tok = self.peek_tok.borrow_mut(); + TokenAndSpan { + tok: util::replace(peek_tok.get(), token::UNDERSCORE), + sp: self.peek_span.get(), + } }; string_advance_token(self); ret_val } - fn fatal(@mut self, m: ~str) -> ! { - self.span_diagnostic.span_fatal(self.peek_span, m) + fn fatal(@self, m: ~str) -> ! { + self.span_diagnostic.span_fatal(self.peek_span.get(), m) } - fn span_diag(@mut self) -> @mut SpanHandler { self.span_diagnostic } - fn peek(@mut self) -> TokenAndSpan { + fn span_diag(@self) -> @SpanHandler { self.span_diagnostic } + fn peek(@self) -> TokenAndSpan { // XXX(pcwalton): Bad copy! TokenAndSpan { - tok: self.peek_tok.clone(), - sp: self.peek_span, + tok: self.peek_tok.get(), + sp: self.peek_span.get(), } } - fn dup(@mut self) -> @mut reader { dup_string_reader(self) as @mut reader } + fn dup(@self) -> @reader { dup_string_reader(self) as @reader } } impl reader for TtReader { - fn is_eof(@mut self) -> bool { self.cur_tok == token::EOF } - fn next_token(@mut self) -> TokenAndSpan { + fn is_eof(@self) -> bool { + let cur_tok = self.cur_tok.borrow(); + *cur_tok.get() == token::EOF + } + fn next_token(@self) -> TokenAndSpan { let r = tt_next_token(self); debug!("TtReader: r={:?}", r); return r; } - fn fatal(@mut self, m: ~str) -> ! { - self.sp_diag.span_fatal(self.cur_span, m); + fn fatal(@self, m: ~str) -> ! { + self.sp_diag.span_fatal(self.cur_span.get(), m); } - fn span_diag(@mut self) -> @mut SpanHandler { self.sp_diag } - fn peek(@mut self) -> TokenAndSpan { + fn span_diag(@self) -> @SpanHandler { self.sp_diag } + fn peek(@self) -> TokenAndSpan { TokenAndSpan { - tok: self.cur_tok.clone(), - sp: self.cur_span, + tok: self.cur_tok.get(), + sp: self.cur_span.get(), } } - fn dup(@mut self) -> @mut reader { dup_tt_reader(self) as @mut reader } + fn dup(@self) -> @reader { dup_tt_reader(self) as @reader } } // report a lexical error spanning [`from_pos`, `to_pos`) -fn fatal_span(rdr: @mut StringReader, +fn fatal_span(rdr: @StringReader, from_pos: BytePos, to_pos: BytePos, m: ~str) -> ! { - rdr.peek_span = codemap::mk_sp(from_pos, to_pos); + rdr.peek_span.set(codemap::mk_sp(from_pos, to_pos)); rdr.fatal(m); } // report a lexical error spanning [`from_pos`, `to_pos`), appending an // escaped character to the error message -fn fatal_span_char(rdr: @mut StringReader, +fn fatal_span_char(rdr: @StringReader, from_pos: BytePos, to_pos: BytePos, m: ~str, @@ -174,7 +181,7 @@ fn fatal_span_char(rdr: @mut StringReader, // report a lexical error spanning [`from_pos`, `to_pos`), appending the // offending string to the error message -fn fatal_span_verbose(rdr: @mut StringReader, +fn fatal_span_verbose(rdr: @StringReader, from_pos: BytePos, to_pos: BytePos, m: ~str) @@ -190,19 +197,20 @@ fn fatal_span_verbose(rdr: @mut StringReader, // EFFECT: advance peek_tok and peek_span to refer to the next token. // EFFECT: update the interner, maybe. -fn string_advance_token(r: @mut StringReader) { +fn string_advance_token(r: @StringReader) { match (consume_whitespace_and_comments(r)) { Some(comment) => { - r.peek_span = comment.sp; - r.peek_tok = comment.tok; + r.peek_span.set(comment.sp); + r.peek_tok.set(comment.tok); }, None => { if is_eof(r) { - r.peek_tok = token::EOF; + r.peek_tok.set(token::EOF); } else { - let start_bytepos = r.last_pos; - r.peek_tok = next_token_inner(r); - r.peek_span = codemap::mk_sp(start_bytepos, r.last_pos); + let start_bytepos = r.last_pos.get(); + r.peek_tok.set(next_token_inner(r)); + r.peek_span.set(codemap::mk_sp(start_bytepos, + r.last_pos.get())); }; } } @@ -216,17 +224,17 @@ fn byte_offset(rdr: &StringReader, pos: BytePos) -> BytePos { /// up to but excluding `rdr.last_pos`, meaning the slice does not include /// the character `rdr.curr`. pub fn with_str_from<T>( - rdr: @mut StringReader, + rdr: @StringReader, start: BytePos, f: |s: &str| -> T) -> T { - with_str_from_to(rdr, start, rdr.last_pos, f) + with_str_from_to(rdr, start, rdr.last_pos.get(), f) } /// Calls `f` with astring slice of the source text spanning from `start` /// up to but excluding `end`. fn with_str_from_to<T>( - rdr: @mut StringReader, + rdr: @StringReader, start: BytePos, end: BytePos, f: |s: &str| -> T) @@ -238,20 +246,22 @@ fn with_str_from_to<T>( // EFFECT: advance the StringReader by one character. If a newline is // discovered, add it to the FileMap's list of line start offsets. -pub fn bump(rdr: &mut StringReader) { - rdr.last_pos = rdr.pos; - let current_byte_offset = byte_offset(rdr, rdr.pos).to_uint(); +pub fn bump(rdr: &StringReader) { + rdr.last_pos.set(rdr.pos.get()); + let current_byte_offset = byte_offset(rdr, rdr.pos.get()).to_uint(); if current_byte_offset < (rdr.src).len() { - assert!(rdr.curr != unsafe { transmute(-1u32) }); // FIXME: #8971: unsound - let last_char = rdr.curr; + assert!(rdr.curr.get() != unsafe { + transmute(-1u32) + }); // FIXME: #8971: unsound + let last_char = rdr.curr.get(); let next = rdr.src.char_range_at(current_byte_offset); let byte_offset_diff = next.next - current_byte_offset; - rdr.pos = rdr.pos + Pos::from_uint(byte_offset_diff); - rdr.curr = next.ch; - rdr.col = rdr.col + CharPos(1u); + rdr.pos.set(rdr.pos.get() + Pos::from_uint(byte_offset_diff)); + rdr.curr.set(next.ch); + rdr.col.set(rdr.col.get() + CharPos(1u)); if last_char == '\n' { - rdr.filemap.next_line(rdr.last_pos); - rdr.col = CharPos(0u); + rdr.filemap.next_line(rdr.last_pos.get()); + rdr.col.set(CharPos(0u)); } if byte_offset_diff > 1 { @@ -259,14 +269,14 @@ pub fn bump(rdr: &mut StringReader) { Pos::from_uint(current_byte_offset), byte_offset_diff); } } else { - rdr.curr = unsafe { transmute(-1u32) }; // FIXME: #8971: unsound + rdr.curr.set(unsafe { transmute(-1u32) }); // FIXME: #8971: unsound } } -pub fn is_eof(rdr: @mut StringReader) -> bool { - rdr.curr == unsafe { transmute(-1u32) } // FIXME: #8971: unsound +pub fn is_eof(rdr: @StringReader) -> bool { + rdr.curr.get() == unsafe { transmute(-1u32) } // FIXME: #8971: unsound } -pub fn nextch(rdr: @mut StringReader) -> char { - let offset = byte_offset(rdr, rdr.pos).to_uint(); +pub fn nextch(rdr: @StringReader) -> char { + let offset = byte_offset(rdr, rdr.pos.get()).to_uint(); if offset < (rdr.src).len() { return rdr.src.char_at(offset); } else { return unsafe { transmute(-1u32) }; } // FIXME: #8971: unsound @@ -296,9 +306,9 @@ fn is_hex_digit(c: char) -> bool { // EFFECT: eats whitespace and comments. // returns a Some(sugared-doc-attr) if one exists, None otherwise. -fn consume_whitespace_and_comments(rdr: @mut StringReader) +fn consume_whitespace_and_comments(rdr: @StringReader) -> Option<TokenAndSpan> { - while is_whitespace(rdr.curr) { bump(rdr); } + while is_whitespace(rdr.curr.get()) { bump(rdr); } return consume_any_line_comment(rdr); } @@ -309,17 +319,17 @@ pub fn is_line_non_doc_comment(s: &str) -> bool { // PRECONDITION: rdr.curr is not whitespace // EFFECT: eats any kind of comment. // returns a Some(sugared-doc-attr) if one exists, None otherwise -fn consume_any_line_comment(rdr: @mut StringReader) +fn consume_any_line_comment(rdr: @StringReader) -> Option<TokenAndSpan> { - if rdr.curr == '/' { + if rdr.curr.get() == '/' { match nextch(rdr) { '/' => { bump(rdr); bump(rdr); // line comments starting with "///" or "//!" are doc-comments - if rdr.curr == '/' || rdr.curr == '!' { - let start_bpos = rdr.pos - BytePos(3); - while rdr.curr != '\n' && !is_eof(rdr) { + if rdr.curr.get() == '/' || rdr.curr.get() == '!' { + let start_bpos = rdr.pos.get() - BytePos(3); + while rdr.curr.get() != '\n' && !is_eof(rdr) { bump(rdr); } let ret = with_str_from(rdr, start_bpos, |string| { @@ -327,7 +337,7 @@ fn consume_any_line_comment(rdr: @mut StringReader) if !is_line_non_doc_comment(string) { Some(TokenAndSpan{ tok: token::DOC_COMMENT(str_to_ident(string)), - sp: codemap::mk_sp(start_bpos, rdr.pos) + sp: codemap::mk_sp(start_bpos, rdr.pos.get()) }) } else { None @@ -338,7 +348,7 @@ fn consume_any_line_comment(rdr: @mut StringReader) return ret; } } else { - while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); } + while rdr.curr.get() != '\n' && !is_eof(rdr) { bump(rdr); } } // Restart whitespace munch. return consume_whitespace_and_comments(rdr); @@ -346,15 +356,18 @@ fn consume_any_line_comment(rdr: @mut StringReader) '*' => { bump(rdr); bump(rdr); return consume_block_comment(rdr); } _ => () } - } else if rdr.curr == '#' { + } else if rdr.curr.get() == '#' { if nextch(rdr) == '!' { // I guess this is the only way to figure out if // we're at the beginning of the file... let cmap = @CodeMap::new(); - (*cmap).files.push(rdr.filemap); - let loc = cmap.lookup_char_pos_adj(rdr.last_pos); + { + let mut files = cmap.files.borrow_mut(); + files.get().push(rdr.filemap); + } + let loc = cmap.lookup_char_pos_adj(rdr.last_pos.get()); if loc.line == 1u && loc.col == CharPos(0u) { - while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); } + while rdr.curr.get() != '\n' && !is_eof(rdr) { bump(rdr); } return consume_whitespace_and_comments(rdr); } } @@ -367,11 +380,10 @@ pub fn is_block_non_doc_comment(s: &str) -> bool { } // might return a sugared-doc-attr -fn consume_block_comment(rdr: @mut StringReader) - -> Option<TokenAndSpan> { +fn consume_block_comment(rdr: @StringReader) -> Option<TokenAndSpan> { // block comments starting with "/**" or "/*!" are doc-comments - let is_doc_comment = rdr.curr == '*' || rdr.curr == '!'; - let start_bpos = rdr.pos - BytePos(if is_doc_comment {3} else {2}); + let is_doc_comment = rdr.curr.get() == '*' || rdr.curr.get() == '!'; + let start_bpos = rdr.pos.get() - BytePos(if is_doc_comment {3} else {2}); let mut level: int = 1; while level > 0 { @@ -381,12 +393,12 @@ fn consume_block_comment(rdr: @mut StringReader) } else { ~"unterminated block comment" }; - fatal_span(rdr, start_bpos, rdr.last_pos, msg); - } else if rdr.curr == '/' && nextch(rdr) == '*' { + fatal_span(rdr, start_bpos, rdr.last_pos.get(), msg); + } else if rdr.curr.get() == '/' && nextch(rdr) == '*' { level += 1; bump(rdr); bump(rdr); - } else if rdr.curr == '*' && nextch(rdr) == '/' { + } else if rdr.curr.get() == '*' && nextch(rdr) == '/' { level -= 1; bump(rdr); bump(rdr); @@ -401,7 +413,7 @@ fn consume_block_comment(rdr: @mut StringReader) if !is_block_non_doc_comment(string) { Some(TokenAndSpan{ tok: token::DOC_COMMENT(str_to_ident(string)), - sp: codemap::mk_sp(start_bpos, rdr.pos) + sp: codemap::mk_sp(start_bpos, rdr.pos.get()) }) } else { None @@ -415,13 +427,13 @@ fn consume_block_comment(rdr: @mut StringReader) if res.is_some() { res } else { consume_whitespace_and_comments(rdr) } } -fn scan_exponent(rdr: @mut StringReader, start_bpos: BytePos) -> Option<~str> { - let mut c = rdr.curr; +fn scan_exponent(rdr: @StringReader, start_bpos: BytePos) -> Option<~str> { + let mut c = rdr.curr.get(); let mut rslt = ~""; if c == 'e' || c == 'E' { rslt.push_char(c); bump(rdr); - c = rdr.curr; + c = rdr.curr.get(); if c == '-' || c == '+' { rslt.push_char(c); bump(rdr); @@ -430,16 +442,16 @@ fn scan_exponent(rdr: @mut StringReader, start_bpos: BytePos) -> Option<~str> { if exponent.len() > 0u { return Some(rslt + exponent); } else { - fatal_span(rdr, start_bpos, rdr.last_pos, + fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"scan_exponent: bad fp literal"); } } else { return None::<~str>; } } -fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str { +fn scan_digits(rdr: @StringReader, radix: uint) -> ~str { let mut rslt = ~""; loop { - let c = rdr.curr; + let c = rdr.curr.get(); if c == '_' { bump(rdr); continue; } match char::to_digit(c, radix) { Some(_) => { @@ -451,12 +463,12 @@ fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str { }; } -fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { +fn scan_number(c: char, rdr: @StringReader) -> token::Token { let mut num_str; let mut base = 10u; let mut c = c; let mut n = nextch(rdr); - let start_bpos = rdr.last_pos; + let start_bpos = rdr.last_pos.get(); if c == '0' && n == 'x' { bump(rdr); bump(rdr); @@ -471,7 +483,7 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { base = 2u; } num_str = scan_digits(rdr, base); - c = rdr.curr; + c = rdr.curr.get(); nextch(rdr); if c == 'u' || c == 'i' { enum Result { Signed(ast::int_ty), Unsigned(ast::uint_ty) } @@ -481,7 +493,7 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { else { Unsigned(ast::ty_u) } }; bump(rdr); - c = rdr.curr; + c = rdr.curr.get(); if c == '8' { bump(rdr); tp = if signed { Signed(ast::ty_i8) } @@ -505,12 +517,12 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { else { Unsigned(ast::ty_u64) }; } if num_str.len() == 0u { - fatal_span(rdr, start_bpos, rdr.last_pos, + fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"no valid digits found for number"); } let parsed = match from_str_radix::<u64>(num_str, base as uint) { Some(p) => p, - None => fatal_span(rdr, start_bpos, rdr.last_pos, + None => fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"int literal is too large") }; @@ -520,7 +532,8 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { } } let mut is_float = false; - if rdr.curr == '.' && !(ident_start(nextch(rdr)) || nextch(rdr) == '.') { + if rdr.curr.get() == '.' && !(ident_start(nextch(rdr)) || nextch(rdr) == + '.') { is_float = true; bump(rdr); let dec_part = scan_digits(rdr, 10u); @@ -529,11 +542,11 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { } if is_float { match base { - 16u => fatal_span(rdr, start_bpos, rdr.last_pos, + 16u => fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"hexadecimal float literal is not supported"), - 8u => fatal_span(rdr, start_bpos, rdr.last_pos, + 8u => fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"octal float literal is not supported"), - 2u => fatal_span(rdr, start_bpos, rdr.last_pos, + 2u => fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"binary float literal is not supported"), _ => () } @@ -546,9 +559,9 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { None => () } - if rdr.curr == 'f' { + if rdr.curr.get() == 'f' { bump(rdr); - c = rdr.curr; + c = rdr.curr.get(); n = nextch(rdr); if c == '3' && n == '2' { bump(rdr); @@ -564,19 +577,20 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { 32-bit or 64-bit float, it won't be noticed till the back-end. */ } else { - fatal_span(rdr, start_bpos, rdr.last_pos, ~"expected `f32` or `f64` suffix"); + fatal_span(rdr, start_bpos, rdr.last_pos.get(), + ~"expected `f32` or `f64` suffix"); } } if is_float { return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(num_str)); } else { if num_str.len() == 0u { - fatal_span(rdr, start_bpos, rdr.last_pos, + fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"no valid digits found for number"); } let parsed = match from_str_radix::<u64>(num_str, base as uint) { Some(p) => p, - None => fatal_span(rdr, start_bpos, rdr.last_pos, + None => fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"int literal is too large") }; @@ -585,14 +599,14 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { } } -fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char { +fn scan_numeric_escape(rdr: @StringReader, n_hex_digits: uint) -> char { let mut accum_int = 0; let mut i = n_hex_digits; - let start_bpos = rdr.last_pos; + let start_bpos = rdr.last_pos.get(); while i != 0u { - let n = rdr.curr; + let n = rdr.curr.get(); if !is_hex_digit(n) { - fatal_span_char(rdr, rdr.last_pos, rdr.pos, + fatal_span_char(rdr, rdr.last_pos.get(), rdr.pos.get(), ~"illegal character in numeric character escape", n); } @@ -603,7 +617,7 @@ fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char { } match char::from_u32(accum_int as u32) { Some(x) => x, - None => fatal_span(rdr, start_bpos, rdr.last_pos, + None => fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"illegal numeric character escape") } } @@ -626,14 +640,14 @@ fn ident_continue(c: char) -> bool { // return the next token from the string // EFFECT: advances the input past that token // EFFECT: updates the interner -fn next_token_inner(rdr: @mut StringReader) -> token::Token { - let c = rdr.curr; +fn next_token_inner(rdr: @StringReader) -> token::Token { + let c = rdr.curr.get(); if ident_start(c) && nextch(rdr) != '"' && nextch(rdr) != '#' { // Note: r as in r" or r#" is part of a raw string literal, // not an identifier, and is handled further down. - let start = rdr.last_pos; - while ident_continue(rdr.curr) { + let start = rdr.last_pos.get(); + while ident_continue(rdr.curr.get()) { bump(rdr); } @@ -641,7 +655,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { if string == "_" { token::UNDERSCORE } else { - let is_mod_name = rdr.curr == ':' && nextch(rdr) == ':'; + let is_mod_name = rdr.curr.get() == ':' && nextch(rdr) == ':'; // FIXME: perform NFKC normalization here. (Issue #2253) token::IDENT(str_to_ident(string), is_mod_name) @@ -651,9 +665,9 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { if is_dec_digit(c) { return scan_number(c, rdr); } - fn binop(rdr: @mut StringReader, op: token::binop) -> token::Token { + fn binop(rdr: @StringReader, op: token::binop) -> token::Token { bump(rdr); - if rdr.curr == '=' { + if rdr.curr.get() == '=' { bump(rdr); return token::BINOPEQ(op); } else { return token::BINOP(op); } @@ -669,9 +683,9 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { ',' => { bump(rdr); return token::COMMA; } '.' => { bump(rdr); - return if rdr.curr == '.' { + return if rdr.curr.get() == '.' { bump(rdr); - if rdr.curr == '.' { + if rdr.curr.get() == '.' { bump(rdr); token::DOTDOTDOT } else { @@ -692,7 +706,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { '~' => { bump(rdr); return token::TILDE; } ':' => { bump(rdr); - if rdr.curr == ':' { + if rdr.curr.get() == ':' { bump(rdr); return token::MOD_SEP; } else { return token::COLON; } @@ -707,10 +721,10 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { // Multi-byte tokens. '=' => { bump(rdr); - if rdr.curr == '=' { + if rdr.curr.get() == '=' { bump(rdr); return token::EQEQ; - } else if rdr.curr == '>' { + } else if rdr.curr.get() == '>' { bump(rdr); return token::FAT_ARROW; } else { @@ -719,19 +733,19 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { } '!' => { bump(rdr); - if rdr.curr == '=' { + if rdr.curr.get() == '=' { bump(rdr); return token::NE; } else { return token::NOT; } } '<' => { bump(rdr); - match rdr.curr { + match rdr.curr.get() { '=' => { bump(rdr); return token::LE; } '<' => { return binop(rdr, token::SHL); } '-' => { bump(rdr); - match rdr.curr { + match rdr.curr.get() { '>' => { bump(rdr); return token::DARROW; } _ => { return token::LARROW; } } @@ -741,7 +755,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { } '>' => { bump(rdr); - match rdr.curr { + match rdr.curr.get() { '=' => { bump(rdr); return token::GE; } '>' => { return binop(rdr, token::SHR); } _ => { return token::GT; } @@ -750,14 +764,14 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { '\'' => { // Either a character constant 'a' OR a lifetime name 'abc bump(rdr); - let start = rdr.last_pos; - let mut c2 = rdr.curr; + let start = rdr.last_pos.get(); + let mut c2 = rdr.curr.get(); bump(rdr); // If the character is an ident start not followed by another single // quote, then this is a lifetime name: - if ident_start(c2) && rdr.curr != '\'' { - while ident_continue(rdr.curr) { + if ident_start(c2) && rdr.curr.get() != '\'' { + while ident_continue(rdr.curr.get()) { bump(rdr); } return with_str_from(rdr, start, |lifetime_name| { @@ -765,11 +779,12 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { let tok = &token::IDENT(ident, false); if token::is_keyword(token::keywords::Self, tok) { - fatal_span(rdr, start, rdr.last_pos, + fatal_span(rdr, start, rdr.last_pos.get(), ~"invalid lifetime name: 'self is no longer a special lifetime"); } else if token::is_any_keyword(tok) && !token::is_keyword(token::keywords::Static, tok) { - fatal_span(rdr, start, rdr.last_pos, ~"invalid lifetime name"); + fatal_span(rdr, start, rdr.last_pos.get(), + ~"invalid lifetime name"); } else { token::LIFETIME(ident) } @@ -780,8 +795,8 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { match c2 { '\\' => { // '\X' for some X must be a character constant: - let escaped = rdr.curr; - let escaped_pos = rdr.last_pos; + let escaped = rdr.curr.get(); + let escaped_pos = rdr.last_pos.get(); bump(rdr); match escaped { 'n' => { c2 = '\n'; } @@ -795,24 +810,24 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { 'u' => { c2 = scan_numeric_escape(rdr, 4u); } 'U' => { c2 = scan_numeric_escape(rdr, 8u); } c2 => { - fatal_span_char(rdr, escaped_pos, rdr.last_pos, + fatal_span_char(rdr, escaped_pos, rdr.last_pos.get(), ~"unknown character escape", c2); } } } '\t' | '\n' | '\r' | '\'' => { - fatal_span_char(rdr, start, rdr.last_pos, + fatal_span_char(rdr, start, rdr.last_pos.get(), ~"character constant must be escaped", c2); } _ => {} } - if rdr.curr != '\'' { + if rdr.curr.get() != '\'' { fatal_span_verbose(rdr, // Byte offsetting here is okay because the // character before position `start` is an // ascii single quote. start - BytePos(1), - rdr.last_pos, + rdr.last_pos.get(), ~"unterminated character constant"); } bump(rdr); // advance curr past token @@ -820,20 +835,20 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { } '"' => { let mut accum_str = ~""; - let start_bpos = rdr.last_pos; + let start_bpos = rdr.last_pos.get(); bump(rdr); - while rdr.curr != '"' { + while rdr.curr.get() != '"' { if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos, + fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"unterminated double quote string"); } - let ch = rdr.curr; + let ch = rdr.curr.get(); bump(rdr); match ch { '\\' => { - let escaped = rdr.curr; - let escaped_pos = rdr.last_pos; + let escaped = rdr.curr.get(); + let escaped_pos = rdr.last_pos.get(); bump(rdr); match escaped { 'n' => accum_str.push_char('\n'), @@ -854,7 +869,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { accum_str.push_char(scan_numeric_escape(rdr, 8u)); } c2 => { - fatal_span_char(rdr, escaped_pos, rdr.last_pos, + fatal_span_char(rdr, escaped_pos, rdr.last_pos.get(), ~"unknown string escape", c2); } } @@ -866,32 +881,32 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { return token::LIT_STR(str_to_ident(accum_str)); } 'r' => { - let start_bpos = rdr.last_pos; + let start_bpos = rdr.last_pos.get(); bump(rdr); let mut hash_count = 0u; - while rdr.curr == '#' { + while rdr.curr.get() == '#' { bump(rdr); hash_count += 1; } - if rdr.curr != '"' { - fatal_span_char(rdr, start_bpos, rdr.last_pos, + if rdr.curr.get() != '"' { + fatal_span_char(rdr, start_bpos, rdr.last_pos.get(), ~"only `#` is allowed in raw string delimitation; \ found illegal character", - rdr.curr); + rdr.curr.get()); } bump(rdr); - let content_start_bpos = rdr.last_pos; + let content_start_bpos = rdr.last_pos.get(); let mut content_end_bpos; 'outer: loop { if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos, + fatal_span(rdr, start_bpos, rdr.last_pos.get(), ~"unterminated raw string"); } - if rdr.curr == '"' { - content_end_bpos = rdr.last_pos; + if rdr.curr.get() == '"' { + content_end_bpos = rdr.last_pos.get(); for _ in range(0, hash_count) { bump(rdr); - if rdr.curr != '#' { + if rdr.curr.get() != '#' { continue 'outer; } } @@ -932,14 +947,14 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { '^' => { return binop(rdr, token::CARET); } '%' => { return binop(rdr, token::PERCENT); } c => { - fatal_span_char(rdr, rdr.last_pos, rdr.pos, + fatal_span_char(rdr, rdr.last_pos.get(), rdr.pos.get(), ~"unknown start of token", c); } } } -fn consume_whitespace(rdr: @mut StringReader) { - while is_whitespace(rdr.curr) && !is_eof(rdr) { bump(rdr); } +fn consume_whitespace(rdr: @StringReader) { + while is_whitespace(rdr.curr.get()) && !is_eof(rdr) { bump(rdr); } } #[cfg(test)] @@ -953,7 +968,7 @@ mod test { // represents a testing reader (incl. both reader and interner) struct Env { - string_reader: @mut StringReader + string_reader: @StringReader } // open a string reader for the given string @@ -978,7 +993,7 @@ mod test { sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; assert_eq!(tok1,tok2); // the 'main' id is already read: - assert_eq!(string_reader.last_pos.clone(), BytePos(28)); + assert_eq!(string_reader.last_pos.get().clone(), BytePos(28)); // read another token: let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan{ @@ -986,7 +1001,7 @@ mod test { sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; assert_eq!(tok3,tok4); // the lparen is already read: - assert_eq!(string_reader.last_pos.clone(), BytePos(29)) + assert_eq!(string_reader.last_pos.get().clone(), BytePos(29)) } // check that the given reader produces the desired stream diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 5a8444518aa..c20e7f4aaec 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -19,6 +19,7 @@ use parse::attr::parser_attr; use parse::lexer::reader; use parse::parser::Parser; +use std::cell::RefCell; use std::io; use std::io::File; use std::str; @@ -41,27 +42,27 @@ pub mod obsolete; // info about a parsing session. pub struct ParseSess { cm: @codemap::CodeMap, // better be the same as the one in the reader! - span_diagnostic: @mut SpanHandler, // better be the same as the one in the reader! + span_diagnostic: @SpanHandler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions - included_mod_stack: ~[Path], + included_mod_stack: RefCell<~[Path]>, } -pub fn new_parse_sess(demitter: Option<@Emitter>) -> @mut ParseSess { +pub fn new_parse_sess(demitter: Option<@Emitter>) -> @ParseSess { let cm = @CodeMap::new(); - @mut ParseSess { + @ParseSess { cm: cm, span_diagnostic: mk_span_handler(mk_handler(demitter), cm), - included_mod_stack: ~[], + included_mod_stack: RefCell::new(~[]), } } -pub fn new_parse_sess_special_handler(sh: @mut SpanHandler, +pub fn new_parse_sess_special_handler(sh: @SpanHandler, cm: @codemap::CodeMap) - -> @mut ParseSess { - @mut ParseSess { + -> @ParseSess { + @ParseSess { cm: cm, span_diagnostic: sh, - included_mod_stack: ~[], + included_mod_stack: RefCell::new(~[]), } } @@ -73,7 +74,7 @@ pub fn new_parse_sess_special_handler(sh: @mut SpanHandler, pub fn parse_crate_from_file( input: &Path, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ast::Crate { new_parser_from_file(sess, /*bad*/ cfg.clone(), input).parse_crate_mod() // why is there no p.abort_if_errors here? @@ -82,7 +83,7 @@ pub fn parse_crate_from_file( pub fn parse_crate_attrs_from_file( input: &Path, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ~[ast::Attribute] { let mut parser = new_parser_from_file(sess, cfg, input); let (inner, _) = parser.parse_inner_attrs_and_next(); @@ -93,7 +94,7 @@ pub fn parse_crate_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ast::Crate { let mut p = new_parser_from_source_str(sess, /*bad*/ cfg.clone(), @@ -106,7 +107,7 @@ pub fn parse_crate_attrs_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ~[ast::Attribute] { let mut p = new_parser_from_source_str(sess, /*bad*/ cfg.clone(), @@ -120,7 +121,7 @@ pub fn parse_expr_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> @ast::Expr { let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_expr(), p) @@ -131,7 +132,7 @@ pub fn parse_item_from_source_str( source: @str, cfg: ast::CrateConfig, attrs: ~[ast::Attribute], - sess: @mut ParseSess + sess: @ParseSess ) -> Option<@ast::item> { let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_item(attrs),p) @@ -141,7 +142,7 @@ pub fn parse_meta_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> @ast::MetaItem { let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_meta_item(),p) @@ -152,7 +153,7 @@ pub fn parse_stmt_from_source_str( source: @str, cfg: ast::CrateConfig, attrs: ~[ast::Attribute], - sess: @mut ParseSess + sess: @ParseSess ) -> @ast::Stmt { let mut p = new_parser_from_source_str( sess, @@ -167,7 +168,7 @@ pub fn parse_tts_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ~[ast::token_tree] { let mut p = new_parser_from_source_str( sess, @@ -191,7 +192,7 @@ pub fn parse_from_source_str<T>( ss: codemap::FileSubstr, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess) + sess: @ParseSess) -> T { let mut p = new_parser_from_source_substr(sess, cfg, name, ss, source); let r = f(&mut p); @@ -202,7 +203,7 @@ pub fn parse_from_source_str<T>( } // Create a new parser from a source string -pub fn new_parser_from_source_str(sess: @mut ParseSess, +pub fn new_parser_from_source_str(sess: @ParseSess, cfg: ast::CrateConfig, name: @str, source: @str) @@ -212,7 +213,7 @@ pub fn new_parser_from_source_str(sess: @mut ParseSess, // Create a new parser from a source string where the origin // is specified as a substring of another file. -pub fn new_parser_from_source_substr(sess: @mut ParseSess, +pub fn new_parser_from_source_substr(sess: @ParseSess, cfg: ast::CrateConfig, name: @str, ss: codemap::FileSubstr, @@ -224,7 +225,7 @@ pub fn new_parser_from_source_substr(sess: @mut ParseSess, /// Create a new parser, handling errors as appropriate /// if the file doesn't exist pub fn new_parser_from_file( - sess: @mut ParseSess, + sess: @ParseSess, cfg: ast::CrateConfig, path: &Path ) -> Parser { @@ -235,7 +236,7 @@ pub fn new_parser_from_file( /// the file at the given path to the codemap, and return a parser. /// On an error, use the given span as the source of the problem. pub fn new_sub_parser_from_file( - sess: @mut ParseSess, + sess: @ParseSess, cfg: ast::CrateConfig, path: &Path, sp: Span @@ -244,7 +245,7 @@ pub fn new_sub_parser_from_file( } /// Given a filemap and config, return a parser -pub fn filemap_to_parser(sess: @mut ParseSess, +pub fn filemap_to_parser(sess: @ParseSess, filemap: @FileMap, cfg: ast::CrateConfig) -> Parser { tts_to_parser(sess,filemap_to_tts(sess,filemap),cfg) @@ -252,7 +253,7 @@ pub fn filemap_to_parser(sess: @mut ParseSess, // must preserve old name for now, because quote! from the *existing* // compiler expands into it -pub fn new_parser_from_tts(sess: @mut ParseSess, +pub fn new_parser_from_tts(sess: @ParseSess, cfg: ast::CrateConfig, tts: ~[ast::token_tree]) -> Parser { tts_to_parser(sess,tts,cfg) @@ -263,7 +264,7 @@ pub fn new_parser_from_tts(sess: @mut ParseSess, /// Given a session and a path and an optional span (for error reporting), /// add the path to the session's codemap and return the new filemap. -pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option<Span>) +pub fn file_to_filemap(sess: @ParseSess, path: &Path, spanopt: Option<Span>) -> @FileMap { let err = |msg: &str| { match spanopt { @@ -292,35 +293,35 @@ pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option<Span>) // given a session and a string, add the string to // the session's codemap and return the new filemap -pub fn string_to_filemap(sess: @mut ParseSess, source: @str, path: @str) +pub fn string_to_filemap(sess: @ParseSess, source: @str, path: @str) -> @FileMap { sess.cm.new_filemap(path, source) } // given a session and a string and a path and a FileSubStr, add // the string to the CodeMap and return the new FileMap -pub fn substring_to_filemap(sess: @mut ParseSess, source: @str, path: @str, +pub fn substring_to_filemap(sess: @ParseSess, source: @str, path: @str, filesubstr: FileSubstr) -> @FileMap { sess.cm.new_filemap_w_substr(path,filesubstr,source) } // given a filemap, produce a sequence of token-trees -pub fn filemap_to_tts(sess: @mut ParseSess, filemap: @FileMap) +pub fn filemap_to_tts(sess: @ParseSess, filemap: @FileMap) -> ~[ast::token_tree] { // it appears to me that the cfg doesn't matter here... indeed, // parsing tt's probably shouldn't require a parser at all. let cfg = ~[]; let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap); - let mut p1 = Parser(sess, cfg, srdr as @mut reader); + let mut p1 = Parser(sess, cfg, srdr as @reader); p1.parse_all_token_trees() } // given tts and cfg, produce a parser -pub fn tts_to_parser(sess: @mut ParseSess, +pub fn tts_to_parser(sess: @ParseSess, tts: ~[ast::token_tree], cfg: ast::CrateConfig) -> Parser { let trdr = lexer::new_tt_reader(sess.span_diagnostic, None, tts); - Parser(sess, cfg, trdr as @mut reader) + Parser(sess, cfg, trdr as @reader) } // abort if necessary diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2428710087f..40a2ef86e4f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -29,8 +29,7 @@ use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex}; use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc, ExprRepeat}; use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary}; -use ast::{ExprVec, ExprVstore, ExprVstoreMutBox}; -use ast::{ExprVstoreSlice, ExprVstoreBox}; +use ast::{ExprVec, ExprVstore, ExprVstoreSlice, ExprVstoreBox}; use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, extern_fn, Field, fn_decl}; use ast::{ExprVstoreUniq, Onceness, Once, Many}; use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod}; @@ -81,6 +80,7 @@ use parse::{new_sub_parser_from_file, ParseSess}; use opt_vec; use opt_vec::OptVec; +use std::cell::Cell; use std::hashmap::HashSet; use std::util; use std::vec; @@ -286,8 +286,8 @@ struct ParsedItemsAndViewItems { /* ident is handled by common.rs */ -pub fn Parser(sess: @mut ParseSess, cfg: ast::CrateConfig, rdr: @mut reader) - -> Parser { +pub fn Parser(sess: @ParseSess, cfg: ast::CrateConfig, rdr: @reader) + -> Parser { let tok0 = rdr.next_token(); let interner = get_ident_interner(); let span = tok0.sp; @@ -324,7 +324,7 @@ pub fn Parser(sess: @mut ParseSess, cfg: ast::CrateConfig, rdr: @mut reader) } pub struct Parser { - sess: @mut ParseSess, + sess: @ParseSess, cfg: CrateConfig, // the current token: token: token::Token, @@ -340,7 +340,7 @@ pub struct Parser { tokens_consumed: uint, restriction: restriction, quote_depth: uint, // not (yet) related to the quasiquoter - reader: @mut reader, + reader: @reader, interner: @token::ident_interner, /// The set of seen errors about obsolete syntax. Used to suppress /// extra detail when the same error is seen twice @@ -1299,7 +1299,7 @@ impl Parser { if sigil == OwnedSigil { ty_uniq(self.parse_ty(false)) } else { - ty_box(self.parse_mt()) + ty_box(self.parse_ty(false)) } } @@ -2185,7 +2185,7 @@ impl Parser { // unification of matchers and token_trees would vastly improve // the interpolation of matchers maybe_whole!(self, nt_matchers); - let name_idx = @mut 0u; + let name_idx = @Cell::new(0u); match self.token { token::LBRACE | token::LPAREN | token::LBRACKET => { let other_delimiter = token::flip_delimiter(&self.token); @@ -2200,7 +2200,7 @@ impl Parser { // Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be // invalid. It's similar to common::parse_seq. pub fn parse_matcher_subseq_upto(&mut self, - name_idx: @mut uint, + name_idx: @Cell<uint>, ket: &token::Token) -> ~[matcher] { let mut ret_val = ~[]; @@ -2217,13 +2217,13 @@ impl Parser { return ret_val; } - pub fn parse_matcher(&mut self, name_idx: @mut uint) -> matcher { + pub fn parse_matcher(&mut self, name_idx: @Cell<uint>) -> matcher { let lo = self.span.lo; let m = if self.token == token::DOLLAR { self.bump(); if self.token == token::LPAREN { - let name_idx_lo = *name_idx; + let name_idx_lo = name_idx.get(); self.bump(); let ms = self.parse_matcher_subseq_upto(name_idx, &token::RPAREN); @@ -2231,13 +2231,13 @@ impl Parser { self.fatal("repetition body must be nonempty"); } let (sep, zerok) = self.parse_sep_and_zerok(); - match_seq(ms, sep, zerok, name_idx_lo, *name_idx) + match_seq(ms, sep, zerok, name_idx_lo, name_idx.get()) } else { let bound_to = self.parse_ident(); self.expect(&token::COLON); let nt_name = self.parse_ident(); - let m = match_nonterminal(bound_to, nt_name, *name_idx); - *name_idx += 1u; + let m = match_nonterminal(bound_to, nt_name, name_idx.get()); + name_idx.set(name_idx.get() + 1u); m } } else { @@ -2299,17 +2299,14 @@ impl Parser { } token::AT => { self.bump(); - let m = self.parse_mutability(); let e = self.parse_prefix_expr(); hi = e.span.hi; // HACK: turn @[...] into a @-evec ex = match e.node { - ExprVec(..) | ExprRepeat(..) if m == MutMutable => - ExprVstore(e, ExprVstoreMutBox), ExprVec(..) | ExprLit(@codemap::Spanned { node: lit_str(..), span: _}) | - ExprRepeat(..) if m == MutImmutable => ExprVstore(e, ExprVstoreBox), - _ => self.mk_unary(UnBox(m), e) + ExprRepeat(..) => ExprVstore(e, ExprVstoreBox), + _ => self.mk_unary(UnBox, e) }; } token::TILDE => { @@ -4264,21 +4261,28 @@ impl Parser { path: Path, outer_attrs: ~[ast::Attribute], id_sp: Span) -> (ast::item_, ~[ast::Attribute]) { - let maybe_i = self.sess.included_mod_stack.iter().position(|p| *p == path); - match maybe_i { - Some(i) => { - let stack = &self.sess.included_mod_stack; - let mut err = ~"circular modules: "; - for p in stack.slice(i, stack.len()).iter() { - p.display().with_str(|s| err.push_str(s)); - err.push_str(" -> "); + { + let mut included_mod_stack = self.sess + .included_mod_stack + .borrow_mut(); + let maybe_i = included_mod_stack.get() + .iter() + .position(|p| *p == path); + match maybe_i { + Some(i) => { + let mut err = ~"circular modules: "; + let len = included_mod_stack.get().len(); + for p in included_mod_stack.get().slice(i, len).iter() { + p.display().with_str(|s| err.push_str(s)); + err.push_str(" -> "); + } + path.display().with_str(|s| err.push_str(s)); + self.span_fatal(id_sp, err); } - path.display().with_str(|s| err.push_str(s)); - self.span_fatal(id_sp, err); + None => () } - None => () + included_mod_stack.get().push(path.clone()); } - self.sess.included_mod_stack.push(path.clone()); let mut p0 = new_sub_parser_from_file(self.sess, @@ -4289,7 +4293,12 @@ impl Parser { let mod_attrs = vec::append(outer_attrs, inner); let first_item_outer_attrs = next; let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); - self.sess.included_mod_stack.pop(); + { + let mut included_mod_stack = self.sess + .included_mod_stack + .borrow_mut(); + included_mod_stack.get().pop(); + } return (ast::item_mod(m0), mod_attrs); } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 5138115746e..a6239ab3806 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -148,7 +148,7 @@ pub struct print_stack_elt { pub static size_infinity: int = 0xffff; -pub fn mk_printer(out: @mut io::Writer, linewidth: uint) -> @mut Printer { +pub fn mk_printer(out: ~io::Writer, linewidth: uint) -> Printer { // Yes 3, it makes the ring buffers big enough to never // fall behind. let n: uint = 3 * linewidth; @@ -156,7 +156,7 @@ pub fn mk_printer(out: @mut io::Writer, linewidth: uint) -> @mut Printer { let token: ~[token] = vec::from_elem(n, EOF); let size: ~[int] = vec::from_elem(n, 0); let scan_stack: ~[uint] = vec::from_elem(n, 0u); - @mut Printer { + Printer { out: out, buf_len: n, margin: linewidth as int, @@ -171,7 +171,7 @@ pub fn mk_printer(out: @mut io::Writer, linewidth: uint) -> @mut Printer { scan_stack_empty: true, top: 0, bottom: 0, - print_stack: @mut ~[], + print_stack: ~[], pending_indentation: 0 } } @@ -255,7 +255,7 @@ pub fn mk_printer(out: @mut io::Writer, linewidth: uint) -> @mut Printer { * called 'print'. */ pub struct Printer { - out: @mut io::Writer, + out: ~io::Writer, buf_len: uint, margin: int, // width of lines we're constrained to space: int, // number of spaces left on line @@ -276,7 +276,7 @@ pub struct Printer { top: uint, // index of top of scan_stack bottom: uint, // index of bottom of scan_stack // stack of blocks-in-progress being flushed by print - print_stack: @mut ~[print_stack_elt], + print_stack: ~[print_stack_elt], // buffered indentation to avoid writing trailing whitespace pending_indentation: int, } @@ -461,7 +461,7 @@ impl Printer { self.pending_indentation += amount; } pub fn get_top(&mut self) -> print_stack_elt { - let print_stack = &mut *self.print_stack; + let print_stack = &mut self.print_stack; let n = print_stack.len(); if n != 0u { print_stack[n - 1u] @@ -506,7 +506,7 @@ impl Printer { } END => { debug!("print END -> pop END"); - let print_stack = &mut *self.print_stack; + let print_stack = &mut self.print_stack; assert!((print_stack.len() != 0u)); print_stack.pop(); } @@ -557,47 +557,47 @@ impl Printer { // Convenience functions to talk to the printer. // // "raw box" -pub fn rbox(p: @mut Printer, indent: uint, b: breaks) { +pub fn rbox(p: &mut Printer, indent: uint, b: breaks) { p.pretty_print(BEGIN(begin_t { offset: indent as int, breaks: b })); } -pub fn ibox(p: @mut Printer, indent: uint) { rbox(p, indent, inconsistent); } +pub fn ibox(p: &mut Printer, indent: uint) { rbox(p, indent, inconsistent); } -pub fn cbox(p: @mut Printer, indent: uint) { rbox(p, indent, consistent); } +pub fn cbox(p: &mut Printer, indent: uint) { rbox(p, indent, consistent); } -pub fn break_offset(p: @mut Printer, n: uint, off: int) { +pub fn break_offset(p: &mut Printer, n: uint, off: int) { p.pretty_print(BREAK(break_t { offset: off, blank_space: n as int })); } -pub fn end(p: @mut Printer) { p.pretty_print(END); } +pub fn end(p: &mut Printer) { p.pretty_print(END); } -pub fn eof(p: @mut Printer) { p.pretty_print(EOF); } +pub fn eof(p: &mut Printer) { p.pretty_print(EOF); } -pub fn word(p: @mut Printer, wrd: &str) { +pub fn word(p: &mut Printer, wrd: &str) { p.pretty_print(STRING(/* bad */ wrd.to_managed(), wrd.len() as int)); } -pub fn huge_word(p: @mut Printer, wrd: &str) { +pub fn huge_word(p: &mut Printer, wrd: &str) { p.pretty_print(STRING(/* bad */ wrd.to_managed(), size_infinity)); } -pub fn zero_word(p: @mut Printer, wrd: &str) { +pub fn zero_word(p: &mut Printer, wrd: &str) { p.pretty_print(STRING(/* bad */ wrd.to_managed(), 0)); } -pub fn spaces(p: @mut Printer, n: uint) { break_offset(p, n, 0); } +pub fn spaces(p: &mut Printer, n: uint) { break_offset(p, n, 0); } -pub fn zerobreak(p: @mut Printer) { spaces(p, 0u); } +pub fn zerobreak(p: &mut Printer) { spaces(p, 0u); } -pub fn space(p: @mut Printer) { spaces(p, 1u); } +pub fn space(p: &mut Printer) { spaces(p, 1u); } -pub fn hardbreak(p: @mut Printer) { spaces(p, size_infinity as uint); } +pub fn hardbreak(p: &mut Printer) { spaces(p, size_infinity as uint); } pub fn hardbreak_tok_offset(off: int) -> token { BREAK(break_t {offset: off, blank_space: size_infinity}) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 79ef9c2cbbe..9725d6e38de 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -27,18 +27,20 @@ use print::pp::{breaks, consistent, inconsistent, eof}; use print::pp; use print::pprust; +use std::cast; +use std::cell::RefCell; use std::char; use std::str; use std::io; use std::io::Decorator; use std::io::mem::MemWriter; -// The @ps is stored here to prevent recursive type. -pub enum ann_node<'a> { - node_block(@ps, &'a ast::Block), - node_item(@ps, &'a ast::item), - node_expr(@ps, &'a ast::Expr), - node_pat(@ps, &'a ast::Pat), +// The &mut ps is stored here to prevent recursive type. +pub enum ann_node<'a,'b> { + node_block(&'b mut ps, &'a ast::Block), + node_item(&'b mut ps, &'a ast::item), + node_expr(&'b mut ps, &'a ast::Expr), + node_pat(&'b mut ps, &'a ast::Pat), } pub trait pp_ann { @@ -66,45 +68,51 @@ pub struct CurrentCommentAndLiteral { } pub struct ps { - s: @mut pp::Printer, + s: pp::Printer, cm: Option<@CodeMap>, intr: @token::ident_interner, comments: Option<~[comments::cmnt]>, literals: Option<~[comments::lit]>, - cur_cmnt_and_lit: @mut CurrentCommentAndLiteral, - boxes: @mut ~[pp::breaks], + cur_cmnt_and_lit: CurrentCommentAndLiteral, + boxes: RefCell<~[pp::breaks]>, ann: @pp_ann } -pub fn ibox(s: @ps, u: uint) { - s.boxes.push(pp::inconsistent); - pp::ibox(s.s, u); +pub fn ibox(s: &mut ps, u: uint) { + { + let mut boxes = s.boxes.borrow_mut(); + boxes.get().push(pp::inconsistent); + } + pp::ibox(&mut s.s, u); } -pub fn end(s: @ps) { - s.boxes.pop(); - pp::end(s.s); +pub fn end(s: &mut ps) { + { + let mut boxes = s.boxes.borrow_mut(); + boxes.get().pop(); + } + pp::end(&mut s.s); } -pub fn rust_printer(writer: @mut io::Writer, intr: @ident_interner) -> @ps { +pub fn rust_printer(writer: ~io::Writer, intr: @ident_interner) -> ps { return rust_printer_annotated(writer, intr, @no_ann::new() as @pp_ann); } -pub fn rust_printer_annotated(writer: @mut io::Writer, +pub fn rust_printer_annotated(writer: ~io::Writer, intr: @ident_interner, ann: @pp_ann) - -> @ps { - return @ps { + -> ps { + return ps { s: pp::mk_printer(writer, default_columns), cm: None::<@CodeMap>, intr: intr, comments: None::<~[comments::cmnt]>, literals: None::<~[comments::lit]>, - cur_cmnt_and_lit: @mut CurrentCommentAndLiteral { + cur_cmnt_and_lit: CurrentCommentAndLiteral { cur_cmnt: 0, cur_lit: 0 }, - boxes: @mut ~[], + boxes: RefCell::new(~[]), ann: ann }; } @@ -118,11 +126,11 @@ pub static default_columns: uint = 78u; // copy forward. pub fn print_crate(cm: @CodeMap, intr: @ident_interner, - span_diagnostic: @mut diagnostic::SpanHandler, + span_diagnostic: @diagnostic::SpanHandler, crate: &ast::Crate, filename: @str, - input: @mut io::Reader, - out: @mut io::Writer, + input: &mut io::Reader, + out: ~io::Writer, ann: @pp_ann, is_expanded: bool) { let (cmnts, lits) = comments::gather_comments_and_literals( @@ -130,7 +138,7 @@ pub fn print_crate(cm: @CodeMap, filename, input ); - let s = @ps { + let mut s = ps { s: pp::mk_printer(out, default_columns), cm: Some(cm), intr: intr, @@ -143,20 +151,20 @@ pub fn print_crate(cm: @CodeMap, } else { Some(lits) }, - cur_cmnt_and_lit: @mut CurrentCommentAndLiteral { + cur_cmnt_and_lit: CurrentCommentAndLiteral { cur_cmnt: 0, cur_lit: 0 }, - boxes: @mut ~[], + boxes: RefCell::new(~[]), ann: ann }; - print_crate_(s, crate); + print_crate_(&mut s, crate); } -pub fn print_crate_(s: @ps, crate: &ast::Crate) { +pub fn print_crate_(s: &mut ps, crate: &ast::Crate) { print_mod(s, &crate.module, crate.attrs); print_remaining_comments(s); - eof(s.s); + eof(&mut s.s); } pub fn ty_to_str(ty: &ast::Ty, intr: @ident_interner) -> ~str { @@ -203,26 +211,30 @@ pub fn path_to_str(p: &ast::Path, intr: @ident_interner) -> ~str { pub fn fun_to_str(decl: &ast::fn_decl, purity: ast::purity, name: ast::Ident, opt_explicit_self: Option<ast::explicit_self_>, generics: &ast::Generics, intr: @ident_interner) -> ~str { - let wr = @mut MemWriter::new(); - let s = rust_printer(wr as @mut io::Writer, intr); - print_fn(s, decl, Some(purity), AbiSet::Rust(), + let wr = ~MemWriter::new(); + let mut s = rust_printer(wr as ~io::Writer, intr); + print_fn(&mut s, decl, Some(purity), AbiSet::Rust(), name, generics, opt_explicit_self, ast::inherited); - end(s); // Close the head box - end(s); // Close the outer box - eof(s.s); - str::from_utf8_owned(wr.inner_ref().to_owned()) + end(&mut s); // Close the head box + end(&mut s); // Close the outer box + eof(&mut s.s); + unsafe { + get_mem_writer(&mut s.s.out) + } } pub fn block_to_str(blk: &ast::Block, intr: @ident_interner) -> ~str { - let wr = @mut MemWriter::new(); - let s = rust_printer(wr as @mut io::Writer, intr); + let wr = ~MemWriter::new(); + let mut s = rust_printer(wr as ~io::Writer, intr); // containing cbox, will be closed by print-block at } - cbox(s, indent_unit); + cbox(&mut s, indent_unit); // head-ibox, will be closed by print-block after { - ibox(s, 0u); - print_block(s, blk); - eof(s.s); - str::from_utf8_owned(wr.inner_ref().to_owned()) + ibox(&mut s, 0u); + print_block(&mut s, blk); + eof(&mut s.s); + unsafe { + get_mem_writer(&mut s.s.out) + } } pub fn meta_item_to_str(mi: &ast::MetaItem, intr: @ident_interner) -> ~str { @@ -237,28 +249,34 @@ pub fn variant_to_str(var: &ast::variant, intr: @ident_interner) -> ~str { to_str(var, print_variant, intr) } -pub fn cbox(s: @ps, u: uint) { - s.boxes.push(pp::consistent); - pp::cbox(s.s, u); +pub fn cbox(s: &mut ps, u: uint) { + { + let mut boxes = s.boxes.borrow_mut(); + boxes.get().push(pp::consistent); + } + pp::cbox(&mut s.s, u); } // "raw box" -pub fn rbox(s: @ps, u: uint, b: pp::breaks) { - s.boxes.push(b); - pp::rbox(s.s, u, b); +pub fn rbox(s: &mut ps, u: uint, b: pp::breaks) { + { + let mut boxes = s.boxes.borrow_mut(); + boxes.get().push(b); + } + pp::rbox(&mut s.s, u, b); } -pub fn nbsp(s: @ps) { word(s.s, " "); } +pub fn nbsp(s: &mut ps) { word(&mut s.s, " "); } -pub fn word_nbsp(s: @ps, w: &str) { word(s.s, w); nbsp(s); } +pub fn word_nbsp(s: &mut ps, w: &str) { word(&mut s.s, w); nbsp(s); } -pub fn word_space(s: @ps, w: &str) { word(s.s, w); space(s.s); } +pub fn word_space(s: &mut ps, w: &str) { word(&mut s.s, w); space(&mut s.s); } -pub fn popen(s: @ps) { word(s.s, "("); } +pub fn popen(s: &mut ps) { word(&mut s.s, "("); } -pub fn pclose(s: @ps) { word(s.s, ")"); } +pub fn pclose(s: &mut ps) { word(&mut s.s, ")"); } -pub fn head(s: @ps, w: &str) { +pub fn head(s: &mut ps, w: &str) { // outer-box is consistent cbox(s, indent_unit); // head-box is inconsistent @@ -269,49 +287,53 @@ pub fn head(s: @ps, w: &str) { } } -pub fn bopen(s: @ps) { - word(s.s, "{"); +pub fn bopen(s: &mut ps) { + word(&mut s.s, "{"); end(s); // close the head-box } -pub fn bclose_(s: @ps, span: codemap::Span, indented: uint) { +pub fn bclose_(s: &mut ps, span: codemap::Span, indented: uint) { bclose_maybe_open(s, span, indented, true); } -pub fn bclose_maybe_open (s: @ps, span: codemap::Span, indented: uint, +pub fn bclose_maybe_open (s: &mut ps, span: codemap::Span, indented: uint, close_box: bool) { maybe_print_comment(s, span.hi); break_offset_if_not_bol(s, 1u, -(indented as int)); - word(s.s, "}"); + word(&mut s.s, "}"); if close_box { end(s); // close the outer-box } } -pub fn bclose(s: @ps, span: codemap::Span) { bclose_(s, span, indent_unit); } +pub fn bclose(s: &mut ps, span: codemap::Span) { bclose_(s, span, indent_unit); } -pub fn is_begin(s: @ps) -> bool { +pub fn is_begin(s: &mut ps) -> bool { match s.s.last_token() { pp::BEGIN(_) => true, _ => false } } -pub fn is_end(s: @ps) -> bool { +pub fn is_end(s: &mut ps) -> bool { match s.s.last_token() { pp::END => true, _ => false } } -pub fn is_bol(s: @ps) -> bool { +pub fn is_bol(s: &mut ps) -> bool { return s.s.last_token().is_eof() || s.s.last_token().is_hardbreak_tok(); } -pub fn in_cbox(s: @ps) -> bool { - let boxes = &*s.boxes; - let len = boxes.len(); +pub fn in_cbox(s: &mut ps) -> bool { + let boxes = s.boxes.borrow(); + let len = boxes.get().len(); if len == 0u { return false; } - return boxes[len - 1u] == pp::consistent; + return boxes.get()[len - 1u] == pp::consistent; } -pub fn hardbreak_if_not_bol(s: @ps) { if !is_bol(s) { hardbreak(s.s); } } -pub fn space_if_not_bol(s: @ps) { if !is_bol(s) { space(s.s); } } -pub fn break_offset_if_not_bol(s: @ps, n: uint, off: int) { +pub fn hardbreak_if_not_bol(s: &mut ps) { if !is_bol(s) { - break_offset(s.s, n, off); + hardbreak(&mut s.s) + } +} +pub fn space_if_not_bol(s: &mut ps) { if !is_bol(s) { space(&mut s.s); } } +pub fn break_offset_if_not_bol(s: &mut ps, n: uint, off: int) { + if !is_bol(s) { + break_offset(&mut s.s, n, off); } else { if off != 0 && s.s.last_token().is_hardbreak_tok() { // We do something pretty sketchy here: tuck the nonzero @@ -324,15 +346,15 @@ pub fn break_offset_if_not_bol(s: @ps, n: uint, off: int) { // Synthesizes a comment that was not textually present in the original source // file. -pub fn synth_comment(s: @ps, text: ~str) { - word(s.s, "/*"); - space(s.s); - word(s.s, text); - space(s.s); - word(s.s, "*/"); +pub fn synth_comment(s: &mut ps, text: ~str) { + word(&mut s.s, "/*"); + space(&mut s.s); + word(&mut s.s, text); + space(&mut s.s); + word(&mut s.s, "*/"); } -pub fn commasep<T>(s: @ps, b: breaks, elts: &[T], op: |@ps, &T|) { +pub fn commasep<T>(s: &mut ps, b: breaks, elts: &[T], op: |&mut ps, &T|) { rbox(s, 0u, b); let mut first = true; for elt in elts.iter() { @@ -344,10 +366,10 @@ pub fn commasep<T>(s: @ps, b: breaks, elts: &[T], op: |@ps, &T|) { pub fn commasep_cmnt<T>( - s: @ps, + s: &mut ps, b: breaks, elts: &[T], - op: |@ps, &T|, + op: |&mut ps, &T|, get_span: |&T| -> codemap::Span) { rbox(s, 0u, b); let len = elts.len(); @@ -357,7 +379,7 @@ pub fn commasep_cmnt<T>( op(s, elt); i += 1u; if i < len { - word(s.s, ","); + word(&mut s.s, ","); maybe_print_trailing_comment(s, get_span(elt), Some(get_span(&elts[i]).hi)); space_if_not_bol(s); @@ -366,11 +388,11 @@ pub fn commasep_cmnt<T>( end(s); } -pub fn commasep_exprs(s: @ps, b: breaks, exprs: &[@ast::Expr]) { +pub fn commasep_exprs(s: &mut ps, b: breaks, exprs: &[@ast::Expr]) { commasep_cmnt(s, b, exprs, |p, &e| print_expr(p, e), |e| e.span); } -pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::Attribute]) { +pub fn print_mod(s: &mut ps, _mod: &ast::_mod, attrs: &[ast::Attribute]) { print_inner_attributes(s, attrs); for vitem in _mod.view_items.iter() { print_view_item(s, vitem); @@ -378,7 +400,7 @@ pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::Attribute]) { for item in _mod.items.iter() { print_item(s, *item); } } -pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, +pub fn print_foreign_mod(s: &mut ps, nmod: &ast::foreign_mod, attrs: &[ast::Attribute]) { print_inner_attributes(s, attrs); for vitem in nmod.view_items.iter() { @@ -387,29 +409,29 @@ pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, for item in nmod.items.iter() { print_foreign_item(s, *item); } } -pub fn print_opt_lifetime(s: @ps, lifetime: &Option<ast::Lifetime>) { +pub fn print_opt_lifetime(s: &mut ps, lifetime: &Option<ast::Lifetime>) { for l in lifetime.iter() { print_lifetime(s, l); nbsp(s); } } -pub fn print_type(s: @ps, ty: &ast::Ty) { +pub fn print_type(s: &mut ps, ty: &ast::Ty) { maybe_print_comment(s, ty.span.lo); ibox(s, 0u); match ty.node { - ast::ty_nil => word(s.s, "()"), - ast::ty_bot => word(s.s, "!"), - ast::ty_box(ref mt) => { word(s.s, "@"); print_mt(s, mt); } - ast::ty_uniq(ty) => { word(s.s, "~"); print_type(s, ty); } + ast::ty_nil => word(&mut s.s, "()"), + ast::ty_bot => word(&mut s.s, "!"), + ast::ty_box(ty) => { word(&mut s.s, "@"); print_type(s, ty); } + ast::ty_uniq(ty) => { word(&mut s.s, "~"); print_type(s, ty); } ast::ty_vec(ty) => { - word(s.s, "["); + word(&mut s.s, "["); print_type(s, ty); - word(s.s, "]"); + word(&mut s.s, "]"); } - ast::ty_ptr(ref mt) => { word(s.s, "*"); print_mt(s, mt); } + ast::ty_ptr(ref mt) => { word(&mut s.s, "*"); print_mt(s, mt); } ast::ty_rptr(ref lifetime, ref mt) => { - word(s.s, "&"); + word(&mut s.s, "&"); print_opt_lifetime(s, lifetime); print_mt(s, mt); } @@ -417,7 +439,7 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { popen(s); commasep(s, inconsistent, *elts, print_type_ref); if elts.len() == 1 { - word(s.s, ","); + word(&mut s.s, ","); } pclose(s); } @@ -441,16 +463,16 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { } ast::ty_path(ref path, ref bounds, _) => print_bounded_path(s, path, bounds), ast::ty_fixed_length_vec(ty, v) => { - word(s.s, "["); + word(&mut s.s, "["); print_type(s, ty); - word(s.s, ", .."); + word(&mut s.s, ", .."); print_expr(s, v); - word(s.s, "]"); + word(&mut s.s, "]"); } ast::ty_typeof(e) => { - word(s.s, "typeof("); + word(&mut s.s, "typeof("); print_expr(s, e); - word(s.s, ")"); + word(&mut s.s, ")"); } ast::ty_infer => { fail!("print_type shouldn't see a ty_infer"); @@ -460,11 +482,11 @@ pub fn print_type(s: @ps, ty: &ast::Ty) { end(s); } -pub fn print_type_ref(s: @ps, ty: &P<ast::Ty>) { +pub fn print_type_ref(s: &mut ps, ty: &P<ast::Ty>) { print_type(s, *ty); } -pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) { +pub fn print_foreign_item(s: &mut ps, item: &ast::foreign_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); @@ -473,7 +495,7 @@ pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) { print_fn(s, decl, None, AbiSet::Rust(), item.ident, generics, None, item.vis); end(s); // end head-ibox - word(s.s, ";"); + word(&mut s.s, ";"); end(s); // end the outer fn box } ast::foreign_item_static(t, m) => { @@ -484,19 +506,21 @@ pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) { print_ident(s, item.ident); word_space(s, ":"); print_type(s, t); - word(s.s, ";"); + word(&mut s.s, ";"); end(s); // end the head-ibox end(s); // end the outer cbox } } } -pub fn print_item(s: @ps, item: &ast::item) { +pub fn print_item(s: &mut ps, item: &ast::item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); - let ann_node = node_item(s, item); - s.ann.pre(ann_node); + { + let ann_node = node_item(s, item); + s.ann.pre(ann_node); + } match item.node { ast::item_static(ty, m, expr) => { head(s, visibility_qualified(item.vis, "static")); @@ -506,12 +530,12 @@ pub fn print_item(s: @ps, item: &ast::item) { print_ident(s, item.ident); word_space(s, ":"); print_type(s, ty); - space(s.s); + space(&mut s.s); end(s); // end the head-ibox word_space(s, "="); print_expr(s, expr); - word(s.s, ";"); + word(&mut s.s, ";"); end(s); // end the outer cbox } @@ -526,7 +550,7 @@ pub fn print_item(s: @ps, item: &ast::item) { None, item.vis ); - word(s.s, " "); + word(&mut s.s, " "); print_block_with_attrs(s, body, item.attrs); } ast::item_mod(ref _mod) => { @@ -552,10 +576,10 @@ pub fn print_item(s: @ps, item: &ast::item) { print_generics(s, params); end(s); // end the inner ibox - space(s.s); + space(&mut s.s); word_space(s, "="); print_type(s, ty); - word(s.s, ";"); + word(&mut s.s, ";"); end(s); // end the outer ibox } ast::item_enum(ref enum_definition, ref params) => { @@ -577,13 +601,13 @@ pub fn print_item(s: @ps, item: &ast::item) { head(s, visibility_qualified(item.vis, "impl")); if generics.is_parameterized() { print_generics(s, generics); - space(s.s); + space(&mut s.s); } match opt_trait { &Some(ref t) => { print_trait_ref(s, t); - space(s.s); + space(&mut s.s); word_space(s, "for"); } &None => () @@ -591,7 +615,7 @@ pub fn print_item(s: @ps, item: &ast::item) { print_type(s, ty); - space(s.s); + space(&mut s.s); bopen(s); print_inner_attributes(s, item.attrs); for meth in methods.iter() { @@ -604,7 +628,7 @@ pub fn print_item(s: @ps, item: &ast::item) { print_ident(s, item.ident); print_generics(s, generics); if traits.len() != 0u { - word(s.s, ":"); + word(&mut s.s, ":"); for (i, trait_) in traits.iter().enumerate() { nbsp(s); if i != 0 { @@ -613,7 +637,7 @@ pub fn print_item(s: @ps, item: &ast::item) { print_path(s, &trait_.path, false); } } - word(s.s, " "); + word(&mut s.s, " "); bopen(s); for meth in methods.iter() { print_trait_method(s, meth); @@ -625,7 +649,7 @@ pub fn print_item(s: @ps, item: &ast::item) { ..}) => { print_visibility(s, item.vis); print_path(s, pth, false); - word(s.s, "! "); + word(&mut s.s, "! "); print_ident(s, item.ident); cbox(s, indent_unit); popen(s); @@ -634,24 +658,27 @@ pub fn print_item(s: @ps, item: &ast::item) { end(s); } } - s.ann.post(ann_node); + { + let ann_node = node_item(s, item); + s.ann.post(ann_node); + } } -fn print_trait_ref(s: @ps, t: &ast::trait_ref) { +fn print_trait_ref(s: &mut ps, t: &ast::trait_ref) { print_path(s, &t.path, false); } -pub fn print_enum_def(s: @ps, enum_definition: &ast::enum_def, +pub fn print_enum_def(s: &mut ps, enum_definition: &ast::enum_def, generics: &ast::Generics, ident: ast::Ident, span: codemap::Span, visibility: ast::visibility) { head(s, visibility_qualified(visibility, "enum")); print_ident(s, ident); print_generics(s, generics); - space(s.s); + space(&mut s.s); print_variants(s, enum_definition.variants, span); } -pub fn print_variants(s: @ps, +pub fn print_variants(s: &mut ps, variants: &[P<ast::variant>], span: codemap::Span) { bopen(s); @@ -661,7 +688,7 @@ pub fn print_variants(s: @ps, print_outer_attributes(s, v.node.attrs); ibox(s, indent_unit); print_variant(s, v); - word(s.s, ","); + word(&mut s.s, ","); end(s); maybe_print_trailing_comment(s, v.span, None); } @@ -683,7 +710,7 @@ pub fn visibility_qualified(vis: ast::visibility, s: &str) -> ~str { } } -pub fn print_visibility(s: @ps, vis: ast::visibility) { +pub fn print_visibility(s: &mut ps, vis: ast::visibility) { match vis { ast::private | ast::public => word_nbsp(s, visibility_to_str(vis)), @@ -691,7 +718,7 @@ pub fn print_visibility(s: @ps, vis: ast::visibility) { } } -pub fn print_struct(s: @ps, +pub fn print_struct(s: &mut ps, struct_def: &ast::struct_def, generics: &ast::Generics, ident: ast::Ident, @@ -712,7 +739,7 @@ pub fn print_struct(s: @ps, }); pclose(s); } - word(s.s, ";"); + word(&mut s.s, ";"); end(s); end(s); // close the outer-box } else { @@ -731,7 +758,7 @@ pub fn print_struct(s: @ps, print_ident(s, ident); word_nbsp(s, ":"); print_type(s, field.node.ty); - word(s.s, ","); + word(&mut s.s, ","); } } } @@ -747,48 +774,48 @@ pub fn print_struct(s: @ps, /// appropriate macro, transcribe back into the grammar we just parsed from, /// and then pretty-print the resulting AST nodes (so, e.g., we print /// expression arguments as expressions). It can be done! I think. -pub fn print_tt(s: @ps, tt: &ast::token_tree) { +pub fn print_tt(s: &mut ps, tt: &ast::token_tree) { match *tt { ast::tt_delim(ref tts) => print_tts(s, &(tts.as_slice())), ast::tt_tok(_, ref tk) => { - word(s.s, parse::token::to_str(s.intr, tk)); + word(&mut s.s, parse::token::to_str(s.intr, tk)); } ast::tt_seq(_, ref tts, ref sep, zerok) => { - word(s.s, "$("); + word(&mut s.s, "$("); for tt_elt in (*tts).iter() { print_tt(s, tt_elt); } - word(s.s, ")"); + word(&mut s.s, ")"); match (*sep) { - Some(ref tk) => word(s.s, parse::token::to_str(s.intr, tk)), + Some(ref tk) => word(&mut s.s, parse::token::to_str(s.intr, tk)), None => () } - word(s.s, if zerok { "*" } else { "+" }); + word(&mut s.s, if zerok { "*" } else { "+" }); } ast::tt_nonterminal(_, name) => { - word(s.s, "$"); + word(&mut s.s, "$"); print_ident(s, name); } } } -pub fn print_tts(s: @ps, tts: & &[ast::token_tree]) { +pub fn print_tts(s: &mut ps, tts: & &[ast::token_tree]) { ibox(s, 0); for (i, tt) in tts.iter().enumerate() { if i != 0 { - space(s.s); + space(&mut s.s); } print_tt(s, tt); } end(s); } -pub fn print_variant(s: @ps, v: &ast::variant) { +pub fn print_variant(s: &mut ps, v: &ast::variant) { print_visibility(s, v.node.vis); match v.node.kind { ast::tuple_variant_kind(ref args) => { print_ident(s, v.node.name); if !args.is_empty() { popen(s); - fn print_variant_arg(s: @ps, arg: &ast::variant_arg) { + fn print_variant_arg(s: &mut ps, arg: &ast::variant_arg) { print_type(s, arg.ty); } commasep(s, consistent, *args, print_variant_arg); @@ -803,7 +830,7 @@ pub fn print_variant(s: @ps, v: &ast::variant) { } match v.node.disr_expr { Some(d) => { - space(s.s); + space(&mut s.s); word_space(s, "="); print_expr(s, d); } @@ -811,7 +838,7 @@ pub fn print_variant(s: @ps, v: &ast::variant) { } } -pub fn print_ty_method(s: @ps, m: &ast::TypeMethod) { +pub fn print_ty_method(s: &mut ps, m: &ast::TypeMethod) { hardbreak_if_not_bol(s); maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); @@ -826,28 +853,28 @@ pub fn print_ty_method(s: @ps, m: &ast::TypeMethod) { &None, Some(&m.generics), Some(m.explicit_self.node)); - word(s.s, ";"); + word(&mut s.s, ";"); } -pub fn print_trait_method(s: @ps, m: &ast::trait_method) { +pub fn print_trait_method(s: &mut ps, m: &ast::trait_method) { match *m { required(ref ty_m) => print_ty_method(s, ty_m), provided(m) => print_method(s, m) } } -pub fn print_method(s: @ps, meth: &ast::method) { +pub fn print_method(s: &mut ps, meth: &ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); print_fn(s, meth.decl, Some(meth.purity), AbiSet::Rust(), meth.ident, &meth.generics, Some(meth.explicit_self.node), meth.vis); - word(s.s, " "); + word(&mut s.s, " "); print_block_with_attrs(s, meth.body, meth.attrs); } -pub fn print_outer_attributes(s: @ps, attrs: &[ast::Attribute]) { +pub fn print_outer_attributes(s: &mut ps, attrs: &[ast::Attribute]) { let mut count = 0; for attr in attrs.iter() { match attr.node.style { @@ -858,14 +885,14 @@ pub fn print_outer_attributes(s: @ps, attrs: &[ast::Attribute]) { if count > 0 { hardbreak_if_not_bol(s); } } -pub fn print_inner_attributes(s: @ps, attrs: &[ast::Attribute]) { +pub fn print_inner_attributes(s: &mut ps, attrs: &[ast::Attribute]) { let mut count = 0; for attr in attrs.iter() { match attr.node.style { ast::AttrInner => { print_attribute(s, attr); if !attr.node.is_sugared_doc { - word(s.s, ";"); + word(&mut s.s, ";"); } count += 1; } @@ -875,21 +902,21 @@ pub fn print_inner_attributes(s: @ps, attrs: &[ast::Attribute]) { if count > 0 { hardbreak_if_not_bol(s); } } -pub fn print_attribute(s: @ps, attr: &ast::Attribute) { +pub fn print_attribute(s: &mut ps, attr: &ast::Attribute) { hardbreak_if_not_bol(s); maybe_print_comment(s, attr.span.lo); if attr.node.is_sugared_doc { let comment = attr.value_str().unwrap(); - word(s.s, comment); + word(&mut s.s, comment); } else { - word(s.s, "#["); + word(&mut s.s, "#["); print_meta_item(s, attr.meta()); - word(s.s, "]"); + word(&mut s.s, "]"); } } -pub fn print_stmt(s: @ps, st: &ast::Stmt) { +pub fn print_stmt(s: &mut ps, st: &ast::Stmt) { maybe_print_comment(s, st.span.lo); match st.node { ast::StmtDecl(decl, _) => { @@ -902,33 +929,33 @@ pub fn print_stmt(s: @ps, st: &ast::Stmt) { ast::StmtSemi(expr, _) => { space_if_not_bol(s); print_expr(s, expr); - word(s.s, ";"); + word(&mut s.s, ";"); } ast::StmtMac(ref mac, semi) => { space_if_not_bol(s); print_mac(s, mac); - if semi { word(s.s, ";"); } + if semi { word(&mut s.s, ";"); } } } - if parse::classify::stmt_ends_with_semi(st) { word(s.s, ";"); } + if parse::classify::stmt_ends_with_semi(st) { word(&mut s.s, ";"); } maybe_print_trailing_comment(s, st.span, None); } -pub fn print_block(s: @ps, blk: &ast::Block) { +pub fn print_block(s: &mut ps, blk: &ast::Block) { print_possibly_embedded_block(s, blk, block_normal, indent_unit); } -pub fn print_block_unclosed(s: @ps, blk: &ast::Block) { +pub fn print_block_unclosed(s: &mut ps, blk: &ast::Block) { print_possibly_embedded_block_(s, blk, block_normal, indent_unit, &[], false); } -pub fn print_block_unclosed_indent(s: @ps, blk: &ast::Block, indented: uint) { +pub fn print_block_unclosed_indent(s: &mut ps, blk: &ast::Block, indented: uint) { print_possibly_embedded_block_(s, blk, block_normal, indented, &[], false); } -pub fn print_block_with_attrs(s: @ps, +pub fn print_block_with_attrs(s: &mut ps, blk: &ast::Block, attrs: &[ast::Attribute]) { print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs, @@ -937,7 +964,7 @@ pub fn print_block_with_attrs(s: @ps, pub enum embed_type { block_block_fn, block_normal, } -pub fn print_possibly_embedded_block(s: @ps, +pub fn print_possibly_embedded_block(s: &mut ps, blk: &ast::Block, embedded: embed_type, indented: uint) { @@ -945,7 +972,7 @@ pub fn print_possibly_embedded_block(s: @ps, s, blk, embedded, indented, &[], true); } -pub fn print_possibly_embedded_block_(s: @ps, +pub fn print_possibly_embedded_block_(s: &mut ps, blk: &ast::Block, embedded: embed_type, indented: uint, @@ -956,8 +983,10 @@ pub fn print_possibly_embedded_block_(s: @ps, ast::DefaultBlock => () } maybe_print_comment(s, blk.span.lo); - let ann_node = node_block(s, blk); - s.ann.pre(ann_node); + { + let ann_node = node_block(s, blk); + s.ann.pre(ann_node); + } match embedded { block_block_fn => end(s), block_normal => bopen(s) @@ -978,17 +1007,20 @@ pub fn print_possibly_embedded_block_(s: @ps, _ => () } bclose_maybe_open(s, blk.span, indented, close_box); - s.ann.post(ann_node); + { + let ann_node = node_block(s, blk); + s.ann.post(ann_node); + } } -pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block, +pub fn print_if(s: &mut ps, test: &ast::Expr, blk: &ast::Block, elseopt: Option<@ast::Expr>, chk: bool) { head(s, "if"); if chk { word_nbsp(s, "check"); } print_expr(s, test); - space(s.s); + space(&mut s.s); print_block(s, blk); - fn do_else(s: @ps, els: Option<@ast::Expr>) { + fn do_else(s: &mut ps, els: Option<@ast::Expr>) { match els { Some(_else) => { match _else.node { @@ -996,9 +1028,9 @@ pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block, ast::ExprIf(i, t, e) => { cbox(s, indent_unit - 1u); ibox(s, 0u); - word(s.s, " else if "); + word(&mut s.s, " else if "); print_expr(s, i); - space(s.s); + space(&mut s.s); print_block(s, t); do_else(s, e); } @@ -1006,7 +1038,7 @@ pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block, ast::ExprBlock(b) => { cbox(s, indent_unit - 1u); ibox(s, 0u); - word(s.s, " else "); + word(&mut s.s, " else "); print_block(s, b); } // BLEAH, constraints would be great here @@ -1021,12 +1053,12 @@ pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block, do_else(s, elseopt); } -pub fn print_mac(s: @ps, m: &ast::mac) { +pub fn print_mac(s: &mut ps, m: &ast::mac) { match m.node { // I think it's reasonable to hide the ctxt here: ast::mac_invoc_tt(ref pth, ref tts, _) => { print_path(s, pth, false); - word(s.s, "!"); + word(&mut s.s, "!"); popen(s); print_tts(s, &tts.as_slice()); pclose(s); @@ -1034,36 +1066,32 @@ pub fn print_mac(s: @ps, m: &ast::mac) { } } -pub fn print_vstore(s: @ps, t: ast::Vstore) { +pub fn print_vstore(s: &mut ps, t: ast::Vstore) { match t { - ast::VstoreFixed(Some(i)) => word(s.s, format!("{}", i)), - ast::VstoreFixed(None) => word(s.s, "_"), - ast::VstoreUniq => word(s.s, "~"), - ast::VstoreBox => word(s.s, "@"), + ast::VstoreFixed(Some(i)) => word(&mut s.s, format!("{}", i)), + ast::VstoreFixed(None) => word(&mut s.s, "_"), + ast::VstoreUniq => word(&mut s.s, "~"), + ast::VstoreBox => word(&mut s.s, "@"), ast::VstoreSlice(ref r) => { - word(s.s, "&"); + word(&mut s.s, "&"); print_opt_lifetime(s, r); } } } -pub fn print_expr_vstore(s: @ps, t: ast::ExprVstore) { +pub fn print_expr_vstore(s: &mut ps, t: ast::ExprVstore) { match t { - ast::ExprVstoreUniq => word(s.s, "~"), - ast::ExprVstoreBox => word(s.s, "@"), - ast::ExprVstoreMutBox => { - word(s.s, "@"); - word(s.s, "mut"); - } - ast::ExprVstoreSlice => word(s.s, "&"), + ast::ExprVstoreUniq => word(&mut s.s, "~"), + ast::ExprVstoreBox => word(&mut s.s, "@"), + ast::ExprVstoreSlice => word(&mut s.s, "&"), ast::ExprVstoreMutSlice => { - word(s.s, "&"); - word(s.s, "mut"); + word(&mut s.s, "&"); + word(&mut s.s, "mut"); } } } -pub fn print_call_pre(s: @ps, +pub fn print_call_pre(s: &mut ps, sugar: ast::CallSugar, base_args: &mut ~[@ast::Expr]) -> Option<@ast::Expr> { @@ -1080,7 +1108,7 @@ pub fn print_call_pre(s: @ps, } } -pub fn print_call_post(s: @ps, +pub fn print_call_post(s: &mut ps, sugar: ast::CallSugar, blk: &Option<@ast::Expr>, base_args: &mut ~[@ast::Expr]) { @@ -1107,8 +1135,8 @@ pub fn print_call_post(s: @ps, } } -pub fn print_expr(s: @ps, expr: &ast::Expr) { - fn print_field(s: @ps, field: &ast::Field) { +pub fn print_expr(s: &mut ps, expr: &ast::Expr) { + fn print_field(s: &mut ps, field: &ast::Field) { ibox(s, indent_unit); print_ident(s, field.ident.node); word_space(s, ":"); @@ -1119,8 +1147,10 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { maybe_print_comment(s, expr.span.lo); ibox(s, indent_unit); - let ann_node = node_expr(s, expr); - s.ann.pre(ann_node); + { + let ann_node = node_expr(s, expr); + s.ann.pre(ann_node); + } match expr.node { ast::ExprVstore(e, v) => { print_expr_vstore(s, v); @@ -1128,53 +1158,53 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { }, ast::ExprVec(ref exprs, mutbl) => { ibox(s, indent_unit); - word(s.s, "["); + word(&mut s.s, "["); if mutbl == ast::MutMutable { - word(s.s, "mut"); + word(&mut s.s, "mut"); if exprs.len() > 0u { nbsp(s); } } commasep_exprs(s, inconsistent, *exprs); - word(s.s, "]"); + word(&mut s.s, "]"); end(s); } ast::ExprRepeat(element, count, mutbl) => { ibox(s, indent_unit); - word(s.s, "["); + word(&mut s.s, "["); if mutbl == ast::MutMutable { - word(s.s, "mut"); + word(&mut s.s, "mut"); nbsp(s); } print_expr(s, element); - word(s.s, ","); - word(s.s, ".."); + word(&mut s.s, ","); + word(&mut s.s, ".."); print_expr(s, count); - word(s.s, "]"); + word(&mut s.s, "]"); end(s); } ast::ExprStruct(ref path, ref fields, wth) => { print_path(s, path, true); - word(s.s, "{"); + word(&mut s.s, "{"); commasep_cmnt(s, consistent, (*fields), print_field, get_span); match wth { Some(expr) => { ibox(s, indent_unit); - word(s.s, ","); - space(s.s); - word(s.s, ".."); + word(&mut s.s, ","); + space(&mut s.s); + word(&mut s.s, ".."); print_expr(s, expr); end(s); } - _ => (word(s.s, ",")) + _ => (word(&mut s.s, ",")) } - word(s.s, "}"); + word(&mut s.s, "}"); } ast::ExprTup(ref exprs) => { popen(s); commasep_exprs(s, inconsistent, *exprs); if exprs.len() == 1 { - word(s.s, ","); + word(&mut s.s, ","); } pclose(s); } @@ -1188,31 +1218,31 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { let mut base_args = (*args).clone(); let blk = print_call_pre(s, sugar, &mut base_args); print_expr(s, func); - word(s.s, "."); + word(&mut s.s, "."); print_ident(s, ident); if tys.len() > 0u { - word(s.s, "::<"); + word(&mut s.s, "::<"); commasep(s, inconsistent, *tys, print_type_ref); - word(s.s, ">"); + word(&mut s.s, ">"); } print_call_post(s, sugar, &blk, &mut base_args); } ast::ExprBinary(_, op, lhs, rhs) => { print_expr(s, lhs); - space(s.s); + space(&mut s.s); word_space(s, ast_util::binop_to_str(op)); print_expr(s, rhs); } ast::ExprUnary(_, op, expr) => { - word(s.s, ast_util::unop_to_str(op)); + word(&mut s.s, ast_util::unop_to_str(op)); print_expr(s, expr); } ast::ExprAddrOf(m, expr) => { - word(s.s, "&"); + word(&mut s.s, "&"); print_mutability(s, m); // Avoid `& &e` => `&&e`. match (m, &expr.node) { - (ast::MutImmutable, &ast::ExprAddrOf(..)) => space(s.s), + (ast::MutImmutable, &ast::ExprAddrOf(..)) => space(&mut s.s), _ => { } } print_expr(s, expr); @@ -1220,7 +1250,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { ast::ExprLit(lit) => print_literal(s, lit), ast::ExprCast(expr, ty) => { print_expr(s, expr); - space(s.s); + space(&mut s.s); word_space(s, "as"); print_type(s, ty); } @@ -1230,31 +1260,31 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { ast::ExprWhile(test, blk) => { head(s, "while"); print_expr(s, test); - space(s.s); + space(&mut s.s); print_block(s, blk); } ast::ExprForLoop(pat, iter, blk, opt_ident) => { for ident in opt_ident.iter() { - word(s.s, "'"); + word(&mut s.s, "'"); print_ident(s, *ident); word_space(s, ":"); } head(s, "for"); print_pat(s, pat); - space(s.s); + space(&mut s.s); word_space(s, "in"); print_expr(s, iter); - space(s.s); + space(&mut s.s); print_block(s, blk); } ast::ExprLoop(blk, opt_ident) => { for ident in opt_ident.iter() { - word(s.s, "'"); + word(&mut s.s, "'"); print_ident(s, *ident); word_space(s, ":"); } head(s, "loop"); - space(s.s); + space(&mut s.s); print_block(s, blk); } ast::ExprMatch(expr, ref arms) => { @@ -1262,26 +1292,26 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { ibox(s, 4); word_nbsp(s, "match"); print_expr(s, expr); - space(s.s); + space(&mut s.s); bopen(s); let len = arms.len(); for (i, arm) in arms.iter().enumerate() { - space(s.s); + space(&mut s.s); cbox(s, indent_unit); ibox(s, 0u); let mut first = true; for p in arm.pats.iter() { if first { first = false; - } else { space(s.s); word_space(s, "|"); } + } else { space(&mut s.s); word_space(s, "|"); } print_pat(s, *p); } - space(s.s); + space(&mut s.s); match arm.guard { Some(e) => { word_space(s, "if"); print_expr(s, e); - space(s.s); + space(&mut s.s); } None => () } @@ -1309,7 +1339,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { } if !expr_is_simple_block(expr) && i < len - 1 { - word(s.s, ","); + word(&mut s.s, ","); } end(s); // close enclosing cbox } @@ -1329,7 +1359,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { // // if !decl.inputs.is_empty() { print_fn_block_args(s, decl); - space(s.s); + space(&mut s.s); // } assert!(body.stmts.is_empty()); assert!(body.expr.is_some()); @@ -1356,7 +1386,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { // // if !decl.inputs.is_empty() { print_proc_args(s, decl); - space(s.s); + space(&mut s.s); // } assert!(body.stmts.is_empty()); assert!(body.expr.is_some()); @@ -1388,70 +1418,70 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { } ast::ExprAssign(lhs, rhs) => { print_expr(s, lhs); - space(s.s); + space(&mut s.s); word_space(s, "="); print_expr(s, rhs); } ast::ExprAssignOp(_, op, lhs, rhs) => { print_expr(s, lhs); - space(s.s); - word(s.s, ast_util::binop_to_str(op)); + space(&mut s.s); + word(&mut s.s, ast_util::binop_to_str(op)); word_space(s, "="); print_expr(s, rhs); } ast::ExprField(expr, id, ref tys) => { print_expr(s, expr); - word(s.s, "."); + word(&mut s.s, "."); print_ident(s, id); if tys.len() > 0u { - word(s.s, "::<"); + word(&mut s.s, "::<"); commasep(s, inconsistent, *tys, print_type_ref); - word(s.s, ">"); + word(&mut s.s, ">"); } } ast::ExprIndex(_, expr, index) => { print_expr(s, expr); - word(s.s, "["); + word(&mut s.s, "["); print_expr(s, index); - word(s.s, "]"); + word(&mut s.s, "]"); } ast::ExprPath(ref path) => print_path(s, path, true), - ast::ExprSelf => word(s.s, "self"), + ast::ExprSelf => word(&mut s.s, "self"), ast::ExprBreak(opt_ident) => { - word(s.s, "break"); - space(s.s); + word(&mut s.s, "break"); + space(&mut s.s); for ident in opt_ident.iter() { - word(s.s, "'"); + word(&mut s.s, "'"); print_name(s, *ident); - space(s.s); + space(&mut s.s); } } ast::ExprAgain(opt_ident) => { - word(s.s, "continue"); - space(s.s); + word(&mut s.s, "continue"); + space(&mut s.s); for ident in opt_ident.iter() { - word(s.s, "'"); + word(&mut s.s, "'"); print_name(s, *ident); - space(s.s) + space(&mut s.s) } } ast::ExprRet(result) => { - word(s.s, "return"); + word(&mut s.s, "return"); match result { - Some(expr) => { word(s.s, " "); print_expr(s, expr); } + Some(expr) => { word(&mut s.s, " "); print_expr(s, expr); } _ => () } } ast::ExprLogLevel => { - word(s.s, "__log_level"); + word(&mut s.s, "__log_level"); popen(s); pclose(s); } ast::ExprInlineAsm(ref a) => { if a.volatile { - word(s.s, "__volatile__ asm!"); + word(&mut s.s, "__volatile__ asm!"); } else { - word(s.s, "asm!"); + word(&mut s.s, "asm!"); } popen(s); print_string(s, a.asm, a.asm_str_style); @@ -1482,11 +1512,14 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) { pclose(s); } } - s.ann.post(ann_node); + { + let ann_node = node_expr(s, expr); + s.ann.post(ann_node); + } end(s); } -pub fn print_local_decl(s: @ps, loc: &ast::Local) { +pub fn print_local_decl(s: &mut ps, loc: &ast::Local) { print_pat(s, loc.pat); match loc.ty.node { ast::ty_infer => (), @@ -1494,7 +1527,7 @@ pub fn print_local_decl(s: @ps, loc: &ast::Local) { } } -pub fn print_decl(s: @ps, decl: &ast::Decl) { +pub fn print_decl(s: &mut ps, decl: &ast::Decl) { maybe_print_comment(s, decl.span.lo); match decl.node { ast::DeclLocal(ref loc) => { @@ -1502,7 +1535,7 @@ pub fn print_decl(s: @ps, decl: &ast::Decl) { ibox(s, indent_unit); word_nbsp(s, "let"); - fn print_local(s: @ps, loc: &ast::Local) { + fn print_local(s: &mut ps, loc: &ast::Local) { ibox(s, indent_unit); print_local_decl(s, loc); end(s); @@ -1523,28 +1556,28 @@ pub fn print_decl(s: @ps, decl: &ast::Decl) { } } -pub fn print_ident(s: @ps, ident: ast::Ident) { - word(s.s, ident_to_str(&ident)); +pub fn print_ident(s: &mut ps, ident: ast::Ident) { + word(&mut s.s, ident_to_str(&ident)); } -pub fn print_name(s: @ps, name: ast::Name) { - word(s.s, interner_get(name)); +pub fn print_name(s: &mut ps, name: ast::Name) { + word(&mut s.s, interner_get(name)); } -pub fn print_for_decl(s: @ps, loc: &ast::Local, coll: &ast::Expr) { +pub fn print_for_decl(s: &mut ps, loc: &ast::Local, coll: &ast::Expr) { print_local_decl(s, loc); - space(s.s); + space(&mut s.s); word_space(s, "in"); print_expr(s, coll); } -fn print_path_(s: @ps, +fn print_path_(s: &mut ps, path: &ast::Path, colons_before_params: bool, opt_bounds: &Option<OptVec<ast::TyParamBound>>) { maybe_print_comment(s, path.span.lo); if path.global { - word(s.s, "::"); + word(&mut s.s, "::"); } let mut first = true; @@ -1552,7 +1585,7 @@ fn print_path_(s: @ps, if first { first = false } else { - word(s.s, "::") + word(&mut s.s, "::") } print_ident(s, segment.identifier); @@ -1567,9 +1600,9 @@ fn print_path_(s: @ps, if !segment.lifetimes.is_empty() || !segment.types.is_empty() { if colons_before_params { - word(s.s, "::") + word(&mut s.s, "::") } - word(s.s, "<"); + word(&mut s.s, "<"); let mut comma = false; for lifetime in segment.lifetimes.iter() { @@ -1590,29 +1623,31 @@ fn print_path_(s: @ps, print_type_ref); } - word(s.s, ">") + word(&mut s.s, ">") } } } -pub fn print_path(s: @ps, path: &ast::Path, colons_before_params: bool) { +pub fn print_path(s: &mut ps, path: &ast::Path, colons_before_params: bool) { print_path_(s, path, colons_before_params, &None) } -pub fn print_bounded_path(s: @ps, path: &ast::Path, +pub fn print_bounded_path(s: &mut ps, path: &ast::Path, bounds: &Option<OptVec<ast::TyParamBound>>) { print_path_(s, path, false, bounds) } -pub fn print_pat(s: @ps, pat: &ast::Pat) { +pub fn print_pat(s: &mut ps, pat: &ast::Pat) { maybe_print_comment(s, pat.span.lo); - let ann_node = node_pat(s, pat); - s.ann.pre(ann_node); + { + let ann_node = node_pat(s, pat); + s.ann.pre(ann_node); + } /* Pat isn't normalized, but the beauty of it is that it doesn't matter */ match pat.node { - ast::PatWild => word(s.s, "_"), - ast::PatWildMulti => word(s.s, ".."), + ast::PatWild => word(&mut s.s, "_"), + ast::PatWildMulti => word(&mut s.s, ".."), ast::PatIdent(binding_mode, ref path, sub) => { match binding_mode { ast::BindByRef(mutbl) => { @@ -1627,7 +1662,7 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) { print_path(s, path, true); match sub { Some(p) => { - word(s.s, "@"); + word(&mut s.s, "@"); print_pat(s, p); } None => () @@ -1636,7 +1671,7 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) { ast::PatEnum(ref path, ref args_) => { print_path(s, path, true); match *args_ { - None => word(s.s, "(..)"), + None => word(&mut s.s, "(..)"), Some(ref args) => { if !args.is_empty() { popen(s); @@ -1649,8 +1684,8 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) { } ast::PatStruct(ref path, ref fields, etc) => { print_path(s, path, true); - word(s.s, "{"); - fn print_field(s: @ps, f: &ast::FieldPat) { + word(&mut s.s, "{"); + fn print_field(s: &mut ps, f: &ast::FieldPat) { cbox(s, indent_unit); print_ident(s, f.ident); word_space(s, ":"); @@ -1663,39 +1698,39 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) { get_span); if etc { if fields.len() != 0u { word_space(s, ","); } - word(s.s, ".."); + word(&mut s.s, ".."); } - word(s.s, "}"); + word(&mut s.s, "}"); } ast::PatTup(ref elts) => { popen(s); commasep(s, inconsistent, *elts, |s, &p| print_pat(s, p)); if elts.len() == 1 { - word(s.s, ","); + word(&mut s.s, ","); } pclose(s); } ast::PatBox(inner) => { - word(s.s, "@"); + word(&mut s.s, "@"); print_pat(s, inner); } ast::PatUniq(inner) => { - word(s.s, "~"); + word(&mut s.s, "~"); print_pat(s, inner); } ast::PatRegion(inner) => { - word(s.s, "&"); + word(&mut s.s, "&"); print_pat(s, inner); } ast::PatLit(e) => print_expr(s, e), ast::PatRange(begin, end) => { print_expr(s, begin); - space(s.s); - word(s.s, ".."); + space(&mut s.s); + word(&mut s.s, ".."); print_expr(s, end); } ast::PatVec(ref before, slice, ref after) => { - word(s.s, "["); + word(&mut s.s, "["); commasep(s, inconsistent, *before, |s, &p| print_pat(s, p)); for &p in slice.iter() { if !before.is_empty() { word_space(s, ","); } @@ -1703,16 +1738,19 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) { @ast::Pat { node: ast::PatWildMulti, .. } => { // this case is handled by print_pat } - _ => word(s.s, ".."), + _ => word(&mut s.s, ".."), } print_pat(s, p); if !after.is_empty() { word_space(s, ","); } } commasep(s, inconsistent, *after, |s, &p| print_pat(s, p)); - word(s.s, "]"); + word(&mut s.s, "]"); } } - s.ann.post(ann_node); + { + let ann_node = node_pat(s, pat); + s.ann.post(ann_node); + } } pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_interner) -> ~str { @@ -1720,31 +1758,31 @@ pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_in } // Returns whether it printed anything -pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool { +pub fn print_explicit_self(s: &mut ps, explicit_self: ast::explicit_self_) -> bool { match explicit_self { ast::sty_static => { return false; } ast::sty_value(m) => { print_mutability(s, m); - word(s.s, "self"); + word(&mut s.s, "self"); } ast::sty_uniq(m) => { print_mutability(s, m); - word(s.s, "~self"); + word(&mut s.s, "~self"); } ast::sty_region(ref lt, m) => { - word(s.s, "&"); + word(&mut s.s, "&"); print_opt_lifetime(s, lt); print_mutability(s, m); - word(s.s, "self"); + word(&mut s.s, "self"); } ast::sty_box(m) => { - word(s.s, "@"); print_mutability(s, m); word(s.s, "self"); + word(&mut s.s, "@"); print_mutability(s, m); word(&mut s.s, "self"); } } return true; } -pub fn print_fn(s: @ps, +pub fn print_fn(s: &mut ps, decl: &ast::fn_decl, purity: Option<ast::purity>, abis: AbiSet, @@ -1760,7 +1798,7 @@ pub fn print_fn(s: @ps, print_fn_args_and_ret(s, decl, opt_explicit_self); } -pub fn print_fn_args(s: @ps, decl: &ast::fn_decl, +pub fn print_fn_args(s: &mut ps, decl: &ast::fn_decl, opt_explicit_self: Option<ast::explicit_self_>) { // It is unfortunate to duplicate the commasep logic, but we want the // self type and the args all in the same box. @@ -1778,12 +1816,12 @@ pub fn print_fn_args(s: @ps, decl: &ast::fn_decl, end(s); } -pub fn print_fn_args_and_ret(s: @ps, decl: &ast::fn_decl, +pub fn print_fn_args_and_ret(s: &mut ps, decl: &ast::fn_decl, opt_explicit_self: Option<ast::explicit_self_>) { popen(s); print_fn_args(s, decl, opt_explicit_self); if decl.variadic { - word(s.s, ", ..."); + word(&mut s.s, ", ..."); } pclose(s); @@ -1798,10 +1836,10 @@ pub fn print_fn_args_and_ret(s: @ps, decl: &ast::fn_decl, } } -pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { - word(s.s, "|"); +pub fn print_fn_block_args(s: &mut ps, decl: &ast::fn_decl) { + word(&mut s.s, "|"); print_fn_args(s, decl, None); - word(s.s, "|"); + word(&mut s.s, "|"); match decl.output.node { ast::ty_infer => {} @@ -1815,11 +1853,11 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { maybe_print_comment(s, decl.output.span.lo); } -pub fn print_proc_args(s: @ps, decl: &ast::fn_decl) { - word(s.s, "proc"); - word(s.s, "("); +pub fn print_proc_args(s: &mut ps, decl: &ast::fn_decl) { + word(&mut s.s, "proc"); + word(&mut s.s, "("); print_fn_args(s, decl, None); - word(s.s, ")"); + word(&mut s.s, ")"); match decl.output.node { ast::ty_infer => {} @@ -1833,10 +1871,10 @@ pub fn print_proc_args(s: @ps, decl: &ast::fn_decl) { maybe_print_comment(s, decl.output.span.lo); } -pub fn print_bounds(s: @ps, bounds: &OptVec<ast::TyParamBound>, +pub fn print_bounds(s: &mut ps, bounds: &OptVec<ast::TyParamBound>, print_colon_anyway: bool) { if !bounds.is_empty() { - word(s.s, ":"); + word(&mut s.s, ":"); let mut first = true; for bound in bounds.iter() { nbsp(s); @@ -1848,24 +1886,24 @@ pub fn print_bounds(s: @ps, bounds: &OptVec<ast::TyParamBound>, match *bound { TraitTyParamBound(ref tref) => print_trait_ref(s, tref), - RegionTyParamBound => word(s.s, "'static"), + RegionTyParamBound => word(&mut s.s, "'static"), } } } else if print_colon_anyway { - word(s.s, ":"); + word(&mut s.s, ":"); } } -pub fn print_lifetime(s: @ps, lifetime: &ast::Lifetime) { - word(s.s, "'"); +pub fn print_lifetime(s: &mut ps, lifetime: &ast::Lifetime) { + word(&mut s.s, "'"); print_ident(s, lifetime.ident); } -pub fn print_generics(s: @ps, generics: &ast::Generics) { +pub fn print_generics(s: &mut ps, generics: &ast::Generics) { let total = generics.lifetimes.len() + generics.ty_params.len(); if total > 0 { - word(s.s, "<"); - fn print_item(s: @ps, generics: &ast::Generics, idx: uint) { + word(&mut s.s, "<"); + fn print_item(s: &mut ps, generics: &ast::Generics, idx: uint) { if idx < generics.lifetimes.len() { let lifetime = generics.lifetimes.get(idx); print_lifetime(s, lifetime); @@ -1884,21 +1922,21 @@ pub fn print_generics(s: @ps, generics: &ast::Generics) { commasep(s, inconsistent, ints, |s, &i| print_item(s, generics, i)); - word(s.s, ">"); + word(&mut s.s, ">"); } } -pub fn print_meta_item(s: @ps, item: &ast::MetaItem) { +pub fn print_meta_item(s: &mut ps, item: &ast::MetaItem) { ibox(s, indent_unit); match item.node { - ast::MetaWord(name) => word(s.s, name), + ast::MetaWord(name) => word(&mut s.s, name), ast::MetaNameValue(name, value) => { word_space(s, name); word_space(s, "="); print_literal(s, &value); } ast::MetaList(name, ref items) => { - word(s.s, name); + word(&mut s.s, name); popen(s); commasep(s, consistent, @@ -1910,13 +1948,13 @@ pub fn print_meta_item(s: @ps, item: &ast::MetaItem) { end(s); } -pub fn print_view_path(s: @ps, vp: &ast::view_path) { +pub fn print_view_path(s: &mut ps, vp: &ast::view_path) { match vp.node { ast::view_path_simple(ident, ref path, _) => { // FIXME(#6993) can't compare identifiers directly here if path.segments.last().identifier.name != ident.name { print_ident(s, ident); - space(s.s); + space(&mut s.s); word_space(s, "="); } print_path(s, path, false); @@ -1924,29 +1962,29 @@ pub fn print_view_path(s: @ps, vp: &ast::view_path) { ast::view_path_glob(ref path, _) => { print_path(s, path, false); - word(s.s, "::*"); + word(&mut s.s, "::*"); } ast::view_path_list(ref path, ref idents, _) => { if path.segments.is_empty() { - word(s.s, "{"); + word(&mut s.s, "{"); } else { print_path(s, path, false); - word(s.s, "::{"); + word(&mut s.s, "::{"); } commasep(s, inconsistent, (*idents), |s, w| { print_ident(s, w.node.name); }); - word(s.s, "}"); + word(&mut s.s, "}"); } } } -pub fn print_view_paths(s: @ps, vps: &[@ast::view_path]) { +pub fn print_view_paths(s: &mut ps, vps: &[@ast::view_path]) { commasep(s, inconsistent, vps, |p, &vp| print_view_path(p, vp)); } -pub fn print_view_item(s: @ps, item: &ast::view_item) { +pub fn print_view_item(s: &mut ps, item: &ast::view_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); @@ -1956,9 +1994,9 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { head(s, "extern mod"); print_ident(s, id); for &(ref p, style) in optional_path.iter() { - space(s.s); - word(s.s, "="); - space(s.s); + space(&mut s.s); + word(&mut s.s, "="); + space(&mut s.s); print_string(s, *p, style); } } @@ -1968,24 +2006,24 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) { print_view_paths(s, *vps); } } - word(s.s, ";"); + word(&mut s.s, ";"); end(s); // end inner head-block end(s); // end outer head-block } -pub fn print_mutability(s: @ps, mutbl: ast::Mutability) { +pub fn print_mutability(s: &mut ps, mutbl: ast::Mutability) { match mutbl { ast::MutMutable => word_nbsp(s, "mut"), ast::MutImmutable => {/* nothing */ } } } -pub fn print_mt(s: @ps, mt: &ast::mt) { +pub fn print_mt(s: &mut ps, mt: &ast::mt) { print_mutability(s, mt.mutbl); print_type(s, mt.ty); } -pub fn print_arg(s: @ps, input: &ast::arg) { +pub fn print_arg(s: &mut ps, input: &ast::arg) { ibox(s, indent_unit); match input.ty.node { ast::ty_infer => print_pat(s, input.pat), @@ -1999,8 +2037,8 @@ pub fn print_arg(s: @ps, input: &ast::arg) { } _ => { print_pat(s, input.pat); - word(s.s, ":"); - space(s.s); + word(&mut s.s, ":"); + space(&mut s.s); } } print_type(s, input.ty); @@ -2009,7 +2047,7 @@ pub fn print_arg(s: @ps, input: &ast::arg) { end(s); } -pub fn print_ty_fn(s: @ps, +pub fn print_ty_fn(s: &mut ps, opt_abis: Option<AbiSet>, opt_sigil: Option<ast::Sigil>, opt_region: &Option<ast::Lifetime>, @@ -2025,7 +2063,7 @@ pub fn print_ty_fn(s: @ps, // Duplicates the logic in `print_fn_header_info()`. This is because that // function prints the sigil in the wrong place. That should be fixed. if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once { - word(s.s, "proc"); + word(&mut s.s, "proc"); } else if opt_sigil == Some(ast::BorrowedSigil) { print_extern_opt_abis(s, opt_abis); for lifetime in opt_region.iter() { @@ -2039,20 +2077,20 @@ pub fn print_ty_fn(s: @ps, print_opt_lifetime(s, opt_region); print_purity(s, purity); print_onceness(s, onceness); - word(s.s, "fn"); + word(&mut s.s, "fn"); } - match id { Some(id) => { word(s.s, " "); print_ident(s, id); } _ => () } + match id { Some(id) => { word(&mut s.s, " "); print_ident(s, id); } _ => () } if opt_sigil != Some(ast::BorrowedSigil) { opt_bounds.as_ref().map(|bounds| print_bounds(s, bounds, true)); } match generics { Some(g) => print_generics(s, g), _ => () } - zerobreak(s.s); + zerobreak(&mut s.s); if opt_sigil == Some(ast::BorrowedSigil) { - word(s.s, "|"); + word(&mut s.s, "|"); } else { popen(s); } @@ -2071,12 +2109,12 @@ pub fn print_ty_fn(s: @ps, end(s); if opt_sigil == Some(ast::BorrowedSigil) { - word(s.s, "|"); + word(&mut s.s, "|"); opt_bounds.as_ref().map(|bounds| print_bounds(s, bounds, true)); } else { if decl.variadic { - word(s.s, ", ..."); + word(&mut s.s, ", ..."); } pclose(s); } @@ -2098,7 +2136,7 @@ pub fn print_ty_fn(s: @ps, end(s); } -pub fn maybe_print_trailing_comment(s: @ps, span: codemap::Span, +pub fn maybe_print_trailing_comment(s: &mut ps, span: codemap::Span, next_pos: Option<BytePos>) { let cm; match s.cm { Some(ccm) => cm = ccm, _ => return } @@ -2119,10 +2157,10 @@ pub fn maybe_print_trailing_comment(s: @ps, span: codemap::Span, } } -pub fn print_remaining_comments(s: @ps) { +pub fn print_remaining_comments(s: &mut ps) { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. - if next_comment(s).is_none() { hardbreak(s.s); } + if next_comment(s).is_none() { hardbreak(&mut s.s); } loop { match next_comment(s) { Some(ref cmnt) => { @@ -2134,11 +2172,11 @@ pub fn print_remaining_comments(s: @ps) { } } -pub fn print_literal(s: @ps, lit: &ast::lit) { +pub fn print_literal(s: &mut ps, lit: &ast::lit) { maybe_print_comment(s, lit.span.lo); match next_lit(s, lit.span.lo) { Some(ref ltrl) => { - word(s.s, (*ltrl).lit); + word(&mut s.s, (*ltrl).lit); return; } _ => () @@ -2149,45 +2187,45 @@ pub fn print_literal(s: @ps, lit: &ast::lit) { let mut res = ~"'"; char::from_u32(ch).unwrap().escape_default(|c| res.push_char(c)); res.push_char('\''); - word(s.s, res); + word(&mut s.s, res); } ast::lit_int(i, t) => { if i < 0_i64 { - word(s.s, + word(&mut s.s, ~"-" + (-i as u64).to_str_radix(10u) + ast_util::int_ty_to_str(t)); } else { - word(s.s, + word(&mut s.s, (i as u64).to_str_radix(10u) + ast_util::int_ty_to_str(t)); } } ast::lit_uint(u, t) => { - word(s.s, + word(&mut s.s, u.to_str_radix(10u) + ast_util::uint_ty_to_str(t)); } ast::lit_int_unsuffixed(i) => { if i < 0_i64 { - word(s.s, ~"-" + (-i as u64).to_str_radix(10u)); + word(&mut s.s, ~"-" + (-i as u64).to_str_radix(10u)); } else { - word(s.s, (i as u64).to_str_radix(10u)); + word(&mut s.s, (i as u64).to_str_radix(10u)); } } ast::lit_float(f, t) => { - word(s.s, f.to_owned() + ast_util::float_ty_to_str(t)); + word(&mut s.s, f.to_owned() + ast_util::float_ty_to_str(t)); } - ast::lit_float_unsuffixed(f) => word(s.s, f), - ast::lit_nil => word(s.s, "()"), + ast::lit_float_unsuffixed(f) => word(&mut s.s, f), + ast::lit_nil => word(&mut s.s, "()"), ast::lit_bool(val) => { - if val { word(s.s, "true"); } else { word(s.s, "false"); } + if val { word(&mut s.s, "true"); } else { word(&mut s.s, "false"); } } ast::lit_binary(arr) => { ibox(s, indent_unit); - word(s.s, "["); - commasep_cmnt(s, inconsistent, arr, |s, u| word(s.s, format!("{}", *u)), + word(&mut s.s, "["); + commasep_cmnt(s, inconsistent, arr, |s, u| word(&mut s.s, format!("{}", *u)), |_| lit.span); - word(s.s, "]"); + word(&mut s.s, "]"); end(s); } } @@ -2197,7 +2235,7 @@ pub fn lit_to_str(l: &ast::lit) -> ~str { return to_str(l, print_literal, parse::token::mk_fake_ident_interner()); } -pub fn next_lit(s: @ps, pos: BytePos) -> Option<comments::lit> { +pub fn next_lit(s: &mut ps, pos: BytePos) -> Option<comments::lit> { match s.literals { Some(ref lits) => { while s.cur_cmnt_and_lit.cur_lit < lits.len() { @@ -2212,7 +2250,7 @@ pub fn next_lit(s: @ps, pos: BytePos) -> Option<comments::lit> { } } -pub fn maybe_print_comment(s: @ps, pos: BytePos) { +pub fn maybe_print_comment(s: &mut ps, pos: BytePos) { loop { match next_comment(s) { Some(ref cmnt) => { @@ -2226,33 +2264,33 @@ pub fn maybe_print_comment(s: @ps, pos: BytePos) { } } -pub fn print_comment(s: @ps, cmnt: &comments::cmnt) { +pub fn print_comment(s: &mut ps, cmnt: &comments::cmnt) { match cmnt.style { comments::mixed => { assert_eq!(cmnt.lines.len(), 1u); - zerobreak(s.s); - word(s.s, cmnt.lines[0]); - zerobreak(s.s); + zerobreak(&mut s.s); + word(&mut s.s, cmnt.lines[0]); + zerobreak(&mut s.s); } comments::isolated => { pprust::hardbreak_if_not_bol(s); for line in cmnt.lines.iter() { // Don't print empty lines because they will end up as trailing // whitespace - if !line.is_empty() { word(s.s, *line); } - hardbreak(s.s); + if !line.is_empty() { word(&mut s.s, *line); } + hardbreak(&mut s.s); } } comments::trailing => { - word(s.s, " "); + word(&mut s.s, " "); if cmnt.lines.len() == 1u { - word(s.s, cmnt.lines[0]); - hardbreak(s.s); + word(&mut s.s, cmnt.lines[0]); + hardbreak(&mut s.s); } else { ibox(s, 0u); for line in cmnt.lines.iter() { - if !line.is_empty() { word(s.s, *line); } - hardbreak(s.s); + if !line.is_empty() { word(&mut s.s, *line); } + hardbreak(&mut s.s); } end(s); } @@ -2264,30 +2302,42 @@ pub fn print_comment(s: @ps, cmnt: &comments::cmnt) { pp::STRING(s, _) => ";" == s, _ => false }; - if is_semi || is_begin(s) || is_end(s) { hardbreak(s.s); } - hardbreak(s.s); + if is_semi || is_begin(s) || is_end(s) { hardbreak(&mut s.s); } + hardbreak(&mut s.s); } } } -pub fn print_string(s: @ps, st: &str, style: ast::StrStyle) { +pub fn print_string(s: &mut ps, st: &str, style: ast::StrStyle) { let st = match style { ast::CookedStr => format!("\"{}\"", st.escape_default()), ast::RawStr(n) => format!("r{delim}\"{string}\"{delim}", delim="#".repeat(n), string=st) }; - word(s.s, st); + word(&mut s.s, st); } -pub fn to_str<T>(t: &T, f: |@ps, &T|, intr: @ident_interner) -> ~str { - let wr = @mut MemWriter::new(); - let s = rust_printer(wr as @mut io::Writer, intr); - f(s, t); - eof(s.s); - str::from_utf8_owned(wr.inner_ref().to_owned()) +// XXX(pcwalton): A nasty function to extract the string from an `io::Writer` +// that we "know" to be a `MemWriter` that works around the lack of checked +// downcasts. +unsafe fn get_mem_writer(writer: &mut ~io::Writer) -> ~str { + let (_, wr): (uint, ~MemWriter) = cast::transmute_copy(writer); + let result = str::from_utf8_owned(wr.inner_ref().to_owned()); + cast::forget(wr); + result } -pub fn next_comment(s: @ps) -> Option<comments::cmnt> { +pub fn to_str<T>(t: &T, f: |&mut ps, &T|, intr: @ident_interner) -> ~str { + let wr = ~MemWriter::new(); + let mut s = rust_printer(wr as ~io::Writer, intr); + f(&mut s, t); + eof(&mut s.s); + unsafe { + get_mem_writer(&mut s.s.out) + } +} + +pub fn next_comment(s: &mut ps) -> Option<comments::cmnt> { match s.comments { Some(ref cmnts) => { if s.cur_cmnt_and_lit.cur_cmnt < cmnts.len() { @@ -2300,7 +2350,7 @@ pub fn next_comment(s: @ps) -> Option<comments::cmnt> { } } -pub fn print_opt_purity(s: @ps, opt_purity: Option<ast::purity>) { +pub fn print_opt_purity(s: &mut ps, opt_purity: Option<ast::purity>) { match opt_purity { Some(ast::impure_fn) => { } Some(purity) => { @@ -2310,7 +2360,7 @@ pub fn print_opt_purity(s: @ps, opt_purity: Option<ast::purity>) { } } -pub fn print_opt_abis_and_extern_if_nondefault(s: @ps, +pub fn print_opt_abis_and_extern_if_nondefault(s: &mut ps, opt_abis: Option<AbiSet>) { match opt_abis { Some(abis) if !abis.is_rust() => { @@ -2321,7 +2371,7 @@ pub fn print_opt_abis_and_extern_if_nondefault(s: @ps, }; } -pub fn print_extern_opt_abis(s: @ps, opt_abis: Option<AbiSet>) { +pub fn print_extern_opt_abis(s: &mut ps, opt_abis: Option<AbiSet>) { match opt_abis { Some(abis) => { word_nbsp(s, "extern"); @@ -2331,23 +2381,23 @@ pub fn print_extern_opt_abis(s: @ps, opt_abis: Option<AbiSet>) { }; } -pub fn print_opt_sigil(s: @ps, opt_sigil: Option<ast::Sigil>) { +pub fn print_opt_sigil(s: &mut ps, opt_sigil: Option<ast::Sigil>) { match opt_sigil { - Some(ast::BorrowedSigil) => { word(s.s, "&"); } - Some(ast::OwnedSigil) => { word(s.s, "~"); } - Some(ast::ManagedSigil) => { word(s.s, "@"); } + Some(ast::BorrowedSigil) => { word(&mut s.s, "&"); } + Some(ast::OwnedSigil) => { word(&mut s.s, "~"); } + Some(ast::ManagedSigil) => { word(&mut s.s, "@"); } None => {} }; } -pub fn print_fn_header_info(s: @ps, +pub fn print_fn_header_info(s: &mut ps, _opt_explicit_self: Option<ast::explicit_self_>, opt_purity: Option<ast::purity>, abis: AbiSet, onceness: ast::Onceness, opt_sigil: Option<ast::Sigil>, vis: ast::visibility) { - word(s.s, visibility_qualified(vis, "")); + word(&mut s.s, visibility_qualified(vis, "")); if abis != AbiSet::Rust() { word_nbsp(s, "extern"); @@ -2361,7 +2411,7 @@ pub fn print_fn_header_info(s: @ps, } print_onceness(s, onceness); - word(s.s, "fn"); + word(&mut s.s, "fn"); print_opt_sigil(s, opt_sigil); } @@ -2380,14 +2430,14 @@ pub fn onceness_to_str(o: ast::Onceness) -> &'static str { } } -pub fn print_purity(s: @ps, p: ast::purity) { +pub fn print_purity(s: &mut ps, p: ast::purity) { match p { ast::impure_fn => (), _ => word_nbsp(s, purity_to_str(p)) } } -pub fn print_onceness(s: @ps, o: ast::Onceness) { +pub fn print_onceness(s: &mut ps, o: ast::Onceness) { match o { ast::Once => { word_nbsp(s, "once"); } ast::Many => {} @@ -2403,12 +2453,6 @@ mod test { use codemap; use parse::token; - fn string_check<T:Eq> (given : &T, expected: &T) { - if !(given == expected) { - fail!("given {:?}, expected {:?}", given, expected); - } - } - #[test] fn test_fun_to_str() { let abba_ident = token::str_to_ident("abba"); diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index c144b36a86f..b694e1f702b 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -14,20 +14,21 @@ use ast::Name; +use std::cell::RefCell; use std::cmp::Equiv; use std::hashmap::HashMap; pub struct Interner<T> { - priv map: @mut HashMap<T, Name>, - priv vect: @mut ~[T], + priv map: @RefCell<HashMap<T, Name>>, + priv vect: @RefCell<~[T]>, } // when traits can extend traits, we should extend index<Name,T> to get [] impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> { pub fn new() -> Interner<T> { Interner { - map: @mut HashMap::new(), - vect: @mut ~[], + map: @RefCell::new(HashMap::new()), + vect: @RefCell::new(~[]), } } @@ -40,37 +41,41 @@ impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> { } pub fn intern(&self, val: T) -> Name { - match self.map.find(&val) { + let mut map = self.map.borrow_mut(); + match map.get().find(&val) { Some(&idx) => return idx, None => (), } - let vect = &mut *self.vect; - let new_idx = vect.len() as Name; - self.map.insert(val.clone(), new_idx); - vect.push(val); + let mut vect = self.vect.borrow_mut(); + let new_idx = vect.get().len() as Name; + map.get().insert(val.clone(), new_idx); + vect.get().push(val); new_idx } pub fn gensym(&self, val: T) -> Name { - let new_idx = { - let vect = &*self.vect; - vect.len() as Name - }; + let mut vect = self.vect.borrow_mut(); + let new_idx = vect.get().len() as Name; // leave out of .map to avoid colliding - self.vect.push(val); + vect.get().push(val); new_idx } pub fn get(&self, idx: Name) -> T { - self.vect[idx].clone() + let vect = self.vect.borrow(); + vect.get()[idx].clone() } - pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() } + pub fn len(&self) -> uint { + let vect = self.vect.borrow(); + vect.get().len() + } pub fn find_equiv<Q:Hash + IterBytes + Equiv<T>>(&self, val: &Q) -> Option<Name> { - match self.map.find_equiv(val) { + let map = self.map.borrow(); + match map.get().find_equiv(val) { Some(v) => Some(*v), None => None, } @@ -80,16 +85,16 @@ impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> { // A StrInterner differs from Interner<String> in that it accepts // borrowed pointers rather than @ ones, resulting in less allocation. pub struct StrInterner { - priv map: @mut HashMap<@str, Name>, - priv vect: @mut ~[@str], + priv map: @RefCell<HashMap<@str, Name>>, + priv vect: @RefCell<~[@str]>, } // when traits can extend traits, we should extend index<Name,T> to get [] impl StrInterner { pub fn new() -> StrInterner { StrInterner { - map: @mut HashMap::new(), - vect: @mut ~[], + map: @RefCell::new(HashMap::new()), + vect: @RefCell::new(~[]), } } @@ -100,22 +105,25 @@ impl StrInterner { } pub fn intern(&self, val: &str) -> Name { - match self.map.find_equiv(&val) { + let mut map = self.map.borrow_mut(); + match map.get().find_equiv(&val) { Some(&idx) => return idx, None => (), } let new_idx = self.len() as Name; let val = val.to_managed(); - self.map.insert(val, new_idx); - self.vect.push(val); + map.get().insert(val, new_idx); + let mut vect = self.vect.borrow_mut(); + vect.get().push(val); new_idx } pub fn gensym(&self, val: &str) -> Name { let new_idx = self.len() as Name; // leave out of .map to avoid colliding - self.vect.push(val.to_managed()); + let mut vect = self.vect.borrow_mut(); + vect.get().push(val.to_managed()); new_idx } @@ -132,17 +140,26 @@ impl StrInterner { pub fn gensym_copy(&self, idx : Name) -> Name { let new_idx = self.len() as Name; // leave out of map to avoid colliding - self.vect.push(self.vect[idx]); + let mut vect = self.vect.borrow_mut(); + let existing = vect.get()[idx]; + vect.get().push(existing); new_idx } - pub fn get(&self, idx: Name) -> @str { self.vect[idx] } + pub fn get(&self, idx: Name) -> @str { + let vect = self.vect.borrow(); + vect.get()[idx] + } - pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() } + pub fn len(&self) -> uint { + let vect = self.vect.borrow(); + vect.get().len() + } pub fn find_equiv<Q:Hash + IterBytes + Equiv<@str>>(&self, val: &Q) -> Option<Name> { - match self.map.find_equiv(val) { + let map = self.map.borrow(); + match map.get().find_equiv(val) { Some(v) => Some(*v), None => None, } diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 01e050c1ffe..dc546c7610f 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -17,7 +17,7 @@ use parse::token; // map a string to tts, using a made-up filename: return both the token_trees // and the ParseSess -pub fn string_to_tts_and_sess (source_str : @str) -> (~[ast::token_tree],@mut ParseSess) { +pub fn string_to_tts_and_sess (source_str : @str) -> (~[ast::token_tree],@ParseSess) { let ps = new_parse_sess(None); (filemap_to_tts(ps,string_to_filemap(ps,source_str,@"bogofile")),ps) } @@ -28,7 +28,7 @@ pub fn string_to_tts(source_str : @str) -> ~[ast::token_tree] { tts } -pub fn string_to_parser_and_sess(source_str: @str) -> (Parser,@mut ParseSess) { +pub fn string_to_parser_and_sess(source_str: @str) -> (Parser,@ParseSess) { let ps = new_parse_sess(None); (new_parser_from_source_str(ps,~[],@"bogofile",source_str),ps) } @@ -54,7 +54,7 @@ pub fn string_to_crate (source_str : @str) -> ast::Crate { } // parse a string, return a crate and the ParseSess -pub fn string_to_crate_and_sess (source_str : @str) -> (ast::Crate,@mut ParseSess) { +pub fn string_to_crate_and_sess (source_str : @str) -> (ast::Crate,@ParseSess) { let (mut p,ps) = string_to_parser_and_sess(source_str); (p.parse_crate_mod(),ps) } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 2e83a038c58..29567ab9442 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -302,10 +302,10 @@ pub fn skip_ty<E, V:Visitor<E>>(_: &mut V, _: &Ty, _: E) { pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) { match typ.node { - ty_uniq(ty) | ty_vec(ty) => { + ty_uniq(ty) | ty_vec(ty) | ty_box(ty) => { visitor.visit_ty(ty, env) } - ty_box(ref mutable_type) | ty_ptr(ref mutable_type) => { + ty_ptr(ref mutable_type) => { visitor.visit_ty(mutable_type.ty, env) } ty_rptr(ref lifetime, ref mutable_type) => { |
