diff --git a/doc/tutorial.md b/doc/tutorial.md index ccc7525b8d5eb..c0d5406f614e9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1431,8 +1431,8 @@ For a more in-depth explanation of borrowed pointers, read the ## Freezing Lending an immutable pointer to an object freezes it and prevents mutation. -`Freeze` objects have freezing enforced statically at compile-time. Examples -of non-`Freeze` types are `@mut` and [`RefCell`][refcell]. +`Freeze` objects have freezing enforced statically at compile-time. An example +of a non-`Freeze` type is [`RefCell`][refcell]. ~~~~ let mut x = 5; @@ -1443,20 +1443,6 @@ let mut x = 5; # x = 3; ~~~~ -Mutable managed boxes handle freezing dynamically when any of their contents -are borrowed, and the task will fail if an attempt to modify them is made while -they are frozen: - -~~~~ -let x = @mut 5; -let y = x; -{ - let z = &*y; // the managed box is now frozen - // modifying it through x or y will cause a task failure -} -// the box is now unfrozen again -~~~~ - [refcell]: http://static.rust-lang.org/doc/master/std/cell/struct.RefCell.html # Dereferencing pointers @@ -1477,7 +1463,7 @@ assignments. Such an assignment modifies the value that the pointer points to. ~~~ -let managed = @mut 10; +let managed = @10; let mut owned = ~20; let mut value = 30; @@ -2113,8 +2099,7 @@ unless they contain managed boxes, managed closures, or borrowed pointers. * `Freeze` - Constant (immutable) types. These are types that do not contain anything intrinsically mutable. -Intrinsically mutable values include `@mut` -and `Cell` in the standard library. +Intrinsically mutable values include `Cell` in the standard library. * `'static` - Non-borrowed types. These are types that do not contain any data whose lifetime is bound to diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index dc5f3b5d3cfd4..5ee0099561a21 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -35,11 +35,13 @@ #[allow(missing_doc)]; -use list::{MutList, MutCons, MutNil}; +use list::{List, Cons, Nil}; +use list; use std::at_vec; use std::cast::{transmute, transmute_mut, transmute_mut_region}; use std::cast; +use std::cell::{Cell, RefCell}; use std::num; use std::ptr; use std::mem; @@ -50,10 +52,11 @@ use std::unstable::intrinsics::{TyDesc, get_tydesc}; // The way arena uses arrays is really deeply awful. The arrays are // allocated, and have capacities reserved, but the fill for the array // will always stay at 0. +#[deriving(Clone)] struct Chunk { - data: @[u8], - fill: uint, - is_pod: bool, + data: RefCell<@[u8]>, + fill: Cell, + is_pod: Cell, } #[no_freeze] @@ -63,7 +66,7 @@ pub struct Arena { // access the head. priv head: Chunk, priv pod_head: Chunk, - priv chunks: @mut MutList, + priv chunks: RefCell<@List>, } impl Arena { @@ -75,7 +78,7 @@ impl Arena { Arena { head: chunk(initial_size, false), pod_head: chunk(initial_size, true), - chunks: @mut MutNil, + chunks: RefCell::new(@Nil), } } } @@ -84,9 +87,9 @@ fn chunk(size: uint, is_pod: bool) -> Chunk { let mut v: @[u8] = @[]; unsafe { at_vec::raw::reserve(&mut v, size); } Chunk { - data: unsafe { cast::transmute(v) }, - fill: 0u, - is_pod: is_pod, + data: RefCell::new(unsafe { cast::transmute(v) }), + fill: Cell::new(0u), + is_pod: Cell::new(is_pod), } } @@ -95,8 +98,9 @@ impl Drop for Arena { fn drop(&mut self) { unsafe { destroy_chunk(&self.head); - self.chunks.each(|chunk| { - if !chunk.is_pod { + + list::each(self.chunks.get(), |chunk| { + if !chunk.is_pod.get() { destroy_chunk(chunk); } true @@ -114,8 +118,11 @@ fn round_up_to(base: uint, align: uint) -> uint { // in it. unsafe fn destroy_chunk(chunk: &Chunk) { let mut idx = 0; - let buf = chunk.data.as_ptr(); - let fill = chunk.fill; + let buf = { + let data = chunk.data.borrow(); + data.get().as_ptr() + }; + let fill = chunk.fill.get(); while idx < fill { let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int)); @@ -155,9 +162,9 @@ impl Arena { // Functions for the POD part of the arena fn alloc_pod_grow(&mut self, n_bytes: uint, align: uint) -> *u8 { // Allocate a new chunk. - let chunk_size = at_vec::capacity(self.pod_head.data); + let chunk_size = at_vec::capacity(self.pod_head.data.get()); let new_min_chunk_size = num::max(n_bytes, chunk_size); - self.chunks = @mut MutCons(self.pod_head, self.chunks); + self.chunks.set(@Cons(self.pod_head.clone(), self.chunks.get())); self.pod_head = chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true); @@ -168,17 +175,17 @@ impl Arena { fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 { unsafe { let this = transmute_mut_region(self); - let start = round_up_to(this.pod_head.fill, align); + let start = round_up_to(this.pod_head.fill.get(), align); let end = start + n_bytes; - if end > at_vec::capacity(this.pod_head.data) { + if end > at_vec::capacity(this.pod_head.data.get()) { return this.alloc_pod_grow(n_bytes, align); } - this.pod_head.fill = end; + this.pod_head.fill.set(end); //debug!("idx = {}, size = {}, align = {}, fill = {}", - // start, n_bytes, align, head.fill); + // start, n_bytes, align, head.fill.get()); - ptr::offset(this.pod_head.data.as_ptr(), start as int) + ptr::offset(this.pod_head.data.get().as_ptr(), start as int) } } @@ -197,9 +204,9 @@ impl Arena { fn alloc_nonpod_grow(&mut self, n_bytes: uint, align: uint) -> (*u8, *u8) { // Allocate a new chunk. - let chunk_size = at_vec::capacity(self.head.data); + let chunk_size = at_vec::capacity(self.head.data.get()); let new_min_chunk_size = num::max(n_bytes, chunk_size); - self.chunks = @mut MutCons(self.head, self.chunks); + self.chunks.set(@Cons(self.head.clone(), self.chunks.get())); self.head = chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false); @@ -218,23 +225,23 @@ impl Arena { { let head = transmute_mut_region(&mut self.head); - tydesc_start = head.fill; - after_tydesc = head.fill + mem::size_of::<*TyDesc>(); + tydesc_start = head.fill.get(); + after_tydesc = head.fill.get() + mem::size_of::<*TyDesc>(); start = round_up_to(after_tydesc, align); end = start + n_bytes; } - if end > at_vec::capacity(self.head.data) { + if end > at_vec::capacity(self.head.data.get()) { return self.alloc_nonpod_grow(n_bytes, align); } let head = transmute_mut_region(&mut self.head); - head.fill = round_up_to(end, mem::pref_align_of::<*TyDesc>()); + head.fill.set(round_up_to(end, mem::pref_align_of::<*TyDesc>())); //debug!("idx = {}, size = {}, align = {}, fill = {}", // start, n_bytes, align, head.fill); - let buf = self.head.data.as_ptr(); + let buf = self.head.data.get().as_ptr(); return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int)); } } diff --git a/src/libextra/list.rs b/src/libextra/list.rs index a2540d3948e89..b530d9c9bc1d8 100644 --- a/src/libextra/list.rs +++ b/src/libextra/list.rs @@ -19,13 +19,6 @@ pub enum List { Nil, } -#[deriving(Eq)] -#[allow(missing_doc)] -pub enum MutList { - MutCons(T, @mut MutList), - MutNil, -} - /// Create a list from a vector pub fn from_vec(v: &[T]) -> @List { v.rev_iter().fold(@Nil::, |t, h| @Cons((*h).clone(), t)) @@ -158,26 +151,6 @@ pub fn each(l: @List, f: |&T| -> bool) -> bool { } } -impl MutList { - /// Iterate over a mutable list - pub fn each(@mut self, f: |&mut T| -> bool) -> bool { - let mut cur = self; - loop { - let borrowed = &mut *cur; - cur = match *borrowed { - MutCons(ref mut hd, tl) => { - if !f(hd) { - return false; - } - tl - } - MutNil => break - } - } - return true; - } -} - #[cfg(test)] mod tests { use list::*; diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 6b298d877da81..e7ccb91fb752b 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -426,18 +426,6 @@ impl + 'static> Decodable for @T { } } -impl> Encodable for @mut T { - fn encode(&self, s: &mut S) { - (**self).encode(s) - } -} - -impl + 'static> Decodable for @mut T { - fn decode(d: &mut D) -> @mut T { - @mut Decodable::decode(d) - } -} - impl<'a, S:Encoder,T:Encodable> Encodable for &'a [T] { fn encode(&self, s: &mut S) { s.emit_seq(self.len(), |s| { diff --git a/src/libextra/term.rs b/src/libextra/term.rs index 05e9b65d19cbd..1f119ca9db4a4 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -113,7 +113,8 @@ impl Terminal { return Err(entry.unwrap_err()); } - let ti = parse(entry.unwrap(), false); + let mut file = entry.unwrap(); + let ti = parse(&mut file, false); if ti.is_err() { return Err(ti.unwrap_err()); } diff --git a/src/libextra/terminfo/searcher.rs b/src/libextra/terminfo/searcher.rs index 09f8cc0efef40..8cbb090269783 100644 --- a/src/libextra/terminfo/searcher.rs +++ b/src/libextra/terminfo/searcher.rs @@ -11,10 +11,9 @@ /// Implement ncurses-compatible database discovery /// Does not support hashed database, only filesystem! -use std::{os, str}; -use std::os::getenv; -use std::io; use std::io::File; +use std::os::getenv; +use std::{os, str}; /// Return path to database entry for `term` pub fn get_dbpath_for_term(term: &str) -> Option<~Path> { @@ -74,9 +73,14 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~Path> { } /// Return open file for `term` -pub fn open(term: &str) -> Result<@mut io::Reader, ~str> { +pub fn open(term: &str) -> Result { match get_dbpath_for_term(term) { - Some(x) => Ok(@mut File::open(x) as @mut io::Reader), + Some(x) => { + match File::open(x) { + Some(file) => Ok(file), + None => Err(~"error opening file"), + } + } None => Err(format!("could not find terminfo entry for {}", term)) } } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 3d6dfd612f254..f8739e30db408 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -944,7 +944,8 @@ impl MetricMap { /// Write MetricDiff to a file. pub fn save(&self, p: &Path) { - self.to_json().to_pretty_writer(@mut File::create(p) as @mut io::Writer); + let mut file = File::create(p); + self.to_json().to_pretty_writer(&mut file) } /// Compare against another MetricMap. Optionally compare all diff --git a/src/libextra/uuid.rs b/src/libextra/uuid.rs index cf40a59a8c507..ef6c9e7f9cd5e 100644 --- a/src/libextra/uuid.rs +++ b/src/libextra/uuid.rs @@ -796,8 +796,8 @@ mod test { use serialize::{Encodable, Decodable}; let u = Uuid::new_v4(); - let wr = @mut MemWriter::new(); - u.encode(&mut ebml::writer::Encoder(wr)); + let mut wr = MemWriter::new(); + u.encode(&mut ebml::writer::Encoder(&mut wr)); let doc = ebml::reader::Doc(wr.inner_ref().as_slice()); let u2 = Decodable::decode(&mut ebml::reader::Decoder(doc)); assert_eq!(u, u2); diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 8713dbde9205a..874e3c70af046 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -173,8 +173,8 @@ impl Database { // FIXME #4330: This should have &mut self and should set self.db_dirty to false. fn save(&self) { - let f = @mut File::create(&self.db_filename); - self.db_cache.to_json().to_pretty_writer(f as @mut io::Writer); + let mut f = File::create(&self.db_filename); + self.db_cache.to_json().to_pretty_writer(&mut f); } fn load(&mut self) { @@ -184,14 +184,16 @@ impl Database { Err(e) => fail!("Couldn't load workcache database {}: {}", self.db_filename.display(), e.desc), - Ok(r) => - match json::from_reader(@mut r.unwrap() as @mut io::Reader) { + Ok(r) => { + let mut stream = r.unwrap(); + match json::from_reader(&mut stream) { Err(e) => fail!("Couldn't parse workcache database (from file {}): {}", self.db_filename.display(), e.to_str()), Ok(r) => { let mut decoder = json::Decoder::new(r); self.db_cache = Decodable::decode(&mut decoder); } + } } } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index b0fa22f817288..5cbf04f6e52f6 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -464,9 +464,19 @@ fn write_out_deps(sess: Session, input: &input, outputs: &OutputFilenames, crate // Build a list of files used to compile the output and // write Makefile-compatible dependency rules - let files: ~[@str] = sess.codemap.files.iter() - .filter_map(|fmap| if fmap.is_real_file() { Some(fmap.name) } else { None }) - .collect(); + let files: ~[@str] = { + let files = sess.codemap.files.borrow(); + files.get() + .iter() + .filter_map(|fmap| { + if fmap.is_real_file() { + Some(fmap.name) + } else { + None + } + }) + .collect() + }; let mut file = io::File::create(&deps_filename); for path in out_filenames.iter() { write!(&mut file as &mut Writer, @@ -517,20 +527,20 @@ impl pprust::pp_ann for IdentifiedAnnotation { fn post(&self, node: pprust::ann_node) { match node { pprust::node_item(s, item) => { - pp::space(s.s); + pp::space(&mut s.s); pprust::synth_comment(s, item.id.to_str()); } - pprust::node_block(s, ref blk) => { - pp::space(s.s); + pprust::node_block(s, blk) => { + pp::space(&mut s.s); pprust::synth_comment(s, ~"block " + blk.id.to_str()); } pprust::node_expr(s, expr) => { - pp::space(s.s); + pp::space(&mut s.s); pprust::synth_comment(s, expr.id.to_str()); pprust::pclose(s); } pprust::node_pat(s, pat) => { - pp::space(s.s); + pp::space(&mut s.s); pprust::synth_comment(s, ~"pat " + pat.id.to_str()); } } @@ -552,10 +562,10 @@ impl pprust::pp_ann for TypedAnnotation { let tcx = self.analysis.ty_cx; match node { pprust::node_expr(s, expr) => { - pp::space(s.s); - pp::word(s.s, "as"); - pp::space(s.s); - pp::word(s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr))); + pp::space(&mut s.s); + pp::word(&mut s.s, "as"); + pp::space(&mut s.s); + pp::word(&mut s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr))); pprust::pclose(s); } _ => () @@ -592,15 +602,15 @@ pub fn pretty_print_input(sess: Session, }; let src = sess.codemap.get_filemap(source_name(input)).src; - let rdr = @mut MemReader::new(src.as_bytes().to_owned()); + let mut rdr = MemReader::new(src.as_bytes().to_owned()); let stdout = io::stdout(); pprust::print_crate(sess.codemap, token::get_ident_interner(), sess.span_diagnostic, &crate, source_name(input), - rdr as @mut io::Reader, - @mut stdout as @mut io::Writer, + &mut rdr, + ~stdout as ~io::Writer, annotation, is_expanded); } @@ -883,7 +893,7 @@ pub fn build_session(sopts: @session::options, demitter: @diagnostic::Emitter) pub fn build_session_(sopts: @session::options, cm: @codemap::CodeMap, demitter: @diagnostic::Emitter, - span_diagnostic_handler: @mut diagnostic::span_handler) + span_diagnostic_handler: @diagnostic::span_handler) -> Session { let target_cfg = build_target_config(sopts, demitter); let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler, diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 63ccc91cd556d..35eb7f18238a4 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -204,12 +204,12 @@ pub struct Session_ { targ_cfg: @config, opts: @options, cstore: @metadata::cstore::CStore, - parse_sess: @mut ParseSess, + parse_sess: @ParseSess, codemap: @codemap::CodeMap, // For a library crate, this is always none entry_fn: RefCell>, entry_type: Cell>, - span_diagnostic: @mut diagnostic::span_handler, + span_diagnostic: @diagnostic::span_handler, filesearch: @filesearch::FileSearch, building_library: Cell, working_dir: Path, @@ -292,7 +292,7 @@ impl Session_ { v } - pub fn diagnostic(&self) -> @mut diagnostic::span_handler { + pub fn diagnostic(&self) -> @diagnostic::span_handler { self.span_diagnostic } pub fn debugging_opt(&self, opt: uint) -> bool { diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 8fa1e5563947f..4ed48a9141255 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -86,7 +86,7 @@ fn dump_crates(crate_cache: &[cache_entry]) { } fn warn_if_multiple_versions(e: &mut Env, - diag: @mut span_handler, + diag: @span_handler, crate_cache: &[cache_entry]) { if crate_cache.len() != 0u { let name = crate_cache[crate_cache.len() - 1].crateid.name.clone(); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 73b0ac46cbda9..cf152319b1948 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -57,7 +57,7 @@ pub type encode_inlined_item<'a> = 'a |ecx: &EncodeContext, ii: ast::inlined_item|; pub struct EncodeParams<'a> { - diag: @mut span_handler, + diag: @span_handler, tcx: ty::ctxt, reexports2: middle::resolve::ExportMap2, item_symbols: &'a RefCell>, @@ -83,7 +83,7 @@ struct Stats { } pub struct EncodeContext<'a> { - diag: @mut span_handler, + diag: @span_handler, tcx: ty::ctxt, stats: @Stats, reexports2: middle::resolve::ExportMap2, @@ -489,7 +489,8 @@ fn encode_reexported_static_methods(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, mod_path: &[ast_map::path_elt], exp: &middle::resolve::Export2) { - match ecx.tcx.items.find(&exp.def_id.node) { + let items = ecx.tcx.items.borrow(); + match items.get().find(&exp.def_id.node) { Some(&ast_map::node_item(item, path)) => { let original_name = ecx.tcx.sess.str_of(item.ident); @@ -1338,7 +1339,8 @@ fn my_visit_item(i: @item, ebml_w: &mut writer::Encoder, ecx_ptr: *int, index: @RefCell<~[entry]>) { - match items.get_copy(&i.id) { + let items = items.borrow(); + match items.get().get_copy(&i.id) { ast_map::node_item(_, pt) => { let mut ebml_w = unsafe { ebml_w.unsafe_clone() @@ -1356,7 +1358,8 @@ fn my_visit_foreign_item(ni: @foreign_item, ebml_w: &mut writer::Encoder, ecx_ptr:*int, index: @RefCell<~[entry]>) { - match items.get_copy(&ni.id) { + let items = items.borrow(); + match items.get().get_copy(&ni.id) { ast_map::node_foreign_item(_, abi, _, pt) => { debug!("writing foreign item {}::{}", ast_map::path_to_str( diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 481a43d1cedd2..ff627d389c30b 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -231,8 +231,7 @@ impl Context { } } -pub fn note_crateid_attr(diag: @mut span_handler, - crateid: &CrateId) { +pub fn note_crateid_attr(diag: @span_handler, crateid: &CrateId) { diag.handler().note(format!("crate_id: {}", crateid.to_str())); } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 1f9f1e1856537..34d12f5ae6f4d 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -32,7 +32,7 @@ macro_rules! mywrite( ($wr:expr, $($arg:tt)*) => ( ) ) pub struct ctxt { - diag: @mut span_handler, + diag: @span_handler, // Def -> str Callback: ds: extern "Rust" fn(DefId) -> ~str, // The type context. diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 90825289ac39f..8e52ca479b1a1 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1429,18 +1429,18 @@ fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item { #[cfg(test)] trait fake_ext_ctxt { fn cfg(&self) -> ast::CrateConfig; - fn parse_sess(&self) -> @mut parse::ParseSess; + fn parse_sess(&self) -> @parse::ParseSess; fn call_site(&self) -> Span; fn ident_of(&self, st: &str) -> ast::Ident; } #[cfg(test)] -type fake_session = @mut parse::ParseSess; +type fake_session = @parse::ParseSess; #[cfg(test)] impl fake_ext_ctxt for fake_session { fn cfg(&self) -> ast::CrateConfig { ~[] } - fn parse_sess(&self) -> @mut parse::ParseSess { *self } + fn parse_sess(&self) -> @parse::ParseSess { *self } fn call_site(&self) -> Span { codemap::Span { lo: codemap::BytePos(0), diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index ddc31598d6740..44b967aade677 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -788,7 +788,8 @@ impl BorrowckCtxt { out: &mut ~str) { match *loan_path { LpVar(id) => { - match self.tcx.items.find(&id) { + let items = self.tcx.items.borrow(); + match items.get().find(&id) { Some(&ast_map::node_local(ref ident)) => { out.push_str(token::ident_to_str(ident)); } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 4dfdd00c27ad6..a6a51e9508351 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -266,13 +266,15 @@ impl Visitor<()> for CheckItemRecursionVisitor { let def_map = self.env.def_map.borrow(); match def_map.get().find(&e.id) { Some(&DefStatic(def_id, _)) if - ast_util::is_local(def_id) => - match self.env.ast_map.get_copy(&def_id.node) { + ast_util::is_local(def_id) => { + let ast_map = self.env.ast_map.borrow(); + match ast_map.get().get_copy(&def_id.node) { ast_map::node_item(it, _) => { self.visit_item(it, ()); } _ => fail!("const not bound to an item") - }, + } + } _ => () } }, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index d0dd36cda9605..b9b0b807e6ed9 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -107,15 +107,18 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt, } if ast_util::is_local(enum_def) { - match tcx.items.find(&enum_def.node) { - None => None, - Some(&ast_map::node_item(it, _)) => match it.node { - item_enum(ast::enum_def { variants: ref variants }, _) => { - variant_expr(*variants, variant_def.node) - } - _ => None - }, - Some(_) => None + { + let items = tcx.items.borrow(); + match items.get().find(&enum_def.node) { + None => None, + Some(&ast_map::node_item(it, _)) => match it.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + Some(_) => None + } } } else { { @@ -155,17 +158,21 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt, } } -pub fn lookup_const_by_id(tcx: ty::ctxt, - def_id: ast::DefId) - -> Option<@Expr> { +pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::DefId) + -> Option<@Expr> { if ast_util::is_local(def_id) { - match tcx.items.find(&def_id.node) { - None => None, - Some(&ast_map::node_item(it, _)) => match it.node { - item_static(_, ast::MutImmutable, const_expr) => Some(const_expr), - _ => None - }, - Some(_) => None + { + let items = tcx.items.borrow(); + match items.get().find(&def_id.node) { + None => None, + Some(&ast_map::node_item(it, _)) => match it.node { + item_static(_, ast::MutImmutable, const_expr) => { + Some(const_expr) + } + _ => None + }, + Some(_) => None + } } } else { { diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 142c69a5233ef..b0ca03181f8d1 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -118,7 +118,7 @@ impl pprust::pp_ann for DataFlowContext { let comment_str = format!("id {}: {}{}{}", id, entry_str, gens_str, kills_str); pprust::synth_comment(ps, comment_str); - pp::space(ps.s); + pp::space(&mut ps.s); } } } @@ -347,19 +347,19 @@ impl DataFlowContext { debug!("Dataflow result:"); debug!("{}", { let this = @(*self).clone(); - this.pretty_print_to(@mut io::stderr() as @mut io::Writer, blk); + this.pretty_print_to(~io::stderr() as ~io::Writer, blk); "" }); } - fn pretty_print_to(@self, wr: @mut io::Writer, blk: &ast::Block) { - let ps = pprust::rust_printer_annotated(wr, - self.tcx.sess.intr(), - self as @pprust::pp_ann); - pprust::cbox(ps, pprust::indent_unit); - pprust::ibox(ps, 0u); - pprust::print_block(ps, blk); - pp::eof(ps.s); + fn pretty_print_to(@self, wr: ~io::Writer, blk: &ast::Block) { + let mut ps = pprust::rust_printer_annotated(wr, + self.tcx.sess.intr(), + self as @pprust::pp_ann); + pprust::cbox(&mut ps, pprust::indent_unit); + pprust::ibox(&mut ps, 0u); + pprust::print_block(&mut ps, blk); + pp::eof(&mut ps.s); } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index d26954ad45856..3536ffec56d84 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -34,7 +34,9 @@ fn should_explore(tcx: ty::ctxt, def_id: ast::DefId) -> bool { if !is_local(def_id) { return false; } - match tcx.items.find(&def_id.node) { + + let items = tcx.items.borrow(); + match items.get().find(&def_id.node) { Some(&ast_map::node_item(..)) | Some(&ast_map::node_method(..)) | Some(&ast_map::node_foreign_item(..)) @@ -92,7 +94,9 @@ impl MarkSymbolVisitor { continue } scanned.insert(id); - match self.tcx.items.find(&id) { + + let items = self.tcx.items.borrow(); + match items.get().find(&id) { Some(node) => { self.live_symbols.insert(id); self.visit_node(node); diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 53a8b93c232da..89cb902cf1064 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -74,23 +74,26 @@ fn find_item(item: @item, ctxt: &mut EntryContext) { match item.node { item_fn(..) => { if item.ident.name == special_idents::main.name { - match ctxt.ast_map.find(&item.id) { - Some(&ast_map::node_item(_, path)) => { - if path.len() == 0 { - // This is a top-level function so can be 'main' - if ctxt.main_fn.is_none() { - ctxt.main_fn = Some((item.id, item.span)); + { + let ast_map = ctxt.ast_map.borrow(); + match ast_map.get().find(&item.id) { + Some(&ast_map::node_item(_, path)) => { + if path.len() == 0 { + // This is a top-level function so can be 'main' + if ctxt.main_fn.is_none() { + ctxt.main_fn = Some((item.id, item.span)); + } else { + ctxt.session.span_err( + item.span, + "multiple 'main' functions"); + } } else { - ctxt.session.span_err( - item.span, - "multiple 'main' functions"); + // This isn't main + ctxt.non_main_fns.push((item.id, item.span)); } - } else { - // This isn't main - ctxt.non_main_fns.push((item.id, item.span)); } + _ => unreachable!() } - _ => unreachable!() } } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index d94bfe1447e01..90b67ba2da73c 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -1238,7 +1238,8 @@ fn check_stability(cx: &Context, e: &ast::Expr) { let stability = if ast_util::is_local(id) { // this crate - match cx.tcx.items.find(&id.node) { + let items = cx.tcx.items.borrow(); + match items.get().find(&id.node) { Some(ast_node) => { let s = ast_node.with_attrs(|attrs| { attrs.map(|a| { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 707446a78fe21..2540471113f09 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -390,7 +390,8 @@ impl<'a> PrivacyVisitor<'a> { let mut closest_private_id = did.node; loop { debug!("privacy - examining {}", self.nodestr(closest_private_id)); - let vis = match self.tcx.items.find(&closest_private_id) { + let items = self.tcx.items.borrow(); + let vis = match items.get().find(&closest_private_id) { // If this item is a method, then we know for sure that it's an // actual method and not a static method. The reason for this is // that these cases are only hit in the ExprMethodCall @@ -496,7 +497,8 @@ impl<'a> PrivacyVisitor<'a> { self.tcx.sess.span_err(span, format!("{} is inaccessible", msg)); } - match self.tcx.items.find(&id) { + let items = self.tcx.items.borrow(); + match items.get().find(&id) { Some(&ast_map::node_item(item, _)) => { let desc = match item.node { ast::item_mod(..) => "module", diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index bbf366c0b061f..5e50017b93edd 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -65,10 +65,15 @@ fn method_might_be_inlined(tcx: ty::ctxt, method: &ast::method, return true } if is_local(impl_src) { - match tcx.items.find(&impl_src.node) { - Some(&ast_map::node_item(item, _)) => item_might_be_inlined(item), - Some(..) | None => { - tcx.sess.span_bug(method.span, "impl did is not an item") + { + let items = tcx.items.borrow(); + match items.get().find(&impl_src.node) { + Some(&ast_map::node_item(item, _)) => { + item_might_be_inlined(item) + } + Some(..) | None => { + tcx.sess.span_bug(method.span, "impl did is not an item") + } } } } else { @@ -208,7 +213,8 @@ impl ReachableContext { } let node_id = def_id.node; - match tcx.items.find(&node_id) { + let items = tcx.items.borrow(); + match items.get().find(&node_id) { Some(&ast_map::node_item(item, _)) => { match item.node { ast::item_fn(..) => item_might_be_inlined(item), @@ -229,7 +235,7 @@ impl ReachableContext { // Check the impl. If the generics on the self type of the // impl require inlining, this method does too. assert!(impl_did.crate == ast::LOCAL_CRATE); - match tcx.items.find(&impl_did.node) { + match items.get().find(&impl_did.node) { Some(&ast_map::node_item(item, _)) => { match item.node { ast::item_impl(ref generics, _, _, _) => { @@ -288,7 +294,8 @@ impl ReachableContext { }; scanned.insert(search_item); - match self.tcx.items.find(&search_item) { + let items = self.tcx.items.borrow(); + match items.get().find(&search_item) { Some(item) => self.propagate_node(item, search_item, &mut visitor), None if search_item == ast::CRATE_NODE_ID => {} diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index ce953ab3ab70f..315cdcd1b5f58 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2210,10 +2210,13 @@ impl Visitor<()> for TransItemVisitor { pub fn trans_item(ccx: @CrateContext, item: &ast::item) { let _icx = push_ctxt("trans_item"); - let path = match ccx.tcx.items.get_copy(&item.id) { - ast_map::node_item(_, p) => p, - // tjc: ? - _ => fail!("trans_item"), + let path = { + let items = ccx.tcx.items.borrow(); + match items.get().get_copy(&item.id) { + ast_map::node_item(_, p) => p, + // tjc: ? + _ => fail!("trans_item"), + } }; match item.node { ast::item_fn(decl, purity, _abis, ref generics, body) => { @@ -2508,7 +2511,10 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef { Some(v) => v, None => { let mut foreign = false; - let item = ccx.tcx.items.get_copy(&id); + let item = { + let items = ccx.tcx.items.borrow(); + items.get().get_copy(&id) + }; let val = match item { ast_map::node_item(i, pth) => { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index df916f0463bce..05b3e8275a3a4 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -360,17 +360,20 @@ pub fn trans_fn_ref_with_vtables( if type_params.len() > 0 || is_default { must_monomorphise = true; } else if def_id.crate == ast::LOCAL_CRATE { - let map_node = session::expect( - ccx.sess, - ccx.tcx.items.find(&def_id.node), - || format!("local item should be in ast map")); - - match *map_node { - ast_map::node_foreign_item(_, abis, _, _) => { - must_monomorphise = abis.is_intrinsic() - } - _ => { - must_monomorphise = false; + { + let items = ccx.tcx.items.borrow(); + let map_node = session::expect( + ccx.sess, + items.get().find(&def_id.node), + || format!("local item should be in ast map")); + + match *map_node { + ast_map::node_foreign_item(_, abis, _, _) => { + must_monomorphise = abis.is_intrinsic() + } + _ => { + must_monomorphise = false; + } } } } else { diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index c9d30ec19945d..0dd8b841bcf42 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -165,7 +165,13 @@ pub fn get_const_val(cx: @CrateContext, if !ast_util::is_local(def_id) { def_id = inline::maybe_instantiate_inline(cx, def_id); } - match cx.tcx.items.get_copy(&def_id.node) { + + let opt_item = { + let items = cx.tcx.items.borrow(); + items.get().get_copy(&def_id.node) + }; + + match opt_item { ast_map::node_item(@ast::item { node: ast::item_static(_, ast::MutImmutable, _), .. }, _) => { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 3e9aae4730e34..486eb6fd25fcb 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -323,7 +323,10 @@ pub fn create_captured_var_metadata(bcx: @Block, let cx = bcx.ccx(); - let ast_item = cx.tcx.items.find_copy(&node_id); + let ast_item = { + let items = cx.tcx.items.borrow(); + items.get().find_copy(&node_id) + }; let variable_ident = match ast_item { None => { cx.sess.span_bug(span, "debuginfo::create_captured_var_metadata() - NodeId not found"); @@ -422,7 +425,10 @@ pub fn create_self_argument_metadata(bcx: @Block, } // Extract the span of the self argument from the method's AST - let fnitem = bcx.ccx().tcx.items.get_copy(&bcx.fcx.id); + let fnitem = { + let items = bcx.ccx().tcx.items.borrow(); + items.get().get_copy(&bcx.fcx.id) + }; let span = match fnitem { ast_map::node_method(@ast::method { explicit_self: explicit_self, .. }, _, _) => { explicit_self.span @@ -609,7 +615,10 @@ pub fn create_function_debug_context(cx: &CrateContext, let empty_generics = ast::Generics { lifetimes: opt_vec::Empty, ty_params: opt_vec::Empty }; - let fnitem = cx.tcx.items.get_copy(&fn_ast_id); + let fnitem = { + let items = cx.tcx.items.borrow(); + items.get().get_copy(&fn_ast_id) + }; let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem { ast_map::node_item(ref item, _) => { match item.node { @@ -1092,7 +1101,8 @@ fn scope_metadata(fcx: &FunctionContext, match scope_map.get().find_copy(&node_id) { Some(scope_metadata) => scope_metadata, None => { - let node = fcx.ccx.tcx.items.get_copy(&node_id); + let items = fcx.ccx.tcx.items.borrow(); + let node = items.get().get_copy(&node_id); fcx.ccx.sess.span_bug(span, format!("debuginfo: Could not find scope info for node {:?}", node)); @@ -1413,13 +1423,17 @@ fn describe_variant(cx: &CrateContext, // Find the source code location of the variant's definition let variant_definition_span = if variant_info.id.crate == ast::LOCAL_CRATE { - match cx.tcx.items.find(&variant_info.id.node) { - Some(&ast_map::node_variant(ref variant, _, _)) => variant.span, - ref node => { - cx.sess.span_warn(span, - format!("debuginfo::enum_metadata()::adt_struct_metadata() - Unexpected node \ - type: {:?}. This is a bug.", node)); - codemap::dummy_sp() + { + let items = cx.tcx.items.borrow(); + match items.get().find(&variant_info.id.node) { + Some(&ast_map::node_variant(ref variant, _, _)) => variant.span, + ref node => { + cx.sess.span_warn(span, + format!("debuginfo::enum_metadata()::\ + adt_struct_metadata() - Unexpected node \ + type: {:?}. This is a bug.", node)); + codemap::dummy_sp() + } } } } else { @@ -2288,16 +2302,20 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, -> (DIScope, Span) { let containing_scope = namespace_for_item(cx, def_id, warning_span).scope; let definition_span = if def_id.crate == ast::LOCAL_CRATE { - let definition_span = match cx.tcx.items.find(&def_id.node) { - Some(&ast_map::node_item(@ast::item { span, .. }, _)) => span, - ref node => { - cx.sess.span_warn(warning_span, - format!("debuginfo::get_namespace_and_span_for_item() \ - - Unexpected node type: {:?}", *node)); - codemap::dummy_sp() - } - }; - definition_span + { + let items = cx.tcx.items.borrow(); + let definition_span = match items.get().find(&def_id.node) { + Some(&ast_map::node_item(@ast::item { span, .. }, _)) => span, + ref node => { + cx.sess.span_warn(warning_span, + format!("debuginfo::\ + get_namespace_and_span_for_item() \ + - Unexpected node type: {:?}", *node)); + codemap::dummy_sp() + } + }; + definition_span + } } else { // For external items there is no span information codemap::dummy_sp() diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 21f268fb9471f..7c4c9f8937f05 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -355,10 +355,17 @@ pub fn trans_foreign_mod(ccx: @CrateContext, for &foreign_item in foreign_mod.items.iter() { match foreign_item.node { ast::foreign_item_fn(..) => { - let (abis, mut path) = match ccx.tcx.items.get_copy(&foreign_item.id) { - ast_map::node_foreign_item(_, abis, _, path) => (abis, (*path).clone()), - _ => fail!("Unable to find foreign item in tcx.items table.") - }; + let items = ccx.tcx.items.borrow(); + let (abis, mut path) = + match items.get().get_copy(&foreign_item.id) { + ast_map::node_foreign_item(_, abis, _, path) => { + (abis, (*path).clone()) + } + _ => { + fail!("Unable to find foreign item in tcx.items \ + table.") + } + }; if !(abis.is_rust() || abis.is_intrinsic()) { path.push(ast_map::path_name(foreign_item.ident)); register_foreign_item_fn(ccx, abis, &path, foreign_item); diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index f652fbec228cc..c1096f7332235 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -346,9 +346,12 @@ pub fn trans_intrinsic(ccx: @CrateContext, let in_type_size = machine::llbitsize_of_real(ccx, llintype); let out_type_size = machine::llbitsize_of_real(ccx, llouttype); if in_type_size != out_type_size { - let sp = match ccx.tcx.items.get_copy(&ref_id.unwrap()) { - ast_map::node_expr(e) => e.span, - _ => fail!("transmute has non-expr arg"), + let sp = { + let items = ccx.tcx.items.borrow(); + match items.get().get_copy(&ref_id.unwrap()) { + ast_map::node_expr(e) => e.span, + _ => fail!("transmute has non-expr arg"), + } }; let pluralize = |n| if 1u == n { "" } else { "s" }; ccx.sess.span_fatal(sp, diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index d16cf6f1c3b27..d54dd23af96a6 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -246,11 +246,14 @@ pub fn trans_static_method_callee(bcx: @Block, generics.type_param_defs.len(); let mname = if method_id.crate == ast::LOCAL_CRATE { - match bcx.tcx().items.get_copy(&method_id.node) { - ast_map::node_trait_method(trait_method, _, _) => { - ast_util::trait_method_to_ty_method(trait_method).ident + { + let items = bcx.tcx().items.borrow(); + match items.get().get_copy(&method_id.node) { + ast_map::node_trait_method(trait_method, _, _) => { + ast_util::trait_method_to_ty_method(trait_method).ident + } + _ => fail!("callee is not a trait method") } - _ => fail!("callee is not a trait method") } } else { let path = csearch::get_item_path(bcx.tcx(), method_id); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index cf6bebbb1a2a7..a60ddc9d8b61f 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -95,12 +95,16 @@ pub fn monomorphic_fn(ccx: @CrateContext, // calling a static provided method. This is sort of unfortunate. let mut is_static_provided = None; - let map_node = session::expect( - ccx.sess, - ccx.tcx.items.find_copy(&fn_id.node), - || format!("While monomorphizing {:?}, couldn't find it in the item map \ - (may have attempted to monomorphize an item \ - defined in a different crate?)", fn_id)); + let map_node = { + let items = ccx.tcx.items.borrow(); + session::expect( + ccx.sess, + items.get().find_copy(&fn_id.node), + || format!("While monomorphizing {:?}, couldn't find it in the \ + item map (may have attempted to monomorphize an item \ + defined in a different crate?)", fn_id)) + }; + // Get the path so that we can create a symbol let (pt, name, span) = match map_node { ast_map::node_item(i, pt) => (pt, i.ident, i.span), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a3c2e2a4404af..93071f134cb8a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -267,7 +267,7 @@ pub type ctxt = @ctxt_; /// generates so that so that it can be reused and doesn't have to be redone /// later on. struct ctxt_ { - diag: @mut syntax::diagnostic::span_handler, + diag: @syntax::diagnostic::span_handler, interner: RefCell>, next_id: Cell, cstore: @metadata::cstore::CStore, @@ -3556,16 +3556,19 @@ pub fn provided_source(cx: ctxt, id: ast::DefId) -> Option { pub fn provided_trait_methods(cx: ctxt, id: ast::DefId) -> ~[@Method] { if is_local(id) { - match cx.items.find(&id.node) { - Some(&ast_map::node_item(@ast::item { - node: item_trait(_, _, ref ms), - .. - }, _)) => - match ast_util::split_trait_methods(*ms) { - (_, p) => p.map(|m| method(cx, ast_util::local_def(m.id))) - }, - _ => cx.sess.bug(format!("provided_trait_methods: {:?} is not a trait", - id)) + { + let items = cx.items.borrow(); + match items.get().find(&id.node) { + Some(&ast_map::node_item(@ast::item { + node: item_trait(_, _, ref ms), + .. + }, _)) => + match ast_util::split_trait_methods(*ms) { + (_, p) => p.map(|m| method(cx, ast_util::local_def(m.id))) + }, + _ => cx.sess.bug(format!("provided_trait_methods: {:?} is not a trait", + id)) + } } } else { csearch::get_provided_trait_methods(cx, id) @@ -3675,17 +3678,20 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::DefId) -> Option<@TraitRef> { let ret = if id.crate == ast::LOCAL_CRATE { debug!("(impl_trait_ref) searching for trait impl {:?}", id); - match cx.items.find(&id.node) { - Some(&ast_map::node_item(@ast::item { - node: ast::item_impl(_, ref opt_trait, _, _), - ..}, - _)) => { - match opt_trait { - &Some(ref t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), - &None => None + { + let items = cx.items.borrow(); + match items.get().find(&id.node) { + Some(&ast_map::node_item(@ast::item { + node: ast::item_impl(_, ref opt_trait, _, _), + ..}, + _)) => { + match opt_trait { + &Some(ref t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)), + &None => None + } } + _ => None } - _ => None } } else { csearch::get_impl_trait(cx, id) @@ -3857,54 +3863,55 @@ pub fn has_dtor(cx: ctxt, struct_id: DefId) -> bool { pub fn item_path(cx: ctxt, id: ast::DefId) -> ast_map::path { if id.crate != ast::LOCAL_CRATE { - csearch::get_item_path(cx, id) - } else { - // FIXME (#5521): uncomment this code and don't have a catch-all at the - // end of the match statement. Favor explicitly listing - // each variant. - // let node = cx.items.get(&id.node); - // match *node { - match *cx.items.get(&id.node) { - ast_map::node_item(item, path) => { - let item_elt = match item.node { - item_mod(_) | item_foreign_mod(_) => { - ast_map::path_mod(item.ident) - } - _ => { - ast_map::path_name(item.ident) - } - }; - vec::append_one((*path).clone(), item_elt) + return csearch::get_item_path(cx, id) + } + + // FIXME (#5521): uncomment this code and don't have a catch-all at the + // end of the match statement. Favor explicitly listing + // each variant. + // let node = cx.items.get(&id.node); + // match *node { + let items = cx.items.borrow(); + match *items.get().get(&id.node) { + ast_map::node_item(item, path) => { + let item_elt = match item.node { + item_mod(_) | item_foreign_mod(_) => { + ast_map::path_mod(item.ident) } - - ast_map::node_foreign_item(nitem, _, _, path) => { - vec::append_one((*path).clone(), - ast_map::path_name(nitem.ident)) + _ => { + ast_map::path_name(item.ident) } + }; + vec::append_one((*path).clone(), item_elt) + } - ast_map::node_method(method, _, path) => { - vec::append_one((*path).clone(), - ast_map::path_name(method.ident)) - } - ast_map::node_trait_method(trait_method, _, path) => { - let method = ast_util::trait_method_to_ty_method(&*trait_method); - vec::append_one((*path).clone(), - ast_map::path_name(method.ident)) - } + ast_map::node_foreign_item(nitem, _, _, path) => { + vec::append_one((*path).clone(), + ast_map::path_name(nitem.ident)) + } - ast_map::node_variant(ref variant, _, path) => { - vec::append_one(path.init().to_owned(), - ast_map::path_name((*variant).node.name)) - } + ast_map::node_method(method, _, path) => { + vec::append_one((*path).clone(), + ast_map::path_name(method.ident)) + } + ast_map::node_trait_method(trait_method, _, path) => { + let method = ast_util::trait_method_to_ty_method(&*trait_method); + vec::append_one((*path).clone(), + ast_map::path_name(method.ident)) + } - ast_map::node_struct_ctor(_, item, path) => { - vec::append_one((*path).clone(), ast_map::path_name(item.ident)) - } + ast_map::node_variant(ref variant, _, path) => { + vec::append_one(path.init().to_owned(), + ast_map::path_name((*variant).node.name)) + } - ref node => { - cx.sess.bug(format!("cannot find item_path for node {:?}", node)); - } - } + ast_map::node_struct_ctor(_, item, path) => { + vec::append_one((*path).clone(), ast_map::path_name(item.ident)) + } + + ref node => { + cx.sess.bug(format!("cannot find item_path for node {:?}", node)); + } } } @@ -3936,40 +3943,43 @@ pub fn enum_variants(cx: ctxt, id: ast::DefId) -> @~[@VariantInfo] { call eval_const_expr, it should never get called twice for the same expr, since check_enum_variants also updates the enum_var_cache */ - match cx.items.get_copy(&id.node) { - ast_map::node_item(@ast::item { - node: ast::item_enum(ref enum_definition, _), - .. - }, _) => { - let mut last_discriminant: Option = None; - @enum_definition.variants.iter().map(|&variant| { - - let mut discriminant = match last_discriminant { - Some(val) => val + 1, - None => INITIAL_DISCRIMINANT_VALUE - }; - - match variant.node.disr_expr { - Some(e) => match const_eval::eval_const_expr_partial(&cx, e) { - Ok(const_eval::const_int(val)) => discriminant = val as Disr, - Ok(const_eval::const_uint(val)) => discriminant = val as Disr, - Ok(_) => { - cx.sess.span_err(e.span, "expected signed integer constant"); - } - Err(ref err) => { - cx.sess.span_err(e.span, format!("expected constant: {}", (*err))); - } - }, - None => {} - }; - - let variant_info = @VariantInfo::from_ast_variant(cx, variant, discriminant); - last_discriminant = Some(discriminant); - variant_info - - }).collect() - } - _ => cx.sess.bug("enum_variants: id not bound to an enum") + { + let items = cx.items.borrow(); + match items.get().get_copy(&id.node) { + ast_map::node_item(@ast::item { + node: ast::item_enum(ref enum_definition, _), + .. + }, _) => { + let mut last_discriminant: Option = None; + @enum_definition.variants.iter().map(|&variant| { + + let mut discriminant = match last_discriminant { + Some(val) => val + 1, + None => INITIAL_DISCRIMINANT_VALUE + }; + + match variant.node.disr_expr { + Some(e) => match const_eval::eval_const_expr_partial(&cx, e) { + Ok(const_eval::const_int(val)) => discriminant = val as Disr, + Ok(const_eval::const_uint(val)) => discriminant = val as Disr, + Ok(_) => { + cx.sess.span_err(e.span, "expected signed integer constant"); + } + Err(ref err) => { + cx.sess.span_err(e.span, format!("expected constant: {}", (*err))); + } + }, + None => {} + }; + + let variant_info = @VariantInfo::from_ast_variant(cx, variant, discriminant); + last_discriminant = Some(discriminant); + variant_info + + }).collect() + } + _ => cx.sess.bug("enum_variants: id not bound to an enum") + } } }; @@ -4040,11 +4050,17 @@ pub fn lookup_trait_def(cx: ctxt, did: ast::DefId) -> @ty::TraitDef { // decoder to use iterators instead of higher-order functions.) pub fn each_attr(tcx: ctxt, did: DefId, f: |@MetaItem| -> bool) -> bool { if is_local(did) { - match tcx.items.find(&did.node) { - Some(&ast_map::node_item(@ast::item {attrs: ref attrs, ..}, _)) => - attrs.iter().advance(|attr| f(attr.node.value)), - _ => tcx.sess.bug(format!("has_attr: {:?} is not an item", - did)) + { + let items = tcx.items.borrow(); + match items.get().find(&did.node) { + Some(&ast_map::node_item(@ast::item { + attrs: ref attrs, + .. + }, _)) => + attrs.iter().advance(|attr| f(attr.node.value)), + _ => tcx.sess.bug(format!("has_attr: {:?} is not an item", + did)) + } } } else { let mut cont = true; @@ -4120,37 +4136,39 @@ pub fn lookup_field_type(tcx: ctxt, // Fails if the id is not bound to a struct. pub fn lookup_struct_fields(cx: ctxt, did: ast::DefId) -> ~[field_ty] { if did.crate == ast::LOCAL_CRATE { - match cx.items.find(&did.node) { - Some(&ast_map::node_item(i,_)) => { - match i.node { - ast::item_struct(struct_def, _) => { - struct_field_tys(struct_def.fields) - } - _ => cx.sess.bug("struct ID bound to non-struct") - } - } - Some(&ast_map::node_variant(ref variant, _, _)) => { - match (*variant).node.kind { - ast::struct_variant_kind(struct_def) => { - struct_field_tys(struct_def.fields) - } - _ => { - cx.sess.bug("struct ID bound to enum variant that isn't \ - struct-like") - } + { + let items = cx.items.borrow(); + match items.get().find(&did.node) { + Some(&ast_map::node_item(i,_)) => { + match i.node { + ast::item_struct(struct_def, _) => { + struct_field_tys(struct_def.fields) + } + _ => cx.sess.bug("struct ID bound to non-struct") + } + } + Some(&ast_map::node_variant(ref variant, _, _)) => { + match (*variant).node.kind { + ast::struct_variant_kind(struct_def) => { + struct_field_tys(struct_def.fields) + } + _ => { + cx.sess.bug("struct ID bound to enum variant that isn't \ + struct-like") + } + } + } + _ => { + cx.sess.bug( + format!("struct ID not bound to an item: {}", + ast_map::node_id_to_str(cx.items, did.node, + token::get_ident_interner()))); + } } - } - _ => { - cx.sess.bug( - format!("struct ID not bound to an item: {}", - ast_map::node_id_to_str(cx.items, did.node, - token::get_ident_interner()))); - } - } - } - else { - return csearch::get_struct_fields(cx.sess.cstore, did); - } + } + } else { + return csearch::get_struct_fields(cx.sess.cstore, did); + } } pub fn lookup_struct_field(cx: ctxt, @@ -4658,7 +4676,8 @@ pub fn populate_implementations_for_trait_if_necessary( /// If it implements no trait, return `None`. pub fn trait_id_of_impl(tcx: ctxt, def_id: ast::DefId) -> Option { - let node = match tcx.items.find(&def_id.node) { + let items = tcx.items.borrow(); + let node = match items.get().find(&def_id.node) { Some(node) => node, None => return None }; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 7fc2798c7aa6c..6e2afb1d2e7f7 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1309,10 +1309,17 @@ impl<'a> LookupContext<'a> { fn report_static_candidate(&self, idx: uint, did: DefId) { let span = if did.crate == ast::LOCAL_CRATE { - match self.tcx().items.find(&did.node) { - Some(&ast_map::node_method(m, _, _)) - | Some(&ast_map::node_trait_method(@ast::provided(m), _, _)) => m.span, - _ => fail!("report_static_candidate: bad item {:?}", did) + { + let items = self.tcx().items.borrow(); + match items.get().find(&did.node) { + Some(&ast_map::node_method(m, _, _)) + | Some(&ast_map::node_trait_method(@ast::provided(m), + _, + _)) => { + m.span + } + _ => fail!("report_static_candidate: bad item {:?}", did) + } } } else { self.expr.span diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 376af7e9d3dfa..235c15aacb9ca 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -569,10 +569,8 @@ impl CoherenceChecker { // Make sure that this type precisely names a nominal // type. - match self.crate_context - .tcx - .items - .find(&def_id.node) { + let items = self.crate_context.tcx.items.borrow(); + match items.get().find(&def_id.node) { None => { self.crate_context.tcx.sess.span_bug( original_type.span, @@ -629,7 +627,8 @@ impl CoherenceChecker { pub fn span_of_impl(&self, implementation: @Impl) -> Span { assert_eq!(implementation.did.crate, LOCAL_CRATE); - match self.crate_context.tcx.items.find(&implementation.did.node) { + let items = self.crate_context.tcx.items.borrow(); + match items.get().find(&implementation.did.node) { Some(&node_item(item, _)) => { return item.span; } @@ -733,14 +732,19 @@ impl CoherenceChecker { _ => { // Destructors only work on nominal types. if impl_info.did.crate == ast::LOCAL_CRATE { - match tcx.items.find(&impl_info.did.node) { - Some(&ast_map::node_item(@ref item, _)) => { - tcx.sess.span_err((*item).span, - "the Drop trait may only be implemented on \ - structures"); - } - _ => { - tcx.sess.bug("didn't find impl in ast map"); + { + let items = tcx.items.borrow(); + match items.get().find(&impl_info.did.node) { + Some(&ast_map::node_item(@ref item, _)) => { + tcx.sess.span_err((*item).span, + "the Drop trait may \ + only be implemented \ + on structures"); + } + _ => { + tcx.sess.bug("didn't find impl in ast \ + map"); + } } } } else { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 3dfcf15e0240b..410c94a9a67f3 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -106,19 +106,18 @@ impl AstConv for CrateCtxt { fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty { if id.crate != ast::LOCAL_CRATE { - csearch::get_type(self.tcx, id) - } else { - match self.tcx.items.find(&id.node) { - Some(&ast_map::node_item(item, _)) => { - ty_of_item(self, item) - } - Some(&ast_map::node_foreign_item(foreign_item, abis, _, _)) => { + return csearch::get_type(self.tcx, id) + } + + let items = self.tcx.items.borrow(); + match items.get().find(&id.node) { + Some(&ast_map::node_item(item, _)) => ty_of_item(self, item), + Some(&ast_map::node_foreign_item(foreign_item, abis, _, _)) => { ty_of_foreign_item(self, foreign_item, abis) - } - ref x => { + } + ref x => { self.tcx.sess.bug(format!("unexpected sort of item \ - in get_item_ty(): {:?}", (*x))); - } + in get_item_ty(): {:?}", (*x))); } } } @@ -187,7 +186,8 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) { let tcx = ccx.tcx; - match tcx.items.get_copy(&trait_id) { + let items = tcx.items.borrow(); + match items.get().get_copy(&trait_id) { ast_map::node_item(@ast::item { node: ast::item_trait(ref generics, _, ref ms), .. @@ -715,7 +715,8 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::foreign_item) { // map, and I regard each time that I use it as a personal and // moral failing, but at the moment it seems like the only // convenient way to extract the ABI. - ndm - let abis = match ccx.tcx.items.find(&i.id) { + let items = ccx.tcx.items.borrow(); + let abis = match items.get().find(&i.id) { Some(&ast_map::node_foreign_item(_, abis, _, _)) => abis, ref x => { ccx.tcx.sess.bug(format!("unexpected sort of item \ @@ -765,13 +766,14 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt, fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> @ty::TraitDef { if trait_id.crate != ast::LOCAL_CRATE { - ty::lookup_trait_def(ccx.tcx, trait_id) - } else { - match ccx.tcx.items.get(&trait_id.node) { - &ast_map::node_item(item, _) => trait_def_of_item(ccx, item), - _ => ccx.tcx.sess.bug(format!("get_trait_def({}): not an item", - trait_id.node)) - } + return ty::lookup_trait_def(ccx.tcx, trait_id) + } + + let items = ccx.tcx.items.borrow(); + match items.get().get(&trait_id.node) { + &ast_map::node_item(item, _) => trait_def_of_item(ccx, item), + _ => ccx.tcx.sess.bug(format!("get_trait_def({}): not an item", + trait_id.node)) } } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 835c739c0852b..982e2ca0685b2 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -350,7 +350,8 @@ fn check_main_fn_ty(ccx: &CrateCtxt, let main_t = ty::node_id_to_type(tcx, main_id); match ty::get(main_t).sty { ty::ty_bare_fn(..) => { - match tcx.items.find(&main_id) { + let items = tcx.items.borrow(); + match items.get().find(&main_id) { Some(&ast_map::node_item(it,_)) => { match it.node { ast::item_fn(_, _, _, ref ps, _) @@ -395,7 +396,8 @@ fn check_start_fn_ty(ccx: &CrateCtxt, let start_t = ty::node_id_to_type(tcx, start_id); match ty::get(start_t).sty { ty::ty_bare_fn(_) => { - match tcx.items.find(&start_id) { + let items = tcx.items.borrow(); + match items.get().find(&start_id) { Some(&ast_map::node_item(it,_)) => { match it.node { ast::item_fn(_,_,_,ref ps,_) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index ac88018a3c41f..ee77685cf5a12 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -72,7 +72,8 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region) -> (~str, Option) { return match region { ReScope(node_id) => { - match cx.items.find(&node_id) { + let items = cx.items.borrow(); + match items.get().find(&node_id) { Some(&ast_map::node_block(ref blk)) => { explain_span(cx, "block", blk.span) } @@ -113,7 +114,8 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region) bound_region_ptr_to_str(cx, fr.bound_region)) }; - match cx.items.find(&fr.scope_id) { + let items = cx.items.borrow(); + match items.get().find(&fr.scope_id) { Some(&ast_map::node_block(ref blk)) => { let (msg, opt_span) = explain_span(cx, "block", blk.span); (format!("{} {}", prefix, msg), opt_span) @@ -172,7 +174,8 @@ pub fn bound_region_to_str(cx: ctxt, } pub fn ReScope_id_to_str(cx: ctxt, node_id: ast::NodeId) -> ~str { - match cx.items.find(&node_id) { + let items = cx.items.borrow(); + match items.get().find(&node_id) { Some(&ast_map::node_block(ref blk)) => { format!("", cx.sess.codemap.span_to_str(blk.span)) @@ -740,16 +743,21 @@ impl Repr for ast::DefId { // a path for a def-id, so I'll just make a best effort for now // and otherwise fallback to just printing the crate/node pair if self.crate == ast::LOCAL_CRATE { - match tcx.items.find(&self.node) { - Some(&ast_map::node_item(..)) | - Some(&ast_map::node_foreign_item(..)) | - Some(&ast_map::node_method(..)) | - Some(&ast_map::node_trait_method(..)) | - Some(&ast_map::node_variant(..)) | - Some(&ast_map::node_struct_ctor(..)) => { - return format!("{:?}:{}", *self, ty::item_path_str(tcx, *self)); + { + let items = tcx.items.borrow(); + match items.get().find(&self.node) { + Some(&ast_map::node_item(..)) | + Some(&ast_map::node_foreign_item(..)) | + Some(&ast_map::node_method(..)) | + Some(&ast_map::node_trait_method(..)) | + Some(&ast_map::node_variant(..)) | + Some(&ast_map::node_struct_ctor(..)) => { + return format!("{:?}:{}", + *self, + ty::item_path_str(tcx, *self)); + } + _ => {} } - _ => {} } } return format!("{:?}", *self); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 18891d38d38ec..3bba280a09dae 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -88,7 +88,7 @@ pub fn run_core (libs: HashSet, cfgs: ~[~str], path: &Path) -> (clean::Cra let ctxt = @ctxt; local_data::set(super::ctxtkey, ctxt); - let v = @mut RustdocVisitor::new(); + let mut v = RustdocVisitor::new(); v.visit(&ctxt.crate); (v.clean(), analysis) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c60f19d3ad26f..871ff652ea70e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -267,11 +267,11 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output { /// This input format purely deserializes the json output file. No passes are /// run over the deserialized output. fn json_input(input: &str) -> Result { - let input = match File::open(&Path::new(input)) { + let mut input = match File::open(&Path::new(input)) { Some(f) => f, None => return Err(format!("couldn't open {} for reading", input)), }; - match json::from_reader(@mut input as @mut io::Reader) { + match json::from_reader(&mut input) { Err(s) => Err(s.to_str()), Ok(json::Object(obj)) => { let mut obj = obj; @@ -332,6 +332,6 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) { json.insert(~"crate", crate_json); json.insert(~"plugins", json::Object(plugins_json)); - let file = @mut File::create(&dst).unwrap(); - json::Object(json).to_writer(file as @mut io::Writer); + let mut file = File::create(&dst).unwrap(); + json::Object(json).to_writer(&mut file); } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index b21b1db955f05..de6f4d398761f 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -67,7 +67,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int { }; local_data::set(super::ctxtkey, ctx); - let v = @mut RustdocVisitor::new(); + let mut v = RustdocVisitor::new(); v.visit(&ctx.crate); let crate = v.clean(); let (crate, _) = passes::unindent_comments(crate); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 03ab85918c759..9b6e809f8351f 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -32,7 +32,7 @@ impl RustdocVisitor { } impl RustdocVisitor { - pub fn visit(@mut self, crate: &ast::Crate) { + pub fn visit(&mut self, crate: &ast::Crate) { self.attrs = crate.attrs.clone(); fn visit_struct_def(item: &ast::item, sd: @ast::struct_def, generics: &ast::Generics) -> Struct { diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index af940e34789c7..2220310d66c3f 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -80,8 +80,7 @@ struct ReadyCtx { fns: ~[ListenerFn] } -fn fold_mod(_ctx: @mut ReadyCtx, m: &ast::_mod, fold: &mut CrateSetup) - -> ast::_mod { +fn fold_mod(m: &ast::_mod, fold: &mut CrateSetup) -> ast::_mod { fn strip_main(item: @ast::item) -> @ast::item { @ast::item { attrs: item.attrs.iter().filter_map(|attr| { @@ -101,9 +100,9 @@ fn fold_mod(_ctx: @mut ReadyCtx, m: &ast::_mod, fold: &mut CrateSetup) }, fold) } -fn fold_item(ctx: @mut ReadyCtx, item: @ast::item, fold: &mut CrateSetup) +fn fold_item(item: @ast::item, fold: &mut CrateSetup) -> SmallVector<@ast::item> { - ctx.path.push(item.ident); + fold.ctx.path.push(item.ident); let mut cmds = ~[]; let mut had_pkg_do = false; @@ -126,44 +125,44 @@ fn fold_item(ctx: @mut ReadyCtx, item: @ast::item, fold: &mut CrateSetup) } if had_pkg_do { - ctx.fns.push(ListenerFn { + fold.ctx.fns.push(ListenerFn { cmds: cmds, span: item.span, - path: /*bad*/ctx.path.clone() + path: /*bad*/fold.ctx.path.clone() }); } let res = fold::noop_fold_item(item, fold); - ctx.path.pop(); + fold.ctx.path.pop(); res } -struct CrateSetup { - ctx: @mut ReadyCtx, +struct CrateSetup<'a> { + ctx: &'a mut ReadyCtx, } -impl fold::ast_fold for CrateSetup { +impl<'a> fold::ast_fold for CrateSetup<'a> { fn fold_item(&mut self, item: @ast::item) -> SmallVector<@ast::item> { - fold_item(self.ctx, item, self) + fold_item(item, self) } fn fold_mod(&mut self, module: &ast::_mod) -> ast::_mod { - fold_mod(self.ctx, module, self) + fold_mod(module, self) } } /// Generate/filter main function, add the list of commands, etc. pub fn ready_crate(sess: session::Session, crate: ast::Crate) -> ast::Crate { - let ctx = @mut ReadyCtx { + let mut ctx = ReadyCtx { sess: sess, ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone()), path: ~[], fns: ~[] }; let mut fold = CrateSetup { - ctx: ctx, + ctx: &mut ctx, }; fold.fold_crate(crate) } diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index b383c9edf36d3..b26ceb799a7b6 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -58,12 +58,6 @@ impl Clone for @T { fn clone(&self) -> @T { *self } } -impl Clone for @mut T { - /// Return a shallow copy of the managed box. - #[inline] - fn clone(&self) -> @mut T { *self } -} - impl<'a, T> Clone for &'a T { /// Return a shallow copy of the borrowed pointer. #[inline] @@ -168,14 +162,6 @@ impl DeepClone for @T { fn deep_clone(&self) -> @T { @(**self).deep_clone() } } -// FIXME: #6525: should also be implemented for `T: Send + DeepClone` -impl DeepClone for @mut T { - /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing - /// a deep clone of a potentially cyclical type. - #[inline] - fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() } -} - macro_rules! deep_clone_impl( ($t:ty) => { impl DeepClone for $t { @@ -239,23 +225,6 @@ fn test_managed_clone() { assert_eq!(a, b); } -#[test] -fn test_managed_mut_deep_clone() { - let x = @mut 5i; - let y: @mut int = x.deep_clone(); - *x = 20; - assert_eq!(*y, 5); -} - -#[test] -fn test_managed_mut_clone() { - let a = @mut 5i; - let b: @mut int = a.clone(); - assert_eq!(a, b); - *b = 10; - assert_eq!(a, b); -} - #[test] fn test_borrowed_clone() { let x = 5i; diff --git a/src/libstd/default.rs b/src/libstd/default.rs index aaba23c683bca..60f38e3b3defa 100644 --- a/src/libstd/default.rs +++ b/src/libstd/default.rs @@ -16,10 +16,6 @@ pub trait Default { fn default() -> Self; } -impl Default for @mut T { - fn default() -> @mut T { @mut Default::default() } -} - impl Default for @T { fn default() -> @T { @Default::default() } } diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index a7361fa8c373c..334007a82610a 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -377,9 +377,10 @@ mod test { let mut reader = ErroringLaterReader { count: 0, }; - let buf = @mut ~[8, 9]; + // FIXME (#7049): Figure out some other way to do this. + //let buf = @mut ~[8, 9]; (|| { - reader.push_bytes(&mut *buf, 4); + //reader.push_bytes(&mut *buf, 4); }).finally(|| { // NB: Using rtassert here to trigger abort on failure since this is a should_fail test // FIXME: #7049 This fails because buf is still borrowed diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index 7322f0b0647a8..c5705665896f1 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -31,13 +31,6 @@ pub fn ptr_eq(a: @T, b: @T) -> bool { a_ptr == b_ptr } -/// Determine if two mutable shared boxes point to the same object -#[inline] -pub fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { - let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b)); - a_ptr == b_ptr -} - #[cfg(not(test))] impl Eq for @T { #[inline] @@ -46,14 +39,6 @@ impl Eq for @T { fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) } } -#[cfg(not(test))] -impl Eq for @mut T { - #[inline] - fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) } - #[inline] - fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) } -} - #[cfg(not(test))] impl Ord for @T { #[inline] @@ -66,41 +51,18 @@ impl Ord for @T { fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) } } -#[cfg(not(test))] -impl Ord for @mut T { - #[inline] - fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) } - #[inline] - fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) } - #[inline] - fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) } - #[inline] - fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) } -} - #[cfg(not(test))] impl TotalOrd for @T { #[inline] fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) } } -#[cfg(not(test))] -impl TotalOrd for @mut T { - #[inline] - fn cmp(&self, other: &@mut T) -> Ordering { (**self).cmp(*other) } -} - #[cfg(not(test))] impl TotalEq for @T { #[inline] fn equals(&self, other: &@T) -> bool { (**self).equals(*other) } } -#[cfg(not(test))] -impl TotalEq for @mut T { - #[inline] - fn equals(&self, other: &@mut T) -> bool { (**self).equals(*other) } -} #[test] fn test() { let x = @3; diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 8dbec0f63c601..d66d13657fc64 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -1079,11 +1079,6 @@ pub fn pow_with_uint+Mul>(radix: uint, pow: uin total } -impl Zero for @mut T { - fn zero() -> @mut T { @mut Zero::zero() } - fn is_zero(&self) -> bool { (**self).is_zero() } -} - impl Zero for @T { fn zero() -> @T { @Zero::zero() } fn is_zero(&self) -> bool { (**self).is_zero() } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index 2f9478716a37b..e60abed42f254 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -655,13 +655,10 @@ fn test_repr() { exact_test(&(~"he\u10f3llo"), "~\"he\\u10f3llo\""); exact_test(&(@10), "@10"); - exact_test(&(@mut 10), "@mut 10"); - exact_test(&((@mut 10, 2)), "(@mut 10, 2)"); exact_test(&(~10), "~10"); exact_test(&(&10), "&10"); let mut x = 10; exact_test(&(&mut x), "&mut 10"); - exact_test(&(@mut [1, 2]), "@mut [1, 2]"); exact_test(&(0 as *()), "(0x0 as *())"); exact_test(&(0 as *mut ()), "(0x0 as *mut ())"); diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index e6ab159a76952..cb4d0c3eae716 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -475,16 +475,20 @@ mod test { #[test] fn heap_cycles() { + use cell::RefCell; use option::{Option, Some, None}; struct List { - next: Option<@mut List>, + next: Option<@RefCell>, } - let a = @mut List { next: None }; - let b = @mut List { next: Some(a) }; + let a = @RefCell::new(List { next: None }); + let b = @RefCell::new(List { next: Some(a) }); - a.next = Some(b); + { + let mut a = a.borrow_mut(); + a.get().next = Some(b); + } } #[test] diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 9de812ed3856a..bd1c49c6c241f 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -319,13 +319,6 @@ impl IterBytes for @A { } } -impl IterBytes for @mut A { - #[inline] - fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { - (**self).iter_bytes(lsb0, f) - } -} - impl IterBytes for Rc { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8e6e0625138d9..a2e956d03bcd0 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>, + rename_memo: RefCell>, } // NB: these must be placed in any SCTable... diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 63e8251b22c64..254c07851b8ee 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; @@ -147,17 +148,17 @@ impl ast_node { } } -pub type map = @mut HashMap; +pub type map = @RefCell>; pub struct Ctx { map: map, - path: path, - diag: @mut span_handler, + path: RefCell, + diag: @span_handler, } 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, @@ -170,8 +171,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, @@ -186,10 +189,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") } @@ -198,13 +202,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)); } } @@ -218,26 +226,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) { - 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, ()); } @@ -245,8 +267,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))); } _ => () } @@ -258,8 +281,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 @@ -273,13 +299,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) => { @@ -291,16 +319,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, _) => { @@ -310,7 +339,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)) }; @@ -319,7 +349,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); @@ -332,13 +363,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, _: ()) { @@ -373,29 +410,29 @@ impl Visitor<()> for Ctx { } } -pub fn map_crate(diag: @mut span_handler, c: &Crate) -> map { - let cx = @mut Ctx { - map: @mut HashMap::new(), - path: ~[], +pub fn map_crate(diag: @span_handler, 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 span_handler, +pub fn map_decoded_item(diag: @span_handler, 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, }; @@ -405,10 +442,11 @@ pub fn map_decoded_item(diag: @mut span_handler, 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); @@ -416,11 +454,12 @@ pub fn map_decoded_item(diag: @mut span_handler, } // 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) } @@ -484,7 +523,8 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str { pub fn node_item_query(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) } @@ -493,7 +533,8 @@ pub fn node_item_query(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 8744827868782..a91bd725b9243 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; @@ -601,21 +602,23 @@ pub fn visit_ids_for_inlined_item(item: &inlined_item, } struct IdRangeComputingVisitor { - result: @mut id_range, + result: Cell, } 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(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 { + local_data_key!(resolve_table_key: @@RefCell) 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 f2526c29b9a80..3fffc59b7a4aa 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -355,8 +355,7 @@ pub fn find_stability>(mut metas: It) -> O None } -pub fn require_unique_names(diagnostic: @mut span_handler, - metas: &[@MetaItem]) { +pub fn require_unique_names(diagnostic: @span_handler, metas: &[@MetaItem]) { let mut set = HashSet::new(); for meta in metas.iter() { let name = meta.name(); @@ -381,8 +380,10 @@ pub fn require_unique_names(diagnostic: @mut span_handler, * 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 span_handler, attr: @ast::MetaItem, acc: ReprAttr) - -> ReprAttr { +pub fn find_repr_attr(diagnostic: @span_handler, + attr: @ast::MetaItem, + acc: ReprAttr) + -> ReprAttr { let mut acc = acc; match attr.node { ast::MetaList(s, ref items) if "repr" == s => { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 0509760120a42..eaa55a5a8d7fd 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}; @@ -223,9 +224,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 { @@ -236,14 +237,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') { @@ -258,7 +261,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 { @@ -267,13 +271,13 @@ impl FileMap { } pub struct CodeMap { - files: @mut ~[@FileMap] + files: RefCell<~[@FileMap]> } impl CodeMap { pub fn new() -> CodeMap { CodeMap { - files: @mut ~[], + files: RefCell::new(~[]), } } @@ -287,23 +291,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; } @@ -349,9 +353,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); @@ -391,7 +397,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"); @@ -400,13 +411,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; @@ -422,13 +434,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}; } @@ -437,7 +451,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); @@ -455,7 +470,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}; } @@ -465,12 +481,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 59f33bc77696f..d8e410f671bf5 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,18 +31,18 @@ pub trait Emitter { // (fatal, bug, unimpl) may cause immediate exit, // others log errors for later reporting. pub trait handler { - fn fatal(@mut self, msg: &str) -> !; - fn err(@mut self, msg: &str); - fn bump_err_count(@mut self); - fn err_count(@mut self) -> uint; - fn has_errors(@mut self) -> bool; - fn abort_if_errors(@mut self); - fn warn(@mut self, msg: &str); - fn note(@mut self, msg: &str); + fn fatal(@self, msg: &str) -> !; + fn err(@self, msg: &str); + fn bump_err_count(@self); + fn err_count(@self) -> uint; + fn has_errors(@self) -> bool; + fn abort_if_errors(@self); + fn warn(@self, msg: &str); + fn note(@self, msg: &str); // used to indicate a bug in the compiler: - fn bug(@mut self, msg: &str) -> !; - fn unimpl(@mut self, msg: &str) -> !; - fn emit(@mut self, + fn bug(@self, msg: &str) -> !; + fn unimpl(@self, msg: &str) -> !; + fn emit(@self, cmsp: Option<(@codemap::CodeMap, Span)>, msg: &str, lvl: level); @@ -51,94 +52,94 @@ pub trait handler { // accepts span information for source-location // reporting. pub trait span_handler { - fn span_fatal(@mut self, sp: Span, msg: &str) -> !; - fn span_err(@mut self, sp: Span, msg: &str); - fn span_warn(@mut self, sp: Span, msg: &str); - fn span_note(@mut self, sp: Span, msg: &str); - fn span_bug(@mut self, sp: Span, msg: &str) -> !; - fn span_unimpl(@mut self, sp: Span, msg: &str) -> !; - fn handler(@mut self) -> @mut handler; + fn span_fatal(@self, sp: Span, msg: &str) -> !; + fn span_err(@self, sp: Span, msg: &str); + fn span_warn(@self, sp: Span, msg: &str); + fn span_note(@self, sp: Span, msg: &str); + fn span_bug(@self, sp: Span, msg: &str) -> !; + fn span_unimpl(@self, sp: Span, msg: &str) -> !; + fn handler(@self) -> @handler; } struct HandlerT { - err_count: uint, + err_count: Cell, emit: @Emitter, } struct CodemapT { - handler: @mut handler, + handler: @handler, cm: @codemap::CodeMap, } impl span_handler for CodemapT { - fn span_fatal(@mut self, sp: Span, msg: &str) -> ! { + fn span_fatal(@self, sp: Span, msg: &str) -> ! { self.handler.emit(Some((self.cm, sp)), msg, fatal); fail!(); } - fn span_err(@mut self, sp: Span, msg: &str) { + fn span_err(@self, sp: Span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, error); self.handler.bump_err_count(); } - fn span_warn(@mut self, sp: Span, msg: &str) { + fn span_warn(@self, sp: Span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, warning); } - fn span_note(@mut self, sp: Span, msg: &str) { + fn span_note(@self, sp: Span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, note); } - fn span_bug(@mut self, sp: Span, msg: &str) -> ! { + fn span_bug(@self, sp: Span, msg: &str) -> ! { self.span_fatal(sp, ice_msg(msg)); } - fn span_unimpl(@mut self, sp: Span, msg: &str) -> ! { + fn span_unimpl(@self, sp: Span, msg: &str) -> ! { self.span_bug(sp, ~"unimplemented " + msg); } - fn handler(@mut self) -> @mut handler { + fn handler(@self) -> @handler { self.handler } } impl handler for HandlerT { - fn fatal(@mut self, msg: &str) -> ! { + fn fatal(@self, msg: &str) -> ! { self.emit.emit(None, msg, fatal); fail!(); } - fn err(@mut self, msg: &str) { + fn err(@self, msg: &str) { self.emit.emit(None, msg, error); self.bump_err_count(); } - fn bump_err_count(@mut self) { - self.err_count += 1u; + fn bump_err_count(@self) { + self.err_count.set(self.err_count.get() + 1u); } - fn err_count(@mut self) -> uint { - self.err_count + fn err_count(@self) -> uint { + self.err_count.get() } - fn has_errors(@mut self) -> bool { - self.err_count > 0u + fn has_errors(@self) -> bool { + self.err_count.get()> 0u } - fn abort_if_errors(@mut self) { + 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); } - fn warn(@mut self, msg: &str) { + fn warn(@self, msg: &str) { self.emit.emit(None, msg, warning); } - fn note(@mut self, msg: &str) { + fn note(@self, msg: &str) { self.emit.emit(None, msg, note); } - fn bug(@mut self, msg: &str) -> ! { + fn bug(@self, msg: &str) -> ! { self.fatal(ice_msg(msg)); } - fn unimpl(@mut self, msg: &str) -> ! { + fn unimpl(@self, msg: &str) -> ! { self.bug(~"unimplemented " + msg); } - fn emit(@mut self, + fn emit(@self, cmsp: Option<(@codemap::CodeMap, Span)>, msg: &str, lvl: level) { @@ -151,24 +152,24 @@ 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 span_handler { - @mut CodemapT { +pub fn mk_span_handler(handler: @handler, cm: @codemap::CodeMap) + -> @span_handler { + @CodemapT { handler: handler, cm: cm, - } as @mut span_handler + } as @span_handler } -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 HandlerT { - err_count: 0, + @HandlerT { + err_count: Cell::new(0), emit: emit, - } as @mut handler + } as @handler } #[deriving(Eq)] @@ -355,10 +356,7 @@ fn print_macro_backtrace(cm: @codemap::CodeMap, sp: Span) { } } -pub fn expect( - diag: @mut span_handler, - opt: Option, - msg: || -> ~str) +pub fn expect(diag: @span_handler, opt: Option, msg: || -> ~str) -> T { match opt { Some(ref t) => (*t).clone(), diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index cd7953aac2067..0d78acadcae4b 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -39,9 +39,9 @@ fn next_state(s: State) -> Option { pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> base::MacResult { - let p = parse::new_parser_from_tts(cx.parse_sess(), - cx.cfg(), - tts.to_owned()); + let mut p = parse::new_parser_from_tts(cx.parse_sess(), + cx.cfg(), + tts.to_owned()); let mut asm = @""; let mut asm_str_style = None; @@ -66,9 +66,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) asm_str_style = Some(style); } Outputs => { - while *p.token != token::EOF && - *p.token != token::COLON && - *p.token != token::MOD_SEP { + while p.token != token::EOF && + p.token != token::COLON && + p.token != token::MOD_SEP { if outputs.len() != 0 { p.eat(&token::COMMA); @@ -77,10 +77,10 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) let (constraint, _str_style) = p.parse_str(); if constraint.starts_with("+") { - cx.span_unimpl(*p.last_span, + cx.span_unimpl(p.last_span, "'+' (read+write) output operand constraint modifier"); } else if !constraint.starts_with("=") { - cx.span_err(*p.last_span, "output operand constraint lacks '='"); + cx.span_err(p.last_span, "output operand constraint lacks '='"); } p.expect(&token::LPAREN); @@ -91,9 +91,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) } } Inputs => { - while *p.token != token::EOF && - *p.token != token::COLON && - *p.token != token::MOD_SEP { + while p.token != token::EOF && + p.token != token::COLON && + p.token != token::MOD_SEP { if inputs.len() != 0 { p.eat(&token::COMMA); @@ -102,9 +102,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) let (constraint, _str_style) = p.parse_str(); if constraint.starts_with("=") { - cx.span_err(*p.last_span, "input operand constraint contains '='"); + cx.span_err(p.last_span, "input operand constraint contains '='"); } else if constraint.starts_with("+") { - cx.span_err(*p.last_span, "input operand constraint contains '+'"); + cx.span_err(p.last_span, "input operand constraint contains '+'"); } p.expect(&token::LPAREN); @@ -116,9 +116,9 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) } Clobbers => { let mut clobs = ~[]; - while *p.token != token::EOF && - *p.token != token::COLON && - *p.token != token::MOD_SEP { + while p.token != token::EOF && + p.token != token::COLON && + p.token != token::MOD_SEP { if clobs.len() != 0 { p.eat(&token::COMMA); @@ -142,16 +142,16 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) dialect = ast::asm_intel; } - if *p.token == token::COMMA { + if p.token == token::COMMA { p.eat(&token::COMMA); } } } - while *p.token == token::COLON || - *p.token == token::MOD_SEP || - *p.token == token::EOF { - state = if *p.token == token::COLON { + while p.token == token::COLON || + p.token == token::MOD_SEP || + p.token == token::EOF { + state = if p.token == token::COLON { p.bump(); match next_state(state) { Some(x) => x, @@ -160,7 +160,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) break } } - } else if *p.token == token::MOD_SEP { + } else if p.token == token::MOD_SEP { p.bump(); let s = match next_state(state) { Some(x) => x, @@ -176,7 +176,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) break } } - } else if *p.token == token::EOF { + } else if p.token == token::EOF { continue_ = false; break; } else { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ccbc533fbcc72..814238afe41fa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -20,6 +20,7 @@ use parse::token; use parse::token::{ident_to_str, intern, str_to_ident}; use util::small_vector::SmallVector; +use std::cell::RefCell; use std::hashmap::HashMap; // new-style macro! tt code: @@ -156,7 +157,7 @@ pub enum SyntaxExtension { // The SyntaxEnv is the environment that's threaded through the expansion // of macros. It contains bindings for macros, and also a special binding // for " block" (not a legal identifier) that maps to a BlockInfo -pub type SyntaxEnv = @mut MapChain; +pub type SyntaxEnv = @RefCell>; // Transformer : the codomain of SyntaxEnvs @@ -172,9 +173,9 @@ pub enum Transformer { pub struct BlockInfo { // should macros escape from this scope? - macros_escape : bool, + macros_escape: bool, // what are the pending renames? - pending_renames : @mut RenameList + pending_renames: @RefCell, } // a list of ident->name renamings @@ -197,8 +198,8 @@ pub fn syntax_expander_table() -> SyntaxEnv { // NB identifier starts with space, and can't conflict with legal idents syntax_expanders.insert(intern(&" block"), @BlockInfo(BlockInfo{ - macros_escape : false, - pending_renames : @mut ~[] + macros_escape: false, + pending_renames: @RefCell::new(~[]), })); syntax_expanders.insert(intern(&"macro_rules"), @SE(IdentTT(@SyntaxExpanderTTItem { @@ -295,7 +296,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>, @@ -309,7 +310,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, @@ -325,7 +326,7 @@ impl ExtCtxt { match e.node { ast::ExprMac(..) => { let mut expander = expand::MacroExpander { - extsbox: @mut syntax_expander_table(), + extsbox: @RefCell::new(syntax_expander_table()), cx: self, }; e = expand::expand_expr(e, &mut expander); @@ -336,7 +337,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 { @@ -443,11 +444,11 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt, pub fn get_exprs_from_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> ~[@ast::Expr] { - let p = parse::new_parser_from_tts(cx.parse_sess(), - cx.cfg(), - tts.to_owned()); + let mut p = parse::new_parser_from_tts(cx.parse_sess(), + cx.cfg(), + tts.to_owned()); let mut es = ~[]; - while *p.token != token::EOF { + while p.token != token::EOF { if es.len() != 0 && !p.eat(&token::COMMA) { cx.span_fatal(sp, "expected token: `,`"); } @@ -493,20 +494,21 @@ pub fn get_exprs_from_tts(cx: &ExtCtxt, // of another chain. pub enum MapChain { BaseMapChain(~HashMap), - ConsMapChain(~HashMap,@mut MapChain) + ConsMapChain(~HashMap, @RefCell>) } // get the map from an env frame impl MapChain{ // Constructor. I don't think we need a zero-arg one. - pub fn new(init: ~HashMap) -> @mut MapChain { - @mut BaseMapChain(init) + pub fn new(init: ~HashMap) -> @RefCell> { + @RefCell::new(BaseMapChain(init)) } // add a new frame to the environment (functionally) - pub fn push_frame (@mut self) -> @mut MapChain { - @mut ConsMapChain(~HashMap::new() ,self) + pub fn push_frame(this: @RefCell>) + -> @RefCell> { + @RefCell::new(ConsMapChain(~HashMap::new(), this)) } // no need for pop, it'll just be functional. @@ -525,22 +527,23 @@ impl MapChain{ // traits just don't work anywhere...? //impl Map for MapChain { - pub fn contains_key (&self, key: &K) -> bool { + pub fn contains_key(&self, key: &K) -> bool { match *self { BaseMapChain (ref map) => map.contains_key(key), - ConsMapChain (ref map,ref rest) => - (map.contains_key(key) - || rest.contains_key(key)) + ConsMapChain (ref map,ref rest) => { + let rest = rest.borrow(); + (map.contains_key(key) || rest.get().contains_key(key)) + } } } // should each_key and each_value operate on shadowed // names? I think not. // delaying implementing this.... - pub fn each_key (&self, _f: |&K| -> bool) { + pub fn each_key(&self, _f: |&K| -> bool) { fail!("unimplemented 2013-02-15T10:01"); } - pub fn each_value (&self, _f: |&V| -> bool) { + pub fn each_value(&self, _f: |&V| -> bool) { fail!("unimplemented 2013-02-15T10:02"); } @@ -550,8 +553,11 @@ impl MapChain{ match self.get_map().find (key) { Some(ref v) => Some(**v), None => match *self { - BaseMapChain (_) => None, - ConsMapChain (_,ref rest) => rest.find(key) + BaseMapChain(_) => None, + ConsMapChain(_, ref rest) => { + let rest = rest.borrow(); + rest.get().find(key) + } } } } @@ -595,7 +601,8 @@ impl MapChain{ if satisfies_pred(map,&n,|v|pred(v)) { map.insert(key,ext); } else { - rest.insert_into_frame(key,ext,n,pred) + let mut rest = rest.borrow_mut(); + rest.get().insert_into_frame(key, ext, n, pred) } } } @@ -630,7 +637,7 @@ mod test { assert_eq!(m.find(&@"def"),Some(@16)); assert_eq!(*(m.find(&@"abc").unwrap()),15); assert_eq!(*(m.find(&@"def").unwrap()),16); - let n = m.push_frame(); + let n = MapChain::push_frame(m); // old bindings are still present: assert_eq!(*(n.find(&@"abc").unwrap()),15); assert_eq!(*(n.find(&@"def").unwrap()),16); diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs index d9fbc33153a60..f3f44f4fa3f64 100644 --- a/src/libsyntax/ext/cfg.rs +++ b/src/libsyntax/ext/cfg.rs @@ -26,11 +26,13 @@ use parse::token; use parse::attr::parser_attr; pub fn expand_cfg(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> base::MacResult { - let p = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_owned()); + let mut p = parse::new_parser_from_tts(cx.parse_sess(), + cx.cfg(), + tts.to_owned()); let mut cfgs = ~[]; // parse `cfg!(meta_item, meta_item(x,y), meta_item="foo", ...)` - while *p.token != token::EOF { + while p.token != token::EOF { cfgs.push(p.parse_meta_item()); if p.eat(&token::EOF) { break } // trailing comma is optional,. p.expect(&token::COMMA); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index eb07353cda3d1..44849be483268 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -29,6 +29,7 @@ use visit; use visit::Visitor; use util::small_vector::SmallVector; +use std::cell::RefCell; use std::vec; pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { @@ -52,8 +53,12 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { } let extname = &pth.segments[0].identifier; let extnamestr = ident_to_str(extname); - // leaving explicit deref here to highlight unbox op: - match (*fld.extsbox).find(&extname.name) { + let opt_syntax_env = { + let extsbox = fld.extsbox.get(); + let extsbox = extsbox.borrow(); + extsbox.get().find(&extname.name) + }; + match opt_syntax_env { None => { fld.cx.span_fatal( pth.span, @@ -210,7 +215,8 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { // // NB: there is some redundancy between this and expand_item, below, and // they might benefit from some amount of semantic and language-UI merger. -pub fn expand_mod_items(module_: &ast::_mod, fld: &mut MacroExpander) -> ast::_mod { +pub fn expand_mod_items(module_: &ast::_mod, fld: &mut MacroExpander) + -> ast::_mod { // Fold the contents first: let module_ = noop_fold_mod(module_, fld); @@ -221,7 +227,12 @@ pub fn expand_mod_items(module_: &ast::_mod, fld: &mut MacroExpander) -> ast::_m item.attrs.rev_iter().fold(~[*item], |items, attr| { let mname = attr.name(); - match (*fld.extsbox).find(&intern(mname)) { + let opt_syntax_env = { + let extsbox = fld.extsbox.get(); + let extsbox = extsbox.borrow(); + extsbox.get().find(&intern(mname)) + }; + match opt_syntax_env { Some(@SE(ItemDecorator(dec_fn))) => { fld.cx.bt_push(ExpnInfo { call_site: attr.span, @@ -250,12 +261,20 @@ pub fn expand_mod_items(module_: &ast::_mod, fld: &mut MacroExpander) -> ast::_m macro_rules! with_exts_frame ( ($extsboxexpr:expr,$macros_escape:expr,$e:expr) => ({let extsbox = $extsboxexpr; - let oldexts = *extsbox; - *extsbox = oldexts.push_frame(); - extsbox.insert(intern(special_block_name), - @BlockInfo(BlockInfo{macros_escape:$macros_escape,pending_renames:@mut ~[]})); + let oldexts = extsbox.get(); + extsbox.set(MapChain::push_frame(oldexts)); + { + let extsbox = extsbox.get(); + let mut extsbox = extsbox.borrow_mut(); + extsbox.get().insert( + intern(special_block_name), + @BlockInfo(BlockInfo { + macros_escape: $macros_escape, + pending_renames: @RefCell::new(~[]), + })); + } let result = $e; - *extsbox = oldexts; + extsbox.set(oldexts); result }) ) @@ -302,9 +321,16 @@ pub fn expand_item_mac(it: @ast::item, fld: &mut MacroExpander) let extname = &pth.segments[0].identifier; let extnamestr = ident_to_str(extname); let fm = fresh_mark(); - let expanded = match (*fld.extsbox).find(&extname.name) { - None => fld.cx.span_fatal(pth.span, - format!("macro undefined: '{}!'", extnamestr)), + let opt_syntax_env = { + let extsbox = fld.extsbox.get(); + let extsbox = extsbox.borrow(); + extsbox.get().find(&extname.name) + }; + let expanded = match opt_syntax_env { + None => { + fld.cx.span_fatal(pth.span, + format!("macro undefined: '{}!'", extnamestr)) + } Some(@SE(NormalTT(expander, span))) => { if it.ident.name != parse::token::special_idents::invalid.name { @@ -369,7 +395,8 @@ pub fn expand_item_mac(it: @ast::item, fld: &mut MacroExpander) MRDef(ref mdef) => { // yikes... no idea how to apply the mark to this. I'm afraid // we're going to have to wait-and-see on this one. - insert_macro(*fld.extsbox,intern(mdef.name), @SE((*mdef).ext)); + let extsbox = fld.extsbox.get(); + insert_macro(extsbox,intern(mdef.name), @SE((*mdef).ext)); SmallVector::zero() } }; @@ -390,8 +417,12 @@ fn insert_macro(exts: SyntaxEnv, name: ast::Name, transformer: @Transformer) { special_block_name) } }; - exts.insert_into_frame(name,transformer,intern(special_block_name), - is_non_escaping_block) + + let mut exts = exts.borrow_mut(); + exts.get().insert_into_frame(name, + transformer, + intern(special_block_name), + is_non_escaping_block) } // expand a stmt @@ -414,62 +445,76 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> { } let extname = &pth.segments[0].identifier; let extnamestr = ident_to_str(extname); - let fully_expanded: SmallVector<@Stmt> = match (*fld.extsbox).find(&extname.name) { - None => { - fld.cx.span_fatal(pth.span, format!("macro undefined: '{}'", extnamestr)) - } - - Some(@SE(NormalTT(expandfun, exp_span))) => { - fld.cx.bt_push(ExpnInfo { - call_site: s.span, - callee: NameAndSpan { - name: extnamestr, - format: MacroBang, - span: exp_span, - } - }); - let fm = fresh_mark(); - // mark before expansion: - let marked_tts = mark_tts(tts,fm); - let marked_ctxt = new_mark(fm,ctxt); + let fully_expanded: SmallVector<@Stmt> = { + let opt_syntax_env = { + let extsbox = fld.extsbox.get(); + let extsbox = extsbox.borrow(); + extsbox.get().find(&extname.name) + }; + match opt_syntax_env { + None => { + fld.cx.span_fatal(pth.span, + format!("macro undefined: '{}'", extnamestr)) + } - // See the comment in expand_expr for why we want the original span, - // not the current mac.span. - let mac_span = original_span(fld.cx); - - let expanded = match expandfun.expand(fld.cx, - mac_span.call_site, - marked_tts, - marked_ctxt) { - MRExpr(e) => { - @codemap::Spanned { - node: StmtExpr(e, ast::DUMMY_NODE_ID), - span: e.span, + Some(@SE(NormalTT(expandfun, exp_span))) => { + fld.cx.bt_push(ExpnInfo { + call_site: s.span, + callee: NameAndSpan { + name: extnamestr, + format: MacroBang, + span: exp_span, + } + }); + let fm = fresh_mark(); + // mark before expansion: + let marked_tts = mark_tts(tts,fm); + let marked_ctxt = new_mark(fm,ctxt); + + // See the comment in expand_expr for why we want the original span, + // not the current mac.span. + let mac_span = original_span(fld.cx); + + let expanded = match expandfun.expand(fld.cx, + mac_span.call_site, + marked_tts, + marked_ctxt) { + MRExpr(e) => { + @codemap::Spanned { + node: StmtExpr(e, ast::DUMMY_NODE_ID), + span: e.span, + } } + MRAny(any_macro) => any_macro.make_stmt(), + _ => { + fld.cx.span_fatal(pth.span, + format!("non-stmt macro in stmt \ + pos: {}", + extnamestr)) + } + }; + let marked_after = mark_stmt(expanded,fm); + + // Keep going, outside-in. + let fully_expanded = fld.fold_stmt(marked_after); + if fully_expanded.is_empty() { + fld.cx.span_fatal(pth.span, + "macro didn't expand to a statement"); } - MRAny(any_macro) => any_macro.make_stmt(), - _ => fld.cx.span_fatal( - pth.span, - format!("non-stmt macro in stmt pos: {}", extnamestr)) - }; - let marked_after = mark_stmt(expanded,fm); + fld.cx.bt_pop(); + fully_expanded.move_iter() + .map(|s| @Spanned { + span: s.span, + node: s.node.clone() + }) + .collect() + } - // Keep going, outside-in. - let fully_expanded = fld.fold_stmt(marked_after); - if fully_expanded.is_empty() { + _ => { fld.cx.span_fatal(pth.span, - "macro didn't expand to a statement"); + format!("'{}' is not a tt-style macro", + extnamestr)) } - fld.cx.bt_pop(); - fully_expanded.move_iter() - .map(|s| @Spanned { span: s.span, node: s.node.clone() }) - .collect() - } - - _ => { - fld.cx.span_fatal(pth.span, - format!("'{}' is not a tt-style macro", - extnamestr)) } }; @@ -497,7 +542,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) span: stmt_span }, node_id) => { - let block_info = get_block_info(*fld.extsbox); + let block_info = get_block_info(fld.extsbox.get()); let pending_renames = block_info.pending_renames; // take it apart: @@ -517,17 +562,25 @@ 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 new_pending_renames = @RefCell::new(~[]); for ident in name_finder.ident_accumulator.iter() { let new_name = fresh_name(ident); - new_pending_renames.push((*ident,new_name)); + let mut new_pending_renames = + new_pending_renames.borrow_mut(); + new_pending_renames.get().push((*ident,new_name)); } let mut rename_fld = renames_to_fold(new_pending_renames); // rewrite the pattern using the new names (the old ones // have already been applied): let rewritten_pat = rename_fld.fold_pat(expanded_pat); // add them to the existing pending renames: - for pr in new_pending_renames.iter() {pending_renames.push(*pr)} + { + let new_pending_renames = new_pending_renames.borrow(); + for pr in new_pending_renames.get().iter() { + let mut pending_renames = pending_renames.borrow_mut(); + pending_renames.get().push(*pr) + } + } // also, don't forget to expand the init: let new_init_opt = init.map(|e| fld.fold_expr(e)); let rewritten_local = @@ -618,7 +671,7 @@ pub fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P { // expand the elements of a block. pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P { - let block_info = get_block_info(*fld.extsbox); + let block_info = get_block_info(fld.extsbox.get()); let pending_renames = block_info.pending_renames; let mut rename_fld = renames_to_fold(pending_renames); let new_view_items = b.view_items.map(|x| fld.fold_view_item(x)); @@ -640,7 +693,8 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P { // get the (innermost) BlockInfo from an exts stack fn get_block_info(exts : SyntaxEnv) -> BlockInfo { - match exts.find_in_topmost_frame(&intern(special_block_name)) { + let exts = exts.borrow(); + match exts.get().find_in_topmost_frame(&intern(special_block_name)) { Some(@BlockInfo(bi)) => bi, _ => fail!("special identifier {:?} was bound to a non-BlockInfo", @" block") @@ -648,12 +702,15 @@ fn get_block_info(exts : SyntaxEnv) -> BlockInfo { } struct IdentRenamer { - renames: @mut ~[(ast::Ident,ast::Name)], + renames: @RefCell<~[(ast::Ident,ast::Name)]>, } impl ast_fold for IdentRenamer { fn fold_ident(&mut self, id: ast::Ident) -> ast::Ident { - let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| { + let renames = self.renames.borrow(); + let new_ctxt = renames.get() + .iter() + .fold(id.ctxt, |ctxt, &(from, to)| { new_rename(from, to, ctxt) }); ast::Ident { @@ -665,7 +722,8 @@ impl ast_fold for IdentRenamer { // given a mutable list of renames, return a tree-folder that applies those // renames. -pub fn renames_to_fold(renames: @mut ~[(ast::Ident,ast::Name)]) -> IdentRenamer { +pub fn renames_to_fold(renames: @RefCell<~[(ast::Ident,ast::Name)]>) + -> IdentRenamer { IdentRenamer { renames: renames, } @@ -911,7 +969,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 { @@ -931,7 +989,7 @@ pub fn inject_std_macros(parse_sess: @mut parse::ParseSess, } pub struct MacroExpander<'a> { - extsbox: @mut SyntaxEnv, + extsbox: @RefCell, cx: &'a mut ExtCtxt, } @@ -961,7 +1019,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 { // adding *another* layer of indirection here so that the block @@ -972,7 +1030,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess, let extsbox = syntax_expander_table(); let mut cx = ExtCtxt::new(parse_sess, cfg.clone()); let mut expander = MacroExpander { - extsbox: @mut extsbox, + extsbox: @RefCell::new(extsbox), cx: &mut cx, }; @@ -1011,14 +1069,15 @@ impl CtxtFn for Renamer { // a renamer that performs a whole bunch of renames pub struct MultiRenamer { - renames : @mut ~[(ast::Ident,ast::Name)] + renames: @RefCell<~[(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)| { + let renames = self.renames.borrow(); + renames.get().iter().fold(starting_ctxt,|ctxt,&(from,to)| { new_rename(from,to,ctxt) }) } @@ -1334,8 +1393,9 @@ 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 pending_renames = + @RefCell::new(~[(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 path_finder = new_path_finder(~[]); visit::walk_crate(&mut path_finder, &double_renamed, ()); @@ -1347,7 +1407,7 @@ mod test { } fn fake_print_crate(crate: &ast::Crate) { - let out = @mut std::io::stderr() as @mut std::io::Writer; + let mut out = ~std::io::stderr() as ~std::io::Writer; let s = pprust::rust_printer(out, get_ident_interner()); pprust::print_crate_(s, crate); } @@ -1544,8 +1604,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/format.rs b/src/libsyntax/ext/format.rs index 3bfab7da9b46d..8660b4c056091 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -53,11 +53,11 @@ struct Context<'a> { impl<'a> Context<'a> { /// Parses the arguments from the given list of tokens, returning None if /// there's a parse error so we can continue parsing other format! expressions. - fn parse_args(&mut self, sp: Span, - tts: &[ast::token_tree]) -> (@ast::Expr, Option<@ast::Expr>) { - let p = rsparse::new_parser_from_tts(self.ecx.parse_sess(), - self.ecx.cfg(), - tts.to_owned()); + fn parse_args(&mut self, sp: Span, tts: &[ast::token_tree]) + -> (@ast::Expr, Option<@ast::Expr>) { + let mut p = rsparse::new_parser_from_tts(self.ecx.parse_sess(), + self.ecx.cfg(), + tts.to_owned()); // Parse the leading function expression (maybe a block, maybe a path) let extra = p.parse_expr(); if !p.eat(&token::COMMA) { @@ -65,34 +65,34 @@ impl<'a> Context<'a> { return (extra, None); } - if *p.token == token::EOF { + if p.token == token::EOF { self.ecx.span_err(sp, "requires at least a format string argument"); return (extra, None); } let fmtstr = p.parse_expr(); let mut named = false; - while *p.token != token::EOF { + while p.token != token::EOF { if !p.eat(&token::COMMA) { self.ecx.span_err(sp, "expected token: `,`"); return (extra, None); } - if *p.token == token::EOF { break } // accept trailing commas - if named || (token::is_ident(p.token) && + if p.token == token::EOF { break } // accept trailing commas + if named || (token::is_ident(&p.token) && p.look_ahead(1, |t| *t == token::EQ)) { named = true; - let ident = match *p.token { + let ident = match p.token { token::IDENT(i, _) => { p.bump(); i } _ if named => { - self.ecx.span_err(*p.span, + self.ecx.span_err(p.span, "expected ident, positional arguments \ cannot follow named arguments"); return (extra, None); } _ => { - self.ecx.span_err(*p.span, + self.ecx.span_err(p.span, format!("expected ident for named \ argument, but found `{}`", p.this_token_to_str())); diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 330d33d6fc6c4..0f0793e03b776 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -579,22 +579,18 @@ fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::token_tree]) ss } -fn expand_tts(cx: &ExtCtxt, - sp: Span, - tts: &[ast::token_tree]) -> (@ast::Expr, @ast::Expr) { - +fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::token_tree]) + -> (@ast::Expr, @ast::Expr) { // NB: It appears that the main parser loses its mind if we consider // $foo as a tt_nonterminal during the main parse, so we have to re-parse // under quote_depth > 0. This is silly and should go away; the _guess_ is // it has to do with transition away from supporting old-style macros, so // try removing it when enough of them are gone. - let p = parse::new_parser_from_tts( - cx.parse_sess(), - cx.cfg(), - tts.to_owned() - ); - *p.quote_depth += 1u; + let mut p = parse::new_parser_from_tts(cx.parse_sess(), + cx.cfg(), + tts.to_owned()); + p.quote_depth += 1u; let cx_expr = p.parse_expr(); if !p.eat(&token::COMMA) { diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index ccf4bf2acd6f3..5f634f7f054e2 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; @@ -81,9 +82,13 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> base::MacResult { let file = get_single_str_from_tts(cx, sp, tts, "include!"); // The file will be added to the code map by the parser - let p = parse::new_sub_parser_from_file( - cx.parse_sess(), cx.cfg(), - &res_rel_file(cx, sp, &Path::new(file)), sp); + let mut p = + parse::new_sub_parser_from_file(cx.parse_sess(), + cx.cfg(), + &res_rel_file(cx, + sp, + &Path::new(file)), + sp); base::MRExpr(p.parse_expr()) } @@ -104,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 d9b1c2bddbca8..a7d1d8fb3663d 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -25,8 +25,8 @@ 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 rust_parser = Parser(sess, cfg.clone(), rdr.dup()); + let rdr = tt_rdr as @reader; + let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup()); if rust_parser.is_keyword(keywords::True) { cx.set_trace_macros(true); @@ -38,7 +38,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt, rust_parser.bump(); - let rust_parser = Parser(sess, cfg, rdr.dup()); + let mut rust_parser = Parser(sess, cfg, rdr.dup()); let result = rust_parser.parse_expr(); base::MRExpr(result) } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index a450bfeccfe4c..8b22e32262b64 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 { - 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) { 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 { +pub fn parse_or_else(sess: @ParseSess, + cfg: ast::CrateConfig, + rdr: @reader, + ms: ~[matcher]) + -> HashMap { 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)); @@ -403,13 +401,13 @@ pub fn parse( } rdr.next_token(); } else /* bb_eis.len() == 1 */ { - let rust_parser = Parser(sess, cfg.clone(), rdr.dup()); + let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup()); let mut ei = bb_eis.pop(); match ei.elts[ei.idx].node { match_nonterminal(_, ref name, idx) => { ei.matches[idx].push(@matched_nonterminal( - parse_nt(&rust_parser, ident_to_str(name)))); + parse_nt(&mut rust_parser, ident_to_str(name)))); ei.idx += 1u; } _ => fail!() @@ -426,7 +424,7 @@ pub fn parse( } } -pub fn parse_nt(p: &Parser, name: &str) -> nonterminal { +pub fn parse_nt(p: &mut Parser, name: &str) -> nonterminal { match name { "item" => match p.parse_item(~[]) { Some(i) => token::nt_item(i), @@ -438,19 +436,21 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal { "expr" => token::nt_expr(p.parse_expr()), "ty" => token::nt_ty(p.parse_ty(false /* no need to disambiguate*/)), // this could be handled like a token, since it is one - "ident" => match *p.token { + "ident" => match p.token { token::IDENT(sn,b) => { p.bump(); token::nt_ident(~sn,b) } - _ => p.fatal(~"expected ident, found " - + token::to_str(get_ident_interner(), p.token)) + _ => { + let token_str = token::to_str(get_ident_interner(), &p.token); + p.fatal(~"expected ident, found " + token_str) + } }, "path" => { token::nt_path(~p.parse_path(LifetimeAndTypesWithoutColons).path) } "attr" => token::nt_attr(@p.parse_attribute(false)), "tt" => { - *p.quote_depth += 1u; //but in theory, non-quoted tts might be useful + p.quote_depth += 1u; //but in theory, non-quoted tts might be useful let res = token::nt_tt(@p.parse_token_tree()); - *p.quote_depth -= 1u; + p.quote_depth -= 1u; res } "matchers" => token::nt_matchers(p.parse_matchers()), diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index ae9bbdadf2cbd..6e44beb94c7bd 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -24,10 +24,11 @@ use parse::attr::parser_attr; use parse::token::{get_ident_interner, special_idents, gensym_ident, ident_to_str}; use parse::token::{FAT_ARROW, SEMI, nt_matchers, nt_tt, EOF}; use print; +use std::cell::RefCell; use util::small_vector::SmallVector; struct ParserAnyMacro { - parser: @Parser, + parser: RefCell, } impl ParserAnyMacro { @@ -38,28 +39,36 @@ impl ParserAnyMacro { /// fail!(); } )` doesn't get picked up by .parse_expr(), but it's /// allowed to be there. fn ensure_complete_parse(&self, allow_semi: bool) { - if allow_semi && *self.parser.token == SEMI { - self.parser.bump() + let mut parser = self.parser.borrow_mut(); + if allow_semi && parser.get().token == SEMI { + parser.get().bump() } - if *self.parser.token != EOF { - let msg = format!("macro expansion ignores token `{}` and any following", - self.parser.this_token_to_str()); - self.parser.span_err(*self.parser.span, msg); + if parser.get().token != EOF { + let token_str = parser.get().this_token_to_str(); + let msg = format!("macro expansion ignores token `{}` and any \ + following", + token_str); + let span = parser.get().span; + parser.get().span_err(span, msg); } } } impl AnyMacro for ParserAnyMacro { fn make_expr(&self) -> @ast::Expr { - let ret = self.parser.parse_expr(); + let ret = { + let mut parser = self.parser.borrow_mut(); + parser.get().parse_expr() + }; self.ensure_complete_parse(true); ret } fn make_items(&self) -> SmallVector<@ast::item> { let mut ret = SmallVector::zero(); loop { - let attrs = self.parser.parse_outer_attributes(); - match self.parser.parse_item(attrs) { + let mut parser = self.parser.borrow_mut(); + let attrs = parser.get().parse_outer_attributes(); + match parser.get().parse_item(attrs) { Some(item) => ret.push(item), None => break } @@ -68,8 +77,11 @@ impl AnyMacro for ParserAnyMacro { ret } fn make_stmt(&self) -> @ast::Stmt { - let attrs = self.parser.parse_outer_attributes(); - let ret = self.parser.parse_stmt(attrs); + let ret = { + let mut parser = self.parser.borrow_mut(); + let attrs = parser.get().parse_outer_attributes(); + parser.get().parse_stmt(attrs) + }; self.ensure_complete_parse(true); ret } @@ -118,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] { @@ -142,14 +150,11 @@ 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 { - parser: p, + parser: RefCell::new(p), } as @AnyMacro) } failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo { @@ -206,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 58a114a2de0cf..362c1b3891b0f 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, dotdotdoted: bool, sep: Option, - up: Option<@mut TtFrame>, + up: Option<@TtFrame>, } pub struct TtReader { - sp_diag: @mut span_handler, + sp_diag: @span_handler, // the unzipped tree: - stack: @mut TtFrame, + priv stack: RefCell<@TtFrame>, /* for MBE-style macro transcription */ - interpolations: HashMap, - repeat_idx: ~[uint], - repeat_len: ~[uint], + priv interpolations: RefCell>, + priv repeat_idx: RefCell<~[uint]>, + priv repeat_len: RefCell<~[uint]>, /* cached: */ - cur_tok: Token, - cur_span: Span + cur_tok: RefCell, + cur_span: RefCell, } /** 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 span_handler, +pub fn new_tt_reader(sp_diag: @span_handler, interp: Option>, 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/parse/attr.rs b/src/libsyntax/parse/attr.rs index 18e45a20fed83..c8ebc80360498 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -17,24 +17,23 @@ use parse::token::INTERPOLATED; // a parser that can parse attributes. pub trait parser_attr { - fn parse_outer_attributes(&self) -> ~[ast::Attribute]; - fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute; - fn parse_inner_attrs_and_next(&self) -> - (~[ast::Attribute], ~[ast::Attribute]); - fn parse_meta_item(&self) -> @ast::MetaItem; - fn parse_meta_seq(&self) -> ~[@ast::MetaItem]; - fn parse_optional_meta(&self) -> ~[@ast::MetaItem]; + fn parse_outer_attributes(&mut self) -> ~[ast::Attribute]; + fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute; + fn parse_inner_attrs_and_next(&mut self) + -> (~[ast::Attribute], ~[ast::Attribute]); + fn parse_meta_item(&mut self) -> @ast::MetaItem; + fn parse_meta_seq(&mut self) -> ~[@ast::MetaItem]; + fn parse_optional_meta(&mut self) -> ~[@ast::MetaItem]; } impl parser_attr for Parser { - // Parse attributes that appear before an item - fn parse_outer_attributes(&self) -> ~[ast::Attribute] { + fn parse_outer_attributes(&mut self) -> ~[ast::Attribute] { let mut attrs: ~[ast::Attribute] = ~[]; loop { debug!("parse_outer_attributes: self.token={:?}", self.token); - match *self.token { + match self.token { token::INTERPOLATED(token::nt_attr(..)) => { attrs.push(self.parse_attribute(false)); } @@ -66,10 +65,10 @@ impl parser_attr for Parser { // // if permit_inner is true, then a trailing `;` indicates an inner // attribute - fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute { + fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute { debug!("parse_attributes: permit_inner={:?} self.token={:?}", permit_inner, self.token); - let (span, value) = match *self.token { + let (span, value) = match self.token { INTERPOLATED(token::nt_attr(attr)) => { assert!(attr.node.style == ast::AttrOuter); self.bump(); @@ -85,11 +84,12 @@ impl parser_attr for Parser { (mk_sp(lo, hi), meta_item) } _ => { + let token_str = self.this_token_to_str(); self.fatal(format!("expected `\\#` but found `{}`", - self.this_token_to_str())); + token_str)); } }; - let style = if permit_inner && *self.token == token::SEMI { + let style = if permit_inner && self.token == token::SEMI { self.bump(); ast::AttrInner } else { @@ -115,12 +115,12 @@ impl parser_attr for Parser { // matches inner_attrs* outer_attr? // you can make the 'next' field an Option, but the result is going to be // more useful as a vector. - fn parse_inner_attrs_and_next(&self) + fn parse_inner_attrs_and_next(&mut self) -> (~[ast::Attribute], ~[ast::Attribute]) { let mut inner_attrs: ~[ast::Attribute] = ~[]; let mut next_outer_attrs: ~[ast::Attribute] = ~[]; loop { - let attr = match *self.token { + let attr = match self.token { token::INTERPOLATED(token::nt_attr(..)) => { self.parse_attribute(true) } @@ -154,10 +154,11 @@ impl parser_attr for Parser { // matches meta_item = IDENT // | IDENT = lit // | IDENT meta_seq - fn parse_meta_item(&self) -> @ast::MetaItem { + fn parse_meta_item(&mut self) -> @ast::MetaItem { let lo = self.span.lo; - let name = self.id_to_str(self.parse_ident()); - match *self.token { + let ident = self.parse_ident(); + let name = self.id_to_str(ident); + match self.token { token::EQ => { self.bump(); let lit = self.parse_lit(); @@ -187,15 +188,15 @@ impl parser_attr for Parser { } // matches meta_seq = ( COMMASEP(meta_item) ) - fn parse_meta_seq(&self) -> ~[@ast::MetaItem] { + fn parse_meta_seq(&mut self) -> ~[@ast::MetaItem] { self.parse_seq(&token::LPAREN, &token::RPAREN, seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_meta_item()).node } - fn parse_optional_meta(&self) -> ~[@ast::MetaItem] { - match *self.token { + fn parse_optional_meta(&mut self) -> ~[@ast::MetaItem] { + match self.token { token::LPAREN => self.parse_meta_seq(), _ => ~[] } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 0704bf913d7c4..a80d1f117b132 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::span_handler, + @diagnostic::span_handler, 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 d48c1d9d8d7c9..6c164be236d1b 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::either; use std::num::from_str_radix; @@ -26,12 +27,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 span_handler; - 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) -> @span_handler; + fn peek(@self) -> TokenAndSpan; + fn dup(@self) -> @reader; } #[deriving(Clone, Eq)] @@ -41,47 +42,47 @@ pub struct TokenAndSpan { } pub struct StringReader { - span_diagnostic: @mut span_handler, + span_diagnostic: @span_handler, src: @str, // The absolute offset within the codemap of the next character to read - pos: BytePos, + pos: Cell, // The absolute offset within the codemap of the last character read(curr) - last_pos: BytePos, + last_pos: Cell, // The column of the next character to read - col: CharPos, + col: Cell, // The last character to be read - curr: char, + curr: Cell, filemap: @codemap::FileMap, /* cached: */ - peek_tok: token::Token, - peek_span: Span + peek_tok: RefCell, + peek_span: RefCell, } -pub fn new_string_reader(span_diagnostic: @mut span_handler, +pub fn new_string_reader(span_diagnostic: @span_handler, 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 span_handler, +pub fn new_low_level_string_reader(span_diagnostic: @span_handler, 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; @@ -90,78 +91,84 @@ pub fn new_low_level_string_reader(span_diagnostic: @mut span_handler, // 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 span_handler { self.span_diagnostic } - fn peek(@mut self) -> TokenAndSpan { + fn span_diag(@self) -> @span_handler { 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 span_handler { self.sp_diag } - fn peek(@mut self) -> TokenAndSpan { + fn span_diag(@self) -> @span_handler { 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, @@ -175,7 +182,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) @@ -191,19 +198,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())); }; } } @@ -217,17 +225,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( - 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( - rdr: @mut StringReader, + rdr: @StringReader, start: BytePos, end: BytePos, f: |s: &str| -> T) @@ -239,20 +247,22 @@ fn with_str_from_to( // 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 { @@ -260,14 +270,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 @@ -297,9 +307,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 { - while is_whitespace(rdr.curr) { bump(rdr); } + while is_whitespace(rdr.curr.get()) { bump(rdr); } return consume_any_line_comment(rdr); } @@ -310,17 +320,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 { - 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| { @@ -328,7 +338,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 @@ -339,7 +349,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); @@ -347,15 +357,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); } } @@ -368,11 +381,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 { +fn consume_block_comment(rdr: @StringReader) -> Option { // 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 { @@ -382,12 +394,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); @@ -402,7 +414,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 @@ -416,13 +428,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); @@ -431,16 +443,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(_) => { @@ -452,12 +464,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); @@ -472,7 +484,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' { let signed = c == 'i'; @@ -481,7 +493,7 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { else { either::Right(ast::ty_u) } }; bump(rdr); - c = rdr.curr; + c = rdr.curr.get(); if c == '8' { bump(rdr); tp = if signed { either::Left(ast::ty_i8) } @@ -505,12 +517,12 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { else { either::Right(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::(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::(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 73240a9effd9f..7975174f98680 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 span_handler, // better be the same as the one in the reader! + span_diagnostic: @span_handler, // 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 span_handler, +pub fn new_parse_sess_special_handler(sh: @span_handler, 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 span_handler, 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,9 +83,9 @@ 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 parser = new_parser_from_file(sess, cfg, input); + let mut parser = new_parser_from_file(sess, cfg, input); let (inner, _) = parser.parse_inner_attrs_and_next(); return inner; } @@ -93,12 +94,12 @@ pub fn parse_crate_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ast::Crate { - let p = new_parser_from_source_str(sess, - /*bad*/ cfg.clone(), - name, - source); + let mut p = new_parser_from_source_str(sess, + /*bad*/ cfg.clone(), + name, + source); maybe_aborted(p.parse_crate_mod(),p) } @@ -106,12 +107,12 @@ pub fn parse_crate_attrs_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ~[ast::Attribute] { - let p = new_parser_from_source_str(sess, - /*bad*/ cfg.clone(), - name, - source); + let mut p = new_parser_from_source_str(sess, + /*bad*/ cfg.clone(), + name, + source); let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p); return inner; } @@ -120,14 +121,9 @@ pub fn parse_expr_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> @ast::Expr { - let p = new_parser_from_source_str( - sess, - cfg, - name, - source - ); + let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_expr(), p) } @@ -136,14 +132,9 @@ pub fn parse_item_from_source_str( source: @str, cfg: ast::CrateConfig, attrs: ~[ast::Attribute], - sess: @mut ParseSess + sess: @ParseSess ) -> Option<@ast::item> { - let p = new_parser_from_source_str( - sess, - cfg, - name, - source - ); + let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_item(attrs),p) } @@ -151,14 +142,9 @@ pub fn parse_meta_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> @ast::MetaItem { - let p = new_parser_from_source_str( - sess, - cfg, - name, - source - ); + let mut p = new_parser_from_source_str(sess, cfg, name, source); maybe_aborted(p.parse_meta_item(),p) } @@ -167,9 +153,9 @@ pub fn parse_stmt_from_source_str( source: @str, cfg: ast::CrateConfig, attrs: ~[ast::Attribute], - sess: @mut ParseSess + sess: @ParseSess ) -> @ast::Stmt { - let p = new_parser_from_source_str( + let mut p = new_parser_from_source_str( sess, cfg, name, @@ -182,15 +168,15 @@ pub fn parse_tts_from_source_str( name: @str, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess + sess: @ParseSess ) -> ~[ast::token_tree] { - let p = new_parser_from_source_str( + let mut p = new_parser_from_source_str( sess, cfg, name, source ); - *p.quote_depth += 1u; + p.quote_depth += 1u; // right now this is re-creating the token trees from ... token trees. maybe_aborted(p.parse_all_token_trees(),p) } @@ -201,15 +187,15 @@ pub fn parse_tts_from_source_str( // consumed all of the input before returning the function's // result. pub fn parse_from_source_str( - f: |&Parser| -> T, + f: |&mut Parser| -> T, name: @str, ss: codemap::FileSubstr, source: @str, cfg: ast::CrateConfig, - sess: @mut ParseSess) + sess: @ParseSess) -> T { - let p = new_parser_from_source_substr(sess, cfg, name, ss, source); - let r = f(&p); + let mut p = new_parser_from_source_substr(sess, cfg, name, ss, source); + let r = f(&mut p); if !p.reader.is_eof() { p.reader.fatal(~"expected end-of-string"); } @@ -217,7 +203,7 @@ pub fn parse_from_source_str( } // 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) @@ -227,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, @@ -239,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 { @@ -250,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 @@ -259,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) @@ -267,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) @@ -278,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) +pub fn file_to_filemap(sess: @ParseSess, path: &Path, spanopt: Option) -> @FileMap { let err = |msg: &str| { match spanopt { @@ -307,39 +293,39 @@ pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option) // 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 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 -pub fn maybe_aborted(result : T, p: Parser) -> T { +pub fn maybe_aborted(result: T, mut p: Parser) -> T { p.abort_if_errors(); result } @@ -646,7 +632,7 @@ mod test { } fn parser_done(p: Parser){ - assert_eq!((*p.token).clone(), token::EOF); + assert_eq!(p.token.clone(), token::EOF); } #[test] fn parse_ident_pat () { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index d739fca99da07..1991d8b6cd6fc 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -20,7 +20,6 @@ removed. use ast::{Expr, ExprLit, lit_nil}; use codemap::{Span, respan}; use parse::parser::Parser; -use parse::token::Token; use parse::token; use std::str; @@ -56,23 +55,22 @@ impl to_bytes::IterBytes for ObsoleteSyntax { pub trait ParserObsoleteMethods { /// Reports an obsolete syntax non-fatal error. - fn obsolete(&self, sp: Span, kind: ObsoleteSyntax); + fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax); // Reports an obsolete syntax non-fatal error, and returns // a placeholder expression - fn obsolete_expr(&self, sp: Span, kind: ObsoleteSyntax) -> @Expr; - fn report(&self, + fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr; + fn report(&mut self, sp: Span, kind: ObsoleteSyntax, kind_str: &str, desc: &str); - fn token_is_obsolete_ident(&self, ident: &str, token: &Token) -> bool; - fn is_obsolete_ident(&self, ident: &str) -> bool; - fn eat_obsolete_ident(&self, ident: &str) -> bool; + fn is_obsolete_ident(&mut self, ident: &str) -> bool; + fn eat_obsolete_ident(&mut self, ident: &str) -> bool; } impl ParserObsoleteMethods for Parser { /// Reports an obsolete syntax non-fatal error. - fn obsolete(&self, sp: Span, kind: ObsoleteSyntax) { + fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) { let (kind_str, desc) = match kind { ObsoleteSwap => ( "swap", @@ -152,12 +150,12 @@ impl ParserObsoleteMethods for Parser { // Reports an obsolete syntax non-fatal error, and returns // a placeholder expression - fn obsolete_expr(&self, sp: Span, kind: ObsoleteSyntax) -> @Expr { + fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> @Expr { self.obsolete(sp, kind); self.mk_expr(sp.lo, sp.hi, ExprLit(@respan(sp, lit_nil))) } - fn report(&self, + fn report(&mut self, sp: Span, kind: ObsoleteSyntax, kind_str: &str, @@ -170,9 +168,8 @@ impl ParserObsoleteMethods for Parser { } } - fn token_is_obsolete_ident(&self, ident: &str, token: &Token) - -> bool { - match *token { + fn is_obsolete_ident(&mut self, ident: &str) -> bool { + match self.token { token::IDENT(sid, _) => { str::eq_slice(self.id_to_str(sid), ident) } @@ -180,11 +177,7 @@ impl ParserObsoleteMethods for Parser { } } - fn is_obsolete_ident(&self, ident: &str) -> bool { - self.token_is_obsolete_ident(ident, self.token) - } - - fn eat_obsolete_ident(&self, ident: &str) -> bool { + fn eat_obsolete_ident(&mut self, ident: &str) -> bool { if self.is_obsolete_ident(ident) { self.bump(); true diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 729d032043528..28ed56520adb8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -81,6 +81,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; @@ -143,15 +144,17 @@ macro_rules! maybe_whole_expr ( { // This horrible convolution is brought to you by // @mut, have a terrible day - let ret = match *($p).token { + let mut maybe_path = match ($p).token { + INTERPOLATED(token::nt_path(ref pt)) => Some((**pt).clone()), + _ => None, + }; + let ret = match ($p).token { INTERPOLATED(token::nt_expr(e)) => { Some(e) } - INTERPOLATED(token::nt_path(ref pt)) => { - Some($p.mk_expr( - ($p).span.lo, - ($p).span.hi, - ExprPath(/* bad */ (**pt).clone()))) + INTERPOLATED(token::nt_path(_)) => { + let pt = maybe_path.take_unwrap(); + Some($p.mk_expr(($p).span.lo, ($p).span.hi, ExprPath(pt))) } _ => None }; @@ -169,7 +172,7 @@ macro_rules! maybe_whole_expr ( macro_rules! maybe_whole ( ($p:expr, $constructor:ident) => ( { - let __found__ = match *($p).token { + let __found__ = match ($p).token { INTERPOLATED(token::$constructor(_)) => { Some(($p).bump_and_get()) } @@ -185,7 +188,7 @@ macro_rules! maybe_whole ( ); (no_clone $p:expr, $constructor:ident) => ( { - let __found__ = match *($p).token { + let __found__ = match ($p).token { INTERPOLATED(token::$constructor(_)) => { Some(($p).bump_and_get()) } @@ -201,7 +204,7 @@ macro_rules! maybe_whole ( ); (deref $p:expr, $constructor:ident) => ( { - let __found__ = match *($p).token { + let __found__ = match ($p).token { INTERPOLATED(token::$constructor(_)) => { Some(($p).bump_and_get()) } @@ -217,7 +220,7 @@ macro_rules! maybe_whole ( ); (Some $p:expr, $constructor:ident) => ( { - let __found__ = match *($p).token { + let __found__ = match ($p).token { INTERPOLATED(token::$constructor(_)) => { Some(($p).bump_and_get()) } @@ -233,7 +236,7 @@ macro_rules! maybe_whole ( ); (iovi $p:expr, $constructor:ident) => ( { - let __found__ = match *($p).token { + let __found__ = match ($p).token { INTERPOLATED(token::$constructor(_)) => { Some(($p).bump_and_get()) } @@ -249,7 +252,7 @@ macro_rules! maybe_whole ( ); (pair_empty $p:expr, $constructor:ident) => ( { - let __found__ = match *($p).token { + let __found__ = match ($p).token { INTERPOLATED(token::$constructor(_)) => { Some(($p).bump_and_get()) } @@ -284,10 +287,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; @@ -301,55 +302,54 @@ pub fn Parser(sess: @mut ParseSess, interner: interner, sess: sess, cfg: cfg, - token: @mut tok0.tok, - span: @mut span, - last_span: @mut span, - last_token: @mut None, - buffer: @mut ([ + token: tok0.tok, + span: span, + last_span: span, + last_token: None, + buffer: [ placeholder.clone(), placeholder.clone(), placeholder.clone(), placeholder.clone(), - ]), - buffer_start: @mut 0, - buffer_end: @mut 0, - tokens_consumed: @mut 0, - restriction: @mut UNRESTRICTED, - quote_depth: @mut 0, - obsolete_set: @mut HashSet::new(), - mod_path_stack: @mut ~[], - open_braces: @mut ~[], + ], + buffer_start: 0, + buffer_end: 0, + tokens_consumed: 0, + restriction: UNRESTRICTED, + quote_depth: 0, + obsolete_set: HashSet::new(), + mod_path_stack: ~[], + open_braces: ~[], non_copyable: util::NonCopyable } } -// ooh, nasty mutable fields everywhere.... pub struct Parser { - sess: @mut ParseSess, + sess: @ParseSess, cfg: CrateConfig, // the current token: - token: @mut token::Token, + token: token::Token, // the span of the current token: - span: @mut Span, + span: Span, // the span of the prior token: - last_span: @mut Span, + last_span: Span, // the previous token or None (only stashed sometimes). - last_token: @mut Option<~token::Token>, - buffer: @mut [TokenAndSpan, ..4], - buffer_start: @mut int, - buffer_end: @mut int, - tokens_consumed: @mut uint, - restriction: @mut restriction, - quote_depth: @mut uint, // not (yet) related to the quasiquoter - reader: @mut reader, + last_token: Option<~token::Token>, + buffer: [TokenAndSpan, ..4], + buffer_start: int, + buffer_end: int, + tokens_consumed: uint, + restriction: restriction, + quote_depth: uint, // not (yet) related to the quasiquoter + 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 - obsolete_set: @mut HashSet, + obsolete_set: HashSet, /// Used to determine the path to externally loaded source files - mod_path_stack: @mut ~[@str], + mod_path_stack: ~[@str], /// Stack of spans of open delimiters. Used for error message. - open_braces: @mut ~[Span], + open_braces: ~[Span], /* do not copy the parser; its state is tied to outside state */ priv non_copyable: util::NonCopyable } @@ -360,67 +360,59 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool { impl Parser { // convert a token to a string using self's reader - pub fn token_to_str(&self, token: &token::Token) -> ~str { + pub fn token_to_str(token: &token::Token) -> ~str { token::to_str(get_ident_interner(), token) } // convert the current token to a string using self's reader - pub fn this_token_to_str(&self) -> ~str { - self.token_to_str(self.token) + pub fn this_token_to_str(&mut self) -> ~str { + Parser::token_to_str(&self.token) } - pub fn unexpected_last(&self, t: &token::Token) -> ! { - self.span_fatal( - *self.last_span, - format!( - "unexpected token: `{}`", - self.token_to_str(t) - ) - ); + pub fn unexpected_last(&mut self, t: &token::Token) -> ! { + let token_str = Parser::token_to_str(t); + self.span_fatal(self.last_span, format!("unexpected token: `{}`", + token_str)); } - pub fn unexpected(&self) -> ! { - self.fatal( - format!( - "unexpected token: `{}`", - self.this_token_to_str() - ) - ); + pub fn unexpected(&mut self) -> ! { + let this_token = self.this_token_to_str(); + self.fatal(format!("unexpected token: `{}`", this_token)); } // expect and consume the token t. Signal an error if // the next token is not t. - pub fn expect(&self, t: &token::Token) { - if *self.token == *t { + pub fn expect(&mut self, t: &token::Token) { + if self.token == *t { self.bump(); } else { - self.fatal( - format!( - "expected `{}` but found `{}`", - self.token_to_str(t), - self.this_token_to_str() - ) - ) + let token_str = Parser::token_to_str(t); + let this_token_str = self.this_token_to_str(); + self.fatal(format!("expected `{}` but found `{}`", + token_str, + this_token_str)) } } // Expect next token to be edible or inedible token. If edible, // then consume it; if inedible, then return without consuming // anything. Signal a fatal error if next token is unexpected. - pub fn expect_one_of(&self, edible: &[token::Token], inedible: &[token::Token]) { - fn tokens_to_str(p:&Parser, tokens: &[token::Token]) -> ~str { + pub fn expect_one_of(&mut self, + edible: &[token::Token], + inedible: &[token::Token]) { + fn tokens_to_str(tokens: &[token::Token]) -> ~str { let mut i = tokens.iter(); // This might be a sign we need a connect method on Iterator. - let b = i.next().map_default(~"", |t| p.token_to_str(t)); - i.fold(b, |b,a| b + "`, `" + p.token_to_str(a)) + let b = i.next().map_default(~"", |t| Parser::token_to_str(t)); + i.fold(b, |b,a| b + "`, `" + Parser::token_to_str(a)) } - if edible.contains(self.token) { + if edible.contains(&self.token) { self.bump(); - } else if inedible.contains(self.token) { + } else if inedible.contains(&self.token) { // leave it in the input } else { let expected = vec::append(edible.to_owned(), inedible); - let expect = tokens_to_str(self, expected); + let expect = tokens_to_str(expected); let actual = self.this_token_to_str(); self.fatal( if expected.len() != 1 { @@ -435,12 +427,12 @@ impl Parser { // Check for erroneous `ident { }`; if matches, signal error and // recover (without consuming any expected input token). Returns // true if and only if input was consumed for recovery. - pub fn check_for_erroneous_unit_struct_expecting(&self, expected: &[token::Token]) -> bool { - if *self.token == token::LBRACE + pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool { + if self.token == token::LBRACE && expected.iter().all(|t| *t != token::LBRACE) && self.look_ahead(1, |t| *t == token::RBRACE) { // matched; signal non-fatal error and recover. - self.span_err(*self.span, + self.span_err(self.span, "Unit-like struct construction is written with no trailing `{ }`"); self.eat(&token::LBRACE); self.eat(&token::RBRACE); @@ -453,7 +445,7 @@ impl Parser { // Commit to parsing a complete expression `e` expected to be // followed by some token from the set edible + inedible. Recover // from anticipated input errors, discarding erroneous characters. - pub fn commit_expr(&self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) { + pub fn commit_expr(&mut self, e: @Expr, edible: &[token::Token], inedible: &[token::Token]) { debug!("commit_expr {:?}", e); match e.node { ExprPath(..) => { @@ -466,14 +458,14 @@ impl Parser { self.expect_one_of(edible, inedible) } - pub fn commit_expr_expecting(&self, e: @Expr, edible: token::Token) { + pub fn commit_expr_expecting(&mut self, e: @Expr, edible: token::Token) { self.commit_expr(e, &[edible], &[]) } // Commit to parsing a complete statement `s`, which expects to be // followed by some token from the set edible + inedible. Check // for recoverable input errors, discarding erroneous characters. - pub fn commit_stmt(&self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) { + pub fn commit_stmt(&mut self, s: @Stmt, edible: &[token::Token], inedible: &[token::Token]) { debug!("commit_stmt {:?}", s); let _s = s; // unused, but future checks might want to inspect `s`. if self.last_token.as_ref().map_default(false, |t| is_ident_or_path(*t)) { @@ -483,14 +475,14 @@ impl Parser { self.expect_one_of(edible, inedible) } - pub fn commit_stmt_expecting(&self, s: @Stmt, edible: token::Token) { + pub fn commit_stmt_expecting(&mut self, s: @Stmt, edible: token::Token) { self.commit_stmt(s, &[edible], &[]) } - pub fn parse_ident(&self) -> ast::Ident { + pub fn parse_ident(&mut self) -> ast::Ident { self.check_strict_keywords(); self.check_reserved_keywords(); - match *self.token { + match self.token { token::IDENT(i, _) => { self.bump(); i @@ -499,17 +491,13 @@ impl Parser { self.bug("ident interpolation not converted to real token"); } _ => { - self.fatal( - format!( - "expected ident, found `{}`", - self.this_token_to_str() - ) - ); + let token_str = self.this_token_to_str(); + self.fatal(format!( "expected ident, found `{}`", token_str)) } } } - pub fn parse_path_list_ident(&self) -> ast::path_list_ident { + pub fn parse_path_list_ident(&mut self) -> ast::path_list_ident { let lo = self.span.lo; let ident = self.parse_ident(); let hi = self.last_span.hi; @@ -519,20 +507,20 @@ impl Parser { // consume token 'tok' if it exists. Returns true if the given // token was present, false otherwise. - pub fn eat(&self, tok: &token::Token) -> bool { - let is_present = *self.token == *tok; + pub fn eat(&mut self, tok: &token::Token) -> bool { + let is_present = self.token == *tok; if is_present { self.bump() } is_present } - pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { - token::is_keyword(kw, self.token) + pub fn is_keyword(&mut self, kw: keywords::Keyword) -> bool { + token::is_keyword(kw, &self.token) } // if the next token is the given keyword, eat it and return // true. Otherwise, return false. - pub fn eat_keyword(&self, kw: keywords::Keyword) -> bool { - let is_kw = match *self.token { + pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool { + let is_kw = match self.token { token::IDENT(sid, false) => kw.to_ident().name == sid.name, _ => false }; @@ -543,59 +531,63 @@ impl Parser { // if the given word is not a keyword, signal an error. // if the next token is not the given word, signal an error. // otherwise, eat it. - pub fn expect_keyword(&self, kw: keywords::Keyword) { + pub fn expect_keyword(&mut self, kw: keywords::Keyword) { if !self.eat_keyword(kw) { - self.fatal( - format!( - "expected `{}`, found `{}`", - self.id_to_str(kw.to_ident()).to_str(), - self.this_token_to_str() - ) - ); + let id_str = self.id_to_str(kw.to_ident()).to_str(); + let token_str = self.this_token_to_str(); + self.fatal(format!("expected `{}`, found `{}`", + id_str, + token_str)) } } // signal an error if the given string is a strict keyword - pub fn check_strict_keywords(&self) { - if token::is_strict_keyword(self.token) { - self.span_err(*self.span, - format!("found `{}` in ident position", self.this_token_to_str())); + pub fn check_strict_keywords(&mut self) { + if token::is_strict_keyword(&self.token) { + let token_str = self.this_token_to_str(); + self.span_err(self.span, + format!("found `{}` in ident position", token_str)); } } // signal an error if the current token is a reserved keyword - pub fn check_reserved_keywords(&self) { - if token::is_reserved_keyword(self.token) { - self.fatal(format!("`{}` is a reserved keyword", self.this_token_to_str())); + pub fn check_reserved_keywords(&mut self) { + if token::is_reserved_keyword(&self.token) { + let token_str = self.this_token_to_str(); + self.fatal(format!("`{}` is a reserved keyword", token_str)) } } // Expect and consume a `|`. If `||` is seen, replace it with a single // `|` and continue. If a `|` is not seen, signal an error. - fn expect_or(&self) { - match *self.token { + fn expect_or(&mut self) { + match self.token { token::BINOP(token::OR) => self.bump(), token::OROR => { - self.replace_token(token::BINOP(token::OR), - self.span.lo + BytePos(1), - self.span.hi) + let lo = self.span.lo + BytePos(1); + self.replace_token(token::BINOP(token::OR), lo, self.span.hi) } _ => { - let found_token = self.token_to_str(&token::BINOP(token::OR)); + let token_str = self.this_token_to_str(); + let found_token = + Parser::token_to_str(&token::BINOP(token::OR)); self.fatal(format!("expected `{}`, found `{}`", found_token, - self.this_token_to_str())) + token_str)) } } } // Parse a sequence bracketed by `|` and `|`, stopping before the `|`. - fn parse_seq_to_before_or(&self, sep: &token::Token, f: |&Parser| -> T) + fn parse_seq_to_before_or( + &mut self, + sep: &token::Token, + f: |&mut Parser| -> T) -> ~[T] { let mut first = true; let mut vector = ~[]; - while *self.token != token::BINOP(token::OR) && - *self.token != token::OROR { + while self.token != token::BINOP(token::OR) && + self.token != token::OROR { if first { first = false } else { @@ -610,31 +602,34 @@ impl Parser { // expect and consume a GT. if a >> is seen, replace it // with a single > and continue. If a GT is not seen, // signal an error. - pub fn expect_gt(&self) { - match *self.token { + pub fn expect_gt(&mut self) { + match self.token { token::GT => self.bump(), - token::BINOP(token::SHR) => self.replace_token( - token::GT, - self.span.lo + BytePos(1), - self.span.hi - ), - _ => self.fatal(format!("expected `{}`, found `{}`", - self.token_to_str(&token::GT), - self.this_token_to_str())) + token::BINOP(token::SHR) => { + let lo = self.span.lo + BytePos(1); + self.replace_token(token::GT, lo, self.span.hi) + } + _ => { + let gt_str = Parser::token_to_str(&token::GT); + let this_token_str = self.this_token_to_str(); + self.fatal(format!("expected `{}`, found `{}`", + gt_str, + this_token_str)) + } } } // parse a sequence bracketed by '<' and '>', stopping // before the '>'. pub fn parse_seq_to_before_gt( - &self, + &mut self, sep: Option, - f: |&Parser| -> T) + f: |&mut Parser| -> T) -> OptVec { let mut first = true; let mut v = opt_vec::Empty; - while *self.token != token::GT - && *self.token != token::BINOP(token::SHR) { + while self.token != token::GT + && self.token != token::BINOP(token::SHR) { match sep { Some(ref t) => { if first { first = false; } @@ -648,9 +643,9 @@ impl Parser { } pub fn parse_seq_to_gt( - &self, + &mut self, sep: Option, - f: |&Parser| -> T) + f: |&mut Parser| -> T) -> OptVec { let v = self.parse_seq_to_before_gt(sep, f); self.expect_gt(); @@ -661,10 +656,10 @@ impl Parser { // f must consume tokens until reaching the next separator or // closing bracket. pub fn parse_seq_to_end( - &self, + &mut self, ket: &token::Token, sep: SeqSep, - f: |&Parser| -> T) + f: |&mut Parser| -> T) -> ~[T] { let val = self.parse_seq_to_before_end(ket, sep, f); self.bump(); @@ -675,14 +670,14 @@ impl Parser { // f must consume tokens until reaching the next separator or // closing bracket. pub fn parse_seq_to_before_end( - &self, + &mut self, ket: &token::Token, sep: SeqSep, - f: |&Parser| -> T) + f: |&mut Parser| -> T) -> ~[T] { let mut first: bool = true; let mut v: ~[T] = ~[]; - while *self.token != *ket { + while self.token != *ket { match sep.sep { Some(ref t) => { if first { first = false; } @@ -690,7 +685,7 @@ impl Parser { } _ => () } - if sep.trailing_sep_allowed && *self.token == *ket { break; } + if sep.trailing_sep_allowed && self.token == *ket { break; } v.push(f(self)); } return v; @@ -700,11 +695,11 @@ impl Parser { // f must consume tokens until reaching the next separator or // closing bracket. pub fn parse_unspanned_seq( - &self, + &mut self, bra: &token::Token, ket: &token::Token, sep: SeqSep, - f: |&Parser| -> T) + f: |&mut Parser| -> T) -> ~[T] { self.expect(bra); let result = self.parse_seq_to_before_end(ket, sep, f); @@ -715,11 +710,11 @@ impl Parser { // NB: Do not use this function unless you actually plan to place the // spanned list in the AST. pub fn parse_seq( - &self, + &mut self, bra: &token::Token, ket: &token::Token, sep: SeqSep, - f: |&Parser| -> T) + f: |&mut Parser| -> T) -> Spanned<~[T]> { let lo = self.span.lo; self.expect(bra); @@ -730,98 +725,98 @@ impl Parser { } // advance the parser by one token - pub fn bump(&self) { - *self.last_span = *self.span; + pub fn bump(&mut self) { + self.last_span = self.span; // Stash token for error recovery (sometimes; clone is not necessarily cheap). - *self.last_token = if is_ident_or_path(self.token) { - Some(~(*self.token).clone()) + self.last_token = if is_ident_or_path(&self.token) { + Some(~self.token.clone()) } else { None }; - let next = if *self.buffer_start == *self.buffer_end { + let next = if self.buffer_start == self.buffer_end { self.reader.next_token() } else { // Avoid token copies with `util::replace`. - let buffer_start = *self.buffer_start as uint; + let buffer_start = self.buffer_start as uint; let next_index = (buffer_start + 1) & 3 as uint; - *self.buffer_start = next_index as int; + self.buffer_start = next_index as int; let placeholder = TokenAndSpan { tok: token::UNDERSCORE, - sp: *self.span, + sp: self.span, }; util::replace(&mut self.buffer[buffer_start], placeholder) }; - *self.span = next.sp; - *self.token = next.tok; - *self.tokens_consumed += 1u; + self.span = next.sp; + self.token = next.tok; + self.tokens_consumed += 1u; } // Advance the parser by one token and return the bumped token. - pub fn bump_and_get(&self) -> token::Token { - let old_token = util::replace(self.token, token::UNDERSCORE); + pub fn bump_and_get(&mut self) -> token::Token { + let old_token = util::replace(&mut self.token, token::UNDERSCORE); self.bump(); old_token } // EFFECT: replace the current token and span with the given one - pub fn replace_token(&self, + pub fn replace_token(&mut self, next: token::Token, lo: BytePos, hi: BytePos) { - *self.token = next; - *self.span = mk_sp(lo, hi); + self.token = next; + self.span = mk_sp(lo, hi); } - pub fn buffer_length(&self) -> int { - if *self.buffer_start <= *self.buffer_end { - return *self.buffer_end - *self.buffer_start; + pub fn buffer_length(&mut self) -> int { + if self.buffer_start <= self.buffer_end { + return self.buffer_end - self.buffer_start; } - return (4 - *self.buffer_start) + *self.buffer_end; + return (4 - self.buffer_start) + self.buffer_end; } - pub fn look_ahead(&self, distance: uint, f: |&token::Token| -> R) + pub fn look_ahead(&mut self, distance: uint, f: |&token::Token| -> R) -> R { let dist = distance as int; while self.buffer_length() < dist { - self.buffer[*self.buffer_end] = self.reader.next_token(); - *self.buffer_end = (*self.buffer_end + 1) & 3; + self.buffer[self.buffer_end] = self.reader.next_token(); + self.buffer_end = (self.buffer_end + 1) & 3; } - f(&self.buffer[(*self.buffer_start + dist - 1) & 3].tok) + f(&self.buffer[(self.buffer_start + dist - 1) & 3].tok) } - pub fn fatal(&self, m: &str) -> ! { - self.sess.span_diagnostic.span_fatal(*self.span, m) + pub fn fatal(&mut self, m: &str) -> ! { + self.sess.span_diagnostic.span_fatal(self.span, m) } - pub fn span_fatal(&self, sp: Span, m: &str) -> ! { + pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! { self.sess.span_diagnostic.span_fatal(sp, m) } - pub fn span_note(&self, sp: Span, m: &str) { + pub fn span_note(&mut self, sp: Span, m: &str) { self.sess.span_diagnostic.span_note(sp, m) } - pub fn bug(&self, m: &str) -> ! { - self.sess.span_diagnostic.span_bug(*self.span, m) + pub fn bug(&mut self, m: &str) -> ! { + self.sess.span_diagnostic.span_bug(self.span, m) } - pub fn warn(&self, m: &str) { - self.sess.span_diagnostic.span_warn(*self.span, m) + pub fn warn(&mut self, m: &str) { + self.sess.span_diagnostic.span_warn(self.span, m) } - pub fn span_err(&self, sp: Span, m: &str) { + pub fn span_err(&mut self, sp: Span, m: &str) { self.sess.span_diagnostic.span_err(sp, m) } - pub fn abort_if_errors(&self) { + pub fn abort_if_errors(&mut self) { self.sess.span_diagnostic.handler().abort_if_errors(); } - pub fn id_to_str(&self, id: Ident) -> @str { + pub fn id_to_str(&mut self, id: Ident) -> @str { get_ident_interner().get(id.name) } // Is the current token one of the keywords that signals a bare function // type? - pub fn token_is_bare_fn_keyword(&self) -> bool { - if token::is_keyword(keywords::Fn, self.token) { + pub fn token_is_bare_fn_keyword(&mut self) -> bool { + if token::is_keyword(keywords::Fn, &self.token) { return true } - if token::is_keyword(keywords::Unsafe, self.token) || - token::is_keyword(keywords::Once, self.token) { + if token::is_keyword(keywords::Unsafe, &self.token) || + token::is_keyword(keywords::Once, &self.token) { return self.look_ahead(1, |t| token::is_keyword(keywords::Fn, t)) } @@ -829,35 +824,35 @@ impl Parser { } // Is the current token one of the keywords that signals a closure type? - pub fn token_is_closure_keyword(&self) -> bool { - token::is_keyword(keywords::Unsafe, self.token) || - token::is_keyword(keywords::Once, self.token) + pub fn token_is_closure_keyword(&mut self) -> bool { + token::is_keyword(keywords::Unsafe, &self.token) || + token::is_keyword(keywords::Once, &self.token) } // Is the current token one of the keywords that signals an old-style // closure type (with explicit sigil)? - pub fn token_is_old_style_closure_keyword(&self) -> bool { - token::is_keyword(keywords::Unsafe, self.token) || - token::is_keyword(keywords::Once, self.token) || - token::is_keyword(keywords::Fn, self.token) + pub fn token_is_old_style_closure_keyword(&mut self) -> bool { + token::is_keyword(keywords::Unsafe, &self.token) || + token::is_keyword(keywords::Once, &self.token) || + token::is_keyword(keywords::Fn, &self.token) } - pub fn token_is_lifetime(&self, tok: &token::Token) -> bool { + pub fn token_is_lifetime(tok: &token::Token) -> bool { match *tok { token::LIFETIME(..) => true, _ => false, } } - pub fn get_lifetime(&self, tok: &token::Token) -> ast::Ident { - match *tok { + pub fn get_lifetime(&mut self) -> ast::Ident { + match self.token { token::LIFETIME(ref ident) => *ident, _ => self.bug("not a lifetime"), } } // parse a ty_bare_fun type: - pub fn parse_ty_bare_fn(&self) -> ty_ { + pub fn parse_ty_bare_fn(&mut self) -> ty_ { /* [extern "ABI"] [unsafe] fn <'lt> (S) -> T @@ -887,7 +882,7 @@ impl Parser { // Parses a procedure type (`proc`). The initial `proc` keyword must // already have been parsed. - pub fn parse_proc_type(&self) -> ty_ { + pub fn parse_proc_type(&mut self) -> ty_ { let (decl, lifetimes) = self.parse_ty_fn_decl(false); ty_closure(@TyClosure { sigil: OwnedSigil, @@ -901,7 +896,7 @@ impl Parser { } // parse a ty_closure type - pub fn parse_ty_closure(&self, + pub fn parse_ty_closure(&mut self, opt_sigil: Option, mut region: Option) -> ty_ { @@ -943,7 +938,7 @@ impl Parser { // Re-parse the region here. What a hack. if region.is_some() { - self.span_err(*self.last_span, + self.span_err(self.last_span, "lifetime declarations must precede \ the lifetime associated with a \ closure"); @@ -990,7 +985,7 @@ impl Parser { lifetimes: lifetimes, }); - fn parse_onceness(this: &Parser) -> Onceness { + fn parse_onceness(this: &mut Parser) -> Onceness { if this.eat_keyword(keywords::Once) { Once } else { @@ -999,7 +994,7 @@ impl Parser { } } - pub fn parse_unsafety(&self) -> purity { + pub fn parse_unsafety(&mut self) -> purity { if self.eat_keyword(keywords::Unsafe) { return unsafe_fn; } else { @@ -1008,7 +1003,8 @@ impl Parser { } // parse a function type (following the 'fn') - pub fn parse_ty_fn_decl(&self, allow_variadic: bool) -> (P, OptVec) { + pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool) + -> (P, OptVec) { /* (fn) <'lt> (S) -> T @@ -1039,7 +1035,7 @@ impl Parser { } // parse the methods in a trait declaration - pub fn parse_trait_methods(&self) -> ~[trait_method] { + pub fn parse_trait_methods(&mut self) -> ~[trait_method] { self.parse_unspanned_seq( &token::LBRACE, &token::RBRACE, @@ -1048,7 +1044,7 @@ impl Parser { let attrs = p.parse_outer_attributes(); let lo = p.span.lo; - let vis_span = *self.span; + let vis_span = p.span; let vis = p.parse_visibility(); let pur = p.parse_fn_purity(); // NB: at the moment, trait methods are public by default; this @@ -1057,25 +1053,21 @@ impl Parser { let generics = p.parse_generics(); - let (explicit_self, d) = self.parse_fn_decl_with_self(|p| { + let (explicit_self, d) = p.parse_fn_decl_with_self(|p| { // This is somewhat dubious; We don't want to allow argument // names to be left off if there is a definition... p.parse_arg_general(false) }); let hi = p.last_span.hi; - debug!("parse_trait_methods(): trait method signature ends in \ - `{}`", - self.this_token_to_str()); - match *p.token { + match p.token { token::SEMI => { p.bump(); debug!("parse_trait_methods(): parsing required method"); // NB: at the moment, visibility annotations on required // methods are ignored; this could change. if vis != ast::inherited { - self.obsolete(vis_span, - ObsoleteTraitFuncVisibility); + p.obsolete(vis_span, ObsoleteTraitFuncVisibility); } required(TypeMethod { ident: ident, @@ -1109,19 +1101,16 @@ impl Parser { } _ => { - p.fatal( - format!( - "expected `;` or `\\{` but found `{}`", - self.this_token_to_str() - ) - ); - } + let token_str = p.this_token_to_str(); + p.fatal(format!("expected `;` or `\\{` but found `{}`", + token_str)) + } } }) } // parse a possibly mutable type - pub fn parse_mt(&self) -> mt { + pub fn parse_mt(&mut self) -> mt { let mutbl = self.parse_mutability(); let t = self.parse_ty(false); mt { ty: t, mutbl: mutbl } @@ -1129,7 +1118,7 @@ impl Parser { // parse [mut/const/imm] ID : TY // now used only by obsolete record syntax parser... - pub fn parse_ty_field(&self) -> TypeField { + pub fn parse_ty_field(&mut self) -> TypeField { let lo = self.span.lo; let mutbl = self.parse_mutability(); let id = self.parse_ident(); @@ -1144,7 +1133,7 @@ impl Parser { } // parse optional return type [ -> TY ] in function decl - pub fn parse_ret_ty(&self) -> (ret_style, P) { + pub fn parse_ret_ty(&mut self) -> (ret_style, P) { return if self.eat(&token::RARROW) { let lo = self.span.lo; if self.eat(&token::NOT) { @@ -1175,14 +1164,14 @@ impl Parser { // parse a type. // Useless second parameter for compatibility with quasiquote macros. // Bleh! - pub fn parse_ty(&self, _: bool) -> P { + pub fn parse_ty(&mut self, _: bool) -> P { maybe_whole!(no_clone self, nt_ty); let lo = self.span.lo; - let t = if *self.token == token::LPAREN { + let t = if self.token == token::LPAREN { self.bump(); - if *self.token == token::RPAREN { + if self.token == token::RPAREN { self.bump(); ty_nil } else { @@ -1191,9 +1180,9 @@ impl Parser { // of type t let mut ts = ~[self.parse_ty(false)]; let mut one_tuple = false; - while *self.token == token::COMMA { + while self.token == token::COMMA { self.bump(); - if *self.token != token::RPAREN { + if self.token != token::RPAREN { ts.push(self.parse_ty(false)); } else { @@ -1210,19 +1199,19 @@ impl Parser { self.expect(&token::RPAREN); t } - } else if *self.token == token::AT { + } else if self.token == token::AT { // MANAGED POINTER self.bump(); self.parse_box_or_uniq_pointee(ManagedSigil) - } else if *self.token == token::TILDE { + } else if self.token == token::TILDE { // OWNED POINTER self.bump(); self.parse_box_or_uniq_pointee(OwnedSigil) - } else if *self.token == token::BINOP(token::STAR) { + } else if self.token == token::BINOP(token::STAR) { // STAR POINTER (bare pointer?) self.bump(); ty_ptr(self.parse_mt()) - } else if *self.token == token::LBRACKET { + } else if self.token == token::LBRACKET { // VECTOR self.expect(&token::LBRACKET); let t = self.parse_ty(false); @@ -1235,7 +1224,7 @@ impl Parser { }; self.expect(&token::RBRACKET); t - } else if *self.token == token::BINOP(token::AND) { + } else if self.token == token::BINOP(token::AND) { // BORROWED POINTER self.bump(); self.parse_borrowed_pointee() @@ -1244,10 +1233,10 @@ impl Parser { // BARE FUNCTION self.parse_ty_bare_fn() } else if self.token_is_closure_keyword() || - *self.token == token::BINOP(token::OR) || - *self.token == token::OROR || - *self.token == token::LT || - self.token_is_lifetime(self.token) { + self.token == token::BINOP(token::OR) || + self.token == token::OROR || + self.token == token::LT || + Parser::token_is_lifetime(&self.token) { // CLOSURE // // XXX(pcwalton): Eventually `token::LT` will not unambiguously @@ -1266,8 +1255,8 @@ impl Parser { ty_typeof(e) } else if self.eat_keyword(keywords::Proc) { self.parse_proc_type() - } else if *self.token == token::MOD_SEP - || is_ident_or_path(self.token) { + } else if self.token == token::MOD_SEP + || is_ident_or_path(&self.token) { // NAMED TYPE let PathAndBounds { path, @@ -1275,7 +1264,8 @@ impl Parser { } = self.parse_path(LifetimeAndTypesAndBounds); ty_path(path, bounds, ast::DUMMY_NODE_ID) } else { - self.fatal(format!("expected type, found token {:?}", *self.token)); + let msg = format!("expected type, found token {:?}", self.token); + self.fatal(msg); }; let sp = mk_sp(lo, self.last_span.hi); @@ -1283,20 +1273,20 @@ impl Parser { } // parse the type following a @ or a ~ - pub fn parse_box_or_uniq_pointee(&self, + pub fn parse_box_or_uniq_pointee(&mut self, sigil: ast::Sigil) -> ty_ { // ~'foo fn() or ~fn() are parsed directly as obsolete fn types: - match *self.token { + match self.token { token::LIFETIME(..) => { let lifetime = self.parse_lifetime(); - self.obsolete(*self.last_span, ObsoleteBoxedClosure); + self.obsolete(self.last_span, ObsoleteBoxedClosure); return self.parse_ty_closure(Some(sigil), Some(lifetime)); } token::IDENT(..) => { if self.token_is_old_style_closure_keyword() { - self.obsolete(*self.last_span, ObsoleteBoxedClosure); + self.obsolete(self.last_span, ObsoleteBoxedClosure); return self.parse_ty_closure(Some(sigil), None); } } @@ -1314,12 +1304,12 @@ impl Parser { } } - pub fn parse_borrowed_pointee(&self) -> ty_ { + pub fn parse_borrowed_pointee(&mut self) -> ty_ { // look for `&'lt` or `&'foo ` and interpret `foo` as the region name: let opt_lifetime = self.parse_opt_lifetime(); if self.token_is_old_style_closure_keyword() { - self.obsolete(*self.last_span, ObsoleteClosureType); + self.obsolete(self.last_span, ObsoleteClosureType); return self.parse_ty_closure(Some(BorrowedSigil), opt_lifetime); } @@ -1327,18 +1317,18 @@ impl Parser { return ty_rptr(opt_lifetime, mt); } - pub fn is_named_argument(&self) -> bool { - let offset = match *self.token { + pub fn is_named_argument(&mut self) -> bool { + let offset = match self.token { token::BINOP(token::AND) => 1, token::ANDAND => 1, - _ if token::is_keyword(keywords::Mut, self.token) => 1, + _ if token::is_keyword(keywords::Mut, &self.token) => 1, _ => 0 }; debug!("parser is_named_argument offset:{}", offset); if offset == 0 { - is_plain_ident_or_underscore(&*self.token) + is_plain_ident_or_underscore(&self.token) && self.look_ahead(1, |t| *t == token::COLON) } else { self.look_ahead(offset, |t| is_plain_ident_or_underscore(t)) @@ -1348,7 +1338,7 @@ impl Parser { // This version of parse arg doesn't necessarily require // identifier names. - pub fn parse_arg_general(&self, require_name: bool) -> arg { + pub fn parse_arg_general(&mut self, require_name: bool) -> arg { let pat = if require_name || self.is_named_argument() { debug!("parse_arg_general parse_pat (require_name:{:?})", require_name); @@ -1359,7 +1349,7 @@ impl Parser { } else { debug!("parse_arg_general ident_to_pat"); ast_util::ident_to_pat(ast::DUMMY_NODE_ID, - *self.last_span, + self.last_span, special_idents::invalid) }; @@ -1373,12 +1363,12 @@ impl Parser { } // parse a single function argument - pub fn parse_arg(&self) -> arg { + pub fn parse_arg(&mut self) -> arg { self.parse_arg_general(true) } // parse an argument in a lambda header e.g. |arg, arg| - pub fn parse_fn_block_arg(&self) -> arg { + pub fn parse_fn_block_arg(&mut self) -> arg { let pat = self.parse_pat(); let t = if self.eat(&token::COLON) { self.parse_ty(false) @@ -1396,8 +1386,8 @@ impl Parser { } } - pub fn maybe_parse_fixed_vstore(&self) -> Option<@ast::Expr> { - if *self.token == token::COMMA && + pub fn maybe_parse_fixed_vstore(&mut self) -> Option<@ast::Expr> { + if self.token == token::COMMA && self.look_ahead(1, |t| *t == token::DOTDOT) { self.bump(); self.bump(); @@ -1408,7 +1398,7 @@ impl Parser { } // matches token_lit = LIT_INT | ... - pub fn lit_from_token(&self, tok: &token::Token) -> lit_ { + pub fn lit_from_token(&mut self, tok: &token::Token) -> lit_ { match *tok { token::LIT_CHAR(i) => lit_char(i), token::LIT_INT(i, it) => lit_int(i, it), @@ -1425,7 +1415,7 @@ impl Parser { } // matches lit = true | false | token_lit - pub fn parse_lit(&self) -> lit { + pub fn parse_lit(&mut self) -> lit { let lo = self.span.lo; let lit = if self.eat_keyword(keywords::True) { lit_bool(true) @@ -1440,7 +1430,7 @@ impl Parser { } // matches '-' lit | lit - pub fn parse_literal_maybe_minus(&self) -> @Expr { + pub fn parse_literal_maybe_minus(&mut self) -> @Expr { let minus_lo = self.span.lo; let minus_present = self.eat(&token::BINOP(token::MINUS)); @@ -1451,7 +1441,8 @@ impl Parser { if minus_present { let minus_hi = self.span.hi; - self.mk_expr(minus_lo, minus_hi, self.mk_unary(UnNeg, expr)) + let unary = self.mk_unary(UnNeg, expr); + self.mk_expr(minus_lo, minus_hi, unary) } else { expr } @@ -1461,9 +1452,9 @@ impl Parser { /// mode. The `mode` parameter determines whether lifetimes, types, and/or /// bounds are permitted and whether `::` must precede type parameter /// groups. - pub fn parse_path(&self, mode: PathParsingMode) -> PathAndBounds { + pub fn parse_path(&mut self, mode: PathParsingMode) -> PathAndBounds { // Check for a whole path... - let found = match *self.token { + let found = match self.token { INTERPOLATED(token::nt_path(_)) => Some(self.bump_and_get()), _ => None, }; @@ -1580,8 +1571,8 @@ impl Parser { } /// parses 0 or 1 lifetime - pub fn parse_opt_lifetime(&self) -> Option { - match *self.token { + pub fn parse_opt_lifetime(&mut self) -> Option { + match self.token { token::LIFETIME(..) => { Some(self.parse_lifetime()) } @@ -1593,10 +1584,10 @@ impl Parser { /// Parses a single lifetime // matches lifetime = LIFETIME - pub fn parse_lifetime(&self) -> ast::Lifetime { - match *self.token { + pub fn parse_lifetime(&mut self) -> ast::Lifetime { + match self.token { token::LIFETIME(i) => { - let span = *self.span; + let span = self.span; self.bump(); return ast::Lifetime { id: ast::DUMMY_NODE_ID, @@ -1613,7 +1604,7 @@ impl Parser { // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes ) // actually, it matches the empty one too, but putting that in there // messes up the grammar.... - pub fn parse_lifetimes(&self) -> OptVec { + pub fn parse_lifetimes(&mut self) -> OptVec { /*! * * Parses zero or more comma separated lifetimes. @@ -1624,7 +1615,7 @@ impl Parser { let mut res = opt_vec::Empty; loop { - match *self.token { + match self.token { token::LIFETIME(_) => { res.push(self.parse_lifetime()); } @@ -1633,29 +1624,31 @@ impl Parser { } } - match *self.token { + match self.token { token::COMMA => { self.bump();} token::GT => { return res; } token::BINOP(token::SHR) => { return res; } _ => { - self.fatal(format!("expected `,` or `>` after lifetime name, got: {:?}", - *self.token)); + let msg = format!("expected `,` or `>` after lifetime \ + name, got: {:?}", + self.token); + self.fatal(msg); } } } } - pub fn token_is_mutability(&self, tok: &token::Token) -> bool { + pub fn token_is_mutability(tok: &token::Token) -> bool { token::is_keyword(keywords::Mut, tok) || token::is_keyword(keywords::Const, tok) } // parse mutability declaration (mut/const/imm) - pub fn parse_mutability(&self) -> Mutability { + pub fn parse_mutability(&mut self) -> Mutability { if self.eat_keyword(keywords::Mut) { MutMutable } else if self.eat_keyword(keywords::Const) { - self.obsolete(*self.last_span, ObsoleteConstPointer); + self.obsolete(self.last_span, ObsoleteConstPointer); MutImmutable } else { MutImmutable @@ -1663,7 +1656,7 @@ impl Parser { } // parse ident COLON expr - pub fn parse_field(&self) -> Field { + pub fn parse_field(&mut self) -> Field { let lo = self.span.lo; let i = self.parse_ident(); let hi = self.last_span.hi; @@ -1676,7 +1669,7 @@ impl Parser { } } - pub fn mk_expr(&self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr { + pub fn mk_expr(&mut self, lo: BytePos, hi: BytePos, node: Expr_) -> @Expr { @Expr { id: ast::DUMMY_NODE_ID, node: node, @@ -1684,19 +1677,19 @@ impl Parser { } } - pub fn mk_unary(&self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ { + pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ { ExprUnary(ast::DUMMY_NODE_ID, unop, expr) } - pub fn mk_binary(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { + pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs) } - pub fn mk_call(&self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ { + pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ { ExprCall(f, args, sugar) } - pub fn mk_method_call(&self, + pub fn mk_method_call(&mut self, rcvr: @Expr, ident: Ident, tps: ~[P], @@ -1705,19 +1698,19 @@ impl Parser { ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar) } - pub fn mk_index(&self, expr: @Expr, idx: @Expr) -> ast::Expr_ { + pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ { ExprIndex(ast::DUMMY_NODE_ID, expr, idx) } - pub fn mk_field(&self, expr: @Expr, ident: Ident, tys: ~[P]) -> ast::Expr_ { + pub fn mk_field(&mut self, expr: @Expr, ident: Ident, tys: ~[P]) -> ast::Expr_ { ExprField(expr, ident, tys) } - pub fn mk_assign_op(&self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { + pub fn mk_assign_op(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ { ExprAssignOp(ast::DUMMY_NODE_ID, binop, lhs, rhs) } - pub fn mk_mac_expr(&self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr { + pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: mac_) -> @Expr { @Expr { id: ast::DUMMY_NODE_ID, node: ExprMac(codemap::Spanned {node: m, span: mk_sp(lo, hi)}), @@ -1725,8 +1718,8 @@ impl Parser { } } - pub fn mk_lit_u32(&self, i: u32) -> @Expr { - let span = self.span; + pub fn mk_lit_u32(&mut self, i: u32) -> @Expr { + let span = &self.span; let lv_lit = @codemap::Spanned { node: lit_uint(i as u64, ty_u32), span: *span @@ -1742,7 +1735,7 @@ impl Parser { // at the bottom (top?) of the precedence hierarchy, // parse things like parenthesized exprs, // macros, return, etc. - pub fn parse_bottom_expr(&self) -> @Expr { + pub fn parse_bottom_expr(&mut self) -> @Expr { maybe_whole_expr!(self); let lo = self.span.lo; @@ -1750,12 +1743,12 @@ impl Parser { let ex: Expr_; - if *self.token == token::LPAREN { + if self.token == token::LPAREN { self.bump(); // (e) is parenthesized e // (e,) is a tuple with only one field, e let mut trailing_comma = false; - if *self.token == token::RPAREN { + if self.token == token::RPAREN { hi = self.span.hi; self.bump(); let lit = @spanned(lo, hi, lit_nil); @@ -1763,9 +1756,9 @@ impl Parser { } let mut es = ~[self.parse_expr()]; self.commit_expr(*es.last(), &[], &[token::COMMA, token::RPAREN]); - while *self.token == token::COMMA { + while self.token == token::COMMA { self.bump(); - if *self.token != token::RPAREN { + if self.token != token::RPAREN { es.push(self.parse_expr()); self.commit_expr(*es.last(), &[], &[token::COMMA, token::RPAREN]); } @@ -1782,12 +1775,12 @@ impl Parser { else { self.mk_expr(lo, hi, ExprTup(es)) } - } else if *self.token == token::LBRACE { + } else if self.token == token::LBRACE { self.bump(); let blk = self.parse_block_tail(lo, DefaultBlock); return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)); - } else if token::is_bar(&*self.token) { + } else if token::is_bar(&self.token) { return self.parse_lambda_expr(); } else if self.eat_keyword(keywords::Proc) { let decl = self.parse_proc_decl(); @@ -1814,8 +1807,8 @@ impl Parser { ExprDoBody); } else if self.eat_keyword(keywords::While) { return self.parse_while_expr(); - } else if self.token_is_lifetime(&*self.token) { - let lifetime = self.get_lifetime(&*self.token); + } else if Parser::token_is_lifetime(&self.token) { + let lifetime = self.get_lifetime(); self.bump(); self.expect(&token::COLON); if self.eat_keyword(keywords::For) { @@ -1829,8 +1822,8 @@ impl Parser { return self.parse_loop_expr(None); } else if self.eat_keyword(keywords::Continue) { let lo = self.span.lo; - let ex = if self.token_is_lifetime(&*self.token) { - let lifetime = self.get_lifetime(&*self.token); + let ex = if Parser::token_is_lifetime(&self.token) { + let lifetime = self.get_lifetime(); self.bump(); ExprAgain(Some(lifetime.name)) } else { @@ -1842,18 +1835,18 @@ impl Parser { return self.parse_match_expr(); } else if self.eat_keyword(keywords::Unsafe) { return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided)); - } else if *self.token == token::LBRACKET { + } else if self.token == token::LBRACKET { self.bump(); let mutbl = MutImmutable; - if *self.token == token::RBRACKET { + if self.token == token::RBRACKET { // Empty vector. self.bump(); ex = ExprVec(~[], mutbl); } else { // Nonempty vector. let first_expr = self.parse_expr(); - if *self.token == token::COMMA && + if self.token == token::COMMA && self.look_ahead(1, |t| *t == token::DOTDOT) { // Repeating vector syntax: [ 0, ..512 ] self.bump(); @@ -1861,7 +1854,7 @@ impl Parser { let count = self.parse_expr(); self.expect(&token::RBRACKET); ex = ExprRepeat(first_expr, count, mutbl); - } else if *self.token == token::COMMA { + } else if self.token == token::COMMA { // Vector with two or more elements. self.bump(); let remaining_exprs = self.parse_seq_to_end( @@ -1885,36 +1878,36 @@ impl Parser { self.expect(&token::RPAREN); } else if self.eat_keyword(keywords::Return) { // RETURN expression - if can_begin_expr(&*self.token) { + if can_begin_expr(&self.token) { let e = self.parse_expr(); hi = e.span.hi; ex = ExprRet(Some(e)); } else { ex = ExprRet(None); } } else if self.eat_keyword(keywords::Break) { // BREAK expression - if self.token_is_lifetime(&*self.token) { - let lifetime = self.get_lifetime(&*self.token); + if Parser::token_is_lifetime(&self.token) { + let lifetime = self.get_lifetime(); self.bump(); ex = ExprBreak(Some(lifetime.name)); } else { ex = ExprBreak(None); } hi = self.span.hi; - } else if *self.token == token::MOD_SEP || - is_ident(&*self.token) && !self.is_keyword(keywords::True) && + } else if self.token == token::MOD_SEP || + is_ident(&self.token) && !self.is_keyword(keywords::True) && !self.is_keyword(keywords::False) { let pth = self.parse_path(LifetimeAndTypesWithColons).path; // `!`, as an operator, is prefix, so we know this isn't that - if *self.token == token::NOT { + if self.token == token::NOT { // MACRO INVOCATION expression self.bump(); - match *self.token { + match self.token { token::LPAREN | token::LBRACE => {} _ => self.fatal("expected open delimiter") }; - let ket = token::flip_delimiter(&*self.token); + let ket = token::flip_delimiter(&self.token); self.bump(); let tts = self.parse_seq_to_end(&ket, @@ -1923,7 +1916,7 @@ impl Parser { let hi = self.span.hi; return self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts, EMPTY_CTXT)); - } else if *self.token == token::LBRACE { + } else if self.token == token::LBRACE { // This might be a struct literal. if self.looking_at_struct_literal() { // It's a struct literal. @@ -1932,7 +1925,7 @@ impl Parser { let mut base = None; fields.push(self.parse_field()); - while *self.token != token::RBRACE { + while self.token != token::RBRACE { self.commit_expr(fields.last().expr, &[token::COMMA], &[token::RBRACE]); if self.eat(&token::DOTDOT) { @@ -1940,7 +1933,7 @@ impl Parser { break; } - if *self.token == token::RBRACE { + if self.token == token::RBRACE { // Accept an optional trailing comma. break; } @@ -1967,7 +1960,7 @@ impl Parser { } // parse a block or unsafe block - pub fn parse_block_expr(&self, lo: BytePos, blk_mode: BlockCheckMode) + pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode) -> @Expr { self.expect(&token::LBRACE); let blk = self.parse_block_tail(lo, blk_mode); @@ -1975,19 +1968,19 @@ impl Parser { } // parse a.b or a(13) or a[4] or just a - pub fn parse_dot_or_call_expr(&self) -> @Expr { + pub fn parse_dot_or_call_expr(&mut self) -> @Expr { let b = self.parse_bottom_expr(); self.parse_dot_or_call_expr_with(b) } - pub fn parse_dot_or_call_expr_with(&self, e0: @Expr) -> @Expr { + pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr { let mut e = e0; let lo = e.span.lo; let mut hi; loop { // expr.f if self.eat(&token::DOT) { - match *self.token { + match self.token { token::IDENT(i, _) => { hi = self.span.hi; self.bump(); @@ -1999,7 +1992,7 @@ impl Parser { }; // expr.f() method call - match *self.token { + match self.token { token::LPAREN => { let es = self.parse_unspanned_seq( &token::LPAREN, @@ -2013,7 +2006,8 @@ impl Parser { e = self.mk_expr(lo, hi, nd); } _ => { - e = self.mk_expr(lo, hi, self.mk_field(e, i, tys)); + let field = self.mk_field(e, i, tys); + e = self.mk_expr(lo, hi, field) } } } @@ -2022,7 +2016,7 @@ impl Parser { continue; } if self.expr_is_complete(e) { break; } - match *self.token { + match self.token { // expr(...) token::LPAREN => { let es = self.parse_unspanned_seq( @@ -2043,7 +2037,8 @@ impl Parser { let ix = self.parse_expr(); hi = ix.span.hi; self.commit_expr_expecting(ix, token::RBRACKET); - e = self.mk_expr(lo, hi, self.mk_index(e, ix)); + let index = self.mk_index(e, ix); + e = self.mk_expr(lo, hi, index) } _ => return e @@ -2054,11 +2049,11 @@ impl Parser { // parse an optional separator followed by a kleene-style // repetition token (+ or *). - pub fn parse_sep_and_zerok(&self) -> (Option, bool) { - fn parse_zerok(parser: &Parser) -> Option { - match *parser.token { + pub fn parse_sep_and_zerok(&mut self) -> (Option, bool) { + fn parse_zerok(parser: &mut Parser) -> Option { + match parser.token { token::BINOP(token::STAR) | token::BINOP(token::PLUS) => { - let zerok = *parser.token == token::BINOP(token::STAR); + let zerok = parser.token == token::BINOP(token::STAR); parser.bump(); Some(zerok) }, @@ -2079,7 +2074,7 @@ impl Parser { } // parse a single token tree from the input. - pub fn parse_token_tree(&self) -> token_tree { + pub fn parse_token_tree(&mut self) -> token_tree { // FIXME #6994: currently, this is too eager. It // parses token trees but also identifies tt_seq's // and tt_nonterminals; it's too early to know yet @@ -2092,22 +2087,27 @@ impl Parser { // not an EOF, and not the desired right-delimiter (if // it were, parse_seq_to_before_end would have prevented // reaching this point. - fn parse_non_delim_tt_tok(p: &Parser) -> token_tree { + fn parse_non_delim_tt_tok(p: &mut Parser) -> token_tree { maybe_whole!(deref p, nt_tt); - match *p.token { + match p.token { token::RPAREN | token::RBRACE | token::RBRACKET => { // This is a conservative error: only report the last unclosed delimiter. The // previous unclosed delimiters could actually be closed! The parser just hasn't // gotten to them yet. - p.open_braces.last_opt().map(|sp| p.span_note(*sp, "unclosed delimiter")); - p.fatal(format!("incorrect close delimiter: `{}`", p.this_token_to_str())); + match p.open_braces.last_opt() { + None => {} + Some(&sp) => p.span_note(sp, "unclosed delimiter"), + }; + let token_str = p.this_token_to_str(); + p.fatal(format!("incorrect close delimiter: `{}`", + token_str)) }, /* we ought to allow different depths of unquotation */ - token::DOLLAR if *p.quote_depth > 0u => { + token::DOLLAR if p.quote_depth > 0u => { p.bump(); - let sp = *p.span; + let sp = p.span; - if *p.token == token::LPAREN { + if p.token == token::LPAREN { let seq = p.parse_seq( &token::LPAREN, &token::RPAREN, @@ -2135,13 +2135,14 @@ impl Parser { } // turn the next token into a tt_tok: - fn parse_any_tt_tok(p: &Parser) -> token_tree{ - tt_tok(*p.span, p.bump_and_get()) + fn parse_any_tt_tok(p: &mut Parser) -> token_tree{ + tt_tok(p.span, p.bump_and_get()) } - match *self.token { + match self.token { token::EOF => { - for sp in self.open_braces.iter() { + let open_braces = self.open_braces.clone(); + for sp in open_braces.iter() { self.span_note(*sp, "Did you mean to close this delimiter?"); } // There shouldn't really be a span, but it's easier for the test runner @@ -2149,10 +2150,10 @@ impl Parser { self.fatal("This file contains an un-closed delimiter "); } token::LPAREN | token::LBRACE | token::LBRACKET => { - let close_delim = token::flip_delimiter(&*self.token); + let close_delim = token::flip_delimiter(&self.token); // Parse the open delimiter. - (*self.open_braces).push(*self.span); + self.open_braces.push(self.span); let mut result = ~[parse_any_tt_tok(self)]; let trees = @@ -2173,22 +2174,22 @@ impl Parser { // parse a stream of tokens into a list of token_trees, // up to EOF. - pub fn parse_all_token_trees(&self) -> ~[token_tree] { + pub fn parse_all_token_trees(&mut self) -> ~[token_tree] { let mut tts = ~[]; - while *self.token != token::EOF { + while self.token != token::EOF { tts.push(self.parse_token_tree()); } tts } - pub fn parse_matchers(&self) -> ~[matcher] { + pub fn parse_matchers(&mut self) -> ~[matcher] { // unification of matchers and token_trees would vastly improve // the interpolation of matchers maybe_whole!(self, nt_matchers); - let name_idx = @mut 0u; - match *self.token { + let name_idx = @Cell::new(0u); + match self.token { token::LBRACE | token::LPAREN | token::LBRACKET => { - let other_delimiter = token::flip_delimiter(self.token); + let other_delimiter = token::flip_delimiter(&self.token); self.bump(); self.parse_matcher_subseq_upto(name_idx, &other_delimiter) } @@ -2199,16 +2200,16 @@ impl Parser { // This goofy function is necessary to correctly match parens in matchers. // Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be // invalid. It's similar to common::parse_seq. - pub fn parse_matcher_subseq_upto(&self, - name_idx: @mut uint, + pub fn parse_matcher_subseq_upto(&mut self, + name_idx: @Cell, ket: &token::Token) -> ~[matcher] { let mut ret_val = ~[]; let mut lparens = 0u; - while *self.token != *ket || lparens > 0u { - if *self.token == token::LPAREN { lparens += 1u; } - if *self.token == token::RPAREN { lparens -= 1u; } + while self.token != *ket || lparens > 0u { + if self.token == token::LPAREN { lparens += 1u; } + if self.token == token::RPAREN { lparens -= 1u; } ret_val.push(self.parse_matcher(name_idx)); } @@ -2217,13 +2218,13 @@ impl Parser { return ret_val; } - pub fn parse_matcher(&self, name_idx: @mut uint) -> matcher { + pub fn parse_matcher(&mut self, name_idx: @Cell) -> matcher { let lo = self.span.lo; - let m = if *self.token == token::DOLLAR { + let m = if self.token == token::DOLLAR { self.bump(); - if *self.token == token::LPAREN { - let name_idx_lo = *name_idx; + if self.token == token::LPAREN { + let name_idx_lo = name_idx.get(); self.bump(); let ms = self.parse_matcher_subseq_upto(name_idx, &token::RPAREN); @@ -2231,13 +2232,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 { @@ -2248,12 +2249,12 @@ impl Parser { } // parse a prefix-operator expr - pub fn parse_prefix_expr(&self) -> @Expr { + pub fn parse_prefix_expr(&mut self) -> @Expr { let lo = self.span.lo; let hi; let ex; - match *self.token { + match self.token { token::NOT => { self.bump(); let e = self.parse_prefix_expr(); @@ -2347,19 +2348,20 @@ impl Parser { } // parse an expression of binops - pub fn parse_binops(&self) -> @Expr { - self.parse_more_binops(self.parse_prefix_expr(), 0) + pub fn parse_binops(&mut self) -> @Expr { + let prefix_expr = self.parse_prefix_expr(); + self.parse_more_binops(prefix_expr, 0) } // parse an expression of binops of at least min_prec precedence - pub fn parse_more_binops(&self, lhs: @Expr, min_prec: uint) -> @Expr { + pub fn parse_more_binops(&mut self, lhs: @Expr, min_prec: uint) -> @Expr { if self.expr_is_complete(lhs) { return lhs; } // Prevent dynamic borrow errors later on by limiting the // scope of the borrows. { - let token: &token::Token = self.token; - let restriction: &restriction = self.restriction; + let token: &token::Token = &self.token; + let restriction: &restriction = &self.restriction; match (token, restriction) { (&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs, (&token::BINOP(token::OR), @@ -2369,7 +2371,7 @@ impl Parser { } } - let cur_opt = token_to_binop(self.token); + let cur_opt = token_to_binop(&self.token); match cur_opt { Some(cur_op) => { let cur_prec = operator_prec(cur_op); @@ -2377,8 +2379,8 @@ impl Parser { self.bump(); let expr = self.parse_prefix_expr(); let rhs = self.parse_more_binops(expr, cur_prec); - let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, - self.mk_binary(cur_op, lhs, rhs)); + let binary = self.mk_binary(cur_op, lhs, rhs); + let bin = self.mk_expr(lhs.span.lo, rhs.span.hi, binary); self.parse_more_binops(bin, min_prec) } else { lhs @@ -2401,10 +2403,10 @@ impl Parser { // parse an assignment expression.... // actually, this seems to be the main entry point for // parsing an arbitrary expression. - pub fn parse_assign_expr(&self) -> @Expr { + pub fn parse_assign_expr(&mut self) -> @Expr { let lo = self.span.lo; let lhs = self.parse_binops(); - match *self.token { + match self.token { token::EQ => { self.bump(); let rhs = self.parse_expr(); @@ -2425,11 +2427,11 @@ impl Parser { token::SHL => BiShl, token::SHR => BiShr }; - self.mk_expr(lo, rhs.span.hi, - self.mk_assign_op(aop, lhs, rhs)) + let assign_op = self.mk_assign_op(aop, lhs, rhs); + self.mk_expr(lo, rhs.span.hi, assign_op) } token::DARROW => { - self.obsolete(*self.span, ObsoleteSwap); + self.obsolete(self.span, ObsoleteSwap); self.bump(); // Ignore what we get, this is an error anyway self.parse_expr(); @@ -2442,7 +2444,7 @@ impl Parser { } // parse an 'if' expression ('if' token already eaten) - pub fn parse_if_expr(&self) -> @Expr { + pub fn parse_if_expr(&mut self) -> @Expr { let lo = self.last_span.lo; let cond = self.parse_expr(); let thn = self.parse_block(); @@ -2457,12 +2459,12 @@ impl Parser { } // `|args| { ... }` or `{ ...}` like in `do` expressions - pub fn parse_lambda_block_expr(&self) -> @Expr { + pub fn parse_lambda_block_expr(&mut self) -> @Expr { self.parse_lambda_expr_( - || { - match *self.token { + |p| { + match p.token { token::BINOP(token::OR) | token::OROR => { - self.parse_fn_block_decl() + p.parse_fn_block_decl() } _ => { // No argument list - `do foo {` @@ -2471,7 +2473,7 @@ impl Parser { output: P(Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, - span: *self.span + span: p.span }), cf: return_val, variadic: false @@ -2479,28 +2481,28 @@ impl Parser { } } }, - || { - let blk = self.parse_block(); - self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)) + |p| { + let blk = p.parse_block(); + p.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)) }) } // `|args| expr` - pub fn parse_lambda_expr(&self) -> @Expr { - self.parse_lambda_expr_(|| self.parse_fn_block_decl(), - || self.parse_expr()) + pub fn parse_lambda_expr(&mut self) -> @Expr { + self.parse_lambda_expr_(|p| p.parse_fn_block_decl(), + |p| p.parse_expr()) } // parse something of the form |args| expr // this is used both in parsing a lambda expr // and in parsing a block expr as e.g. in for... - pub fn parse_lambda_expr_(&self, - parse_decl: || -> P, - parse_body: || -> @Expr) + pub fn parse_lambda_expr_(&mut self, + parse_decl: |&mut Parser| -> P, + parse_body: |&mut Parser| -> @Expr) -> @Expr { let lo = self.last_span.lo; - let decl = parse_decl(); - let body = parse_body(); + let decl = parse_decl(self); + let body = parse_body(self); let fakeblock = P(ast::Block { view_items: ~[], stmts: ~[], @@ -2510,11 +2512,10 @@ impl Parser { span: body.span, }); - return self.mk_expr(lo, body.span.hi, - ExprFnBlock(decl, fakeblock)); + return self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock)); } - pub fn parse_else_expr(&self) -> @Expr { + pub fn parse_else_expr(&mut self) -> @Expr { if self.eat_keyword(keywords::If) { return self.parse_if_expr(); } else { @@ -2524,7 +2525,7 @@ impl Parser { } // parse a 'for' .. 'in' expression ('for' token already eaten) - pub fn parse_for_expr(&self, opt_ident: Option) -> @Expr { + pub fn parse_for_expr(&mut self, opt_ident: Option) -> @Expr { // Parse: `for in ` let lo = self.last_span.lo; @@ -2541,7 +2542,7 @@ impl Parser { // parse a 'do'. // the 'do' expression parses as a call, but looks like // a function call followed by a closure expression. - pub fn parse_sugary_call_expr(&self, + pub fn parse_sugary_call_expr(&mut self, lo: BytePos, keyword: ~str, sugar: CallSugar, @@ -2570,33 +2571,31 @@ impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); let args = vec::append((*args).clone(), [last_arg]); - self.mk_expr(lo, block.span.hi, - self.mk_method_call(f, - i, - (*tps).clone(), - args, - sugar)) + let method_call = self.mk_method_call(f, + i, + (*tps).clone(), + args, + sugar); + self.mk_expr(lo, block.span.hi, method_call) } ExprField(f, i, ref tps) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - self.mk_expr(lo, block.span.hi, - self.mk_method_call(f, - i, - (*tps).clone(), - ~[last_arg], - sugar)) + let method_call = self.mk_method_call(f, + i, + (*tps).clone(), + ~[last_arg], + sugar); + self.mk_expr(lo, block.span.hi, method_call) } ExprPath(..) | ExprCall(..) | ExprMethodCall(..) | ExprParen(..) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - self.mk_expr( - lo, - last_arg.span.hi, - self.mk_call(e, ~[last_arg], sugar)) + let call = self.mk_call(e, ~[last_arg], sugar); + self.mk_expr(lo, last_arg.span.hi, call) } _ => { // There may be other types of expressions that can @@ -2610,7 +2609,7 @@ impl Parser { } } - pub fn parse_while_expr(&self) -> @Expr { + pub fn parse_while_expr(&mut self) -> @Expr { let lo = self.last_span.lo; let cond = self.parse_expr(); let body = self.parse_block(); @@ -2618,11 +2617,11 @@ impl Parser { return self.mk_expr(lo, hi, ExprWhile(cond, body)); } - pub fn parse_loop_expr(&self, opt_ident: Option) -> @Expr { + pub fn parse_loop_expr(&mut self, opt_ident: Option) -> @Expr { // loop headers look like 'loop {' or 'loop unsafe {' let is_loop_header = - *self.token == token::LBRACE - || (is_ident(&*self.token) + self.token == token::LBRACE + || (is_ident(&self.token) && self.look_ahead(1, |t| *t == token::LBRACE)); if is_loop_header { @@ -2634,14 +2633,14 @@ impl Parser { } else { // This is an obsolete 'continue' expression if opt_ident.is_some() { - self.span_err(*self.last_span, + self.span_err(self.last_span, "a label may not be used with a `loop` expression"); } - self.obsolete(*self.last_span, ObsoleteLoopAsContinue); + self.obsolete(self.last_span, ObsoleteLoopAsContinue); let lo = self.span.lo; - let ex = if self.token_is_lifetime(&*self.token) { - let lifetime = self.get_lifetime(&*self.token); + let ex = if Parser::token_is_lifetime(&self.token) { + let lifetime = self.get_lifetime(); self.bump(); ExprAgain(Some(lifetime.name)) } else { @@ -2653,18 +2652,18 @@ impl Parser { } // For distingishing between struct literals and blocks - fn looking_at_struct_literal(&self) -> bool { - *self.token == token::LBRACE && + fn looking_at_struct_literal(&mut self) -> bool { + self.token == token::LBRACE && (self.look_ahead(1, |t| token::is_plain_ident(t)) && self.look_ahead(2, |t| *t == token::COLON)) } - fn parse_match_expr(&self) -> @Expr { + fn parse_match_expr(&mut self) -> @Expr { let lo = self.last_span.lo; let discriminant = self.parse_expr(); self.commit_expr_expecting(discriminant, token::LBRACE); let mut arms: ~[Arm] = ~[]; - while *self.token != token::RBRACE { + while self.token != token::RBRACE { let pats = self.parse_pats(); let mut guard = None; if self.eat_keyword(keywords::If) { @@ -2675,7 +2674,7 @@ impl Parser { let require_comma = !classify::expr_is_simple_block(expr) - && *self.token != token::RBRACE; + && self.token != token::RBRACE; if require_comma { self.commit_expr(expr, &[token::COMMA], &[token::RBRACE]); @@ -2700,22 +2699,22 @@ impl Parser { } // parse an expression - pub fn parse_expr(&self) -> @Expr { + pub fn parse_expr(&mut self) -> @Expr { return self.parse_expr_res(UNRESTRICTED); } // parse an expression, subject to the given restriction - fn parse_expr_res(&self, r: restriction) -> @Expr { - let old = *self.restriction; - *self.restriction = r; + fn parse_expr_res(&mut self, r: restriction) -> @Expr { + let old = self.restriction; + self.restriction = r; let e = self.parse_assign_expr(); - *self.restriction = old; + self.restriction = old; return e; } // parse the RHS of a local variable declaration (e.g. '= 14;') - fn parse_initializer(&self) -> Option<@Expr> { - if *self.token == token::EQ { + fn parse_initializer(&mut self) -> Option<@Expr> { + if self.token == token::EQ { self.bump(); Some(self.parse_expr()) } else { @@ -2724,17 +2723,17 @@ impl Parser { } // parse patterns, separated by '|' s - fn parse_pats(&self) -> ~[@Pat] { + fn parse_pats(&mut self) -> ~[@Pat] { let mut pats = ~[]; loop { pats.push(self.parse_pat()); - if *self.token == token::BINOP(token::OR) { self.bump(); } + if self.token == token::BINOP(token::OR) { self.bump(); } else { return pats; } }; } fn parse_pat_vec_elements( - &self, + &mut self, ) -> (~[@Pat], Option<@Pat>, ~[@Pat]) { let mut before = ~[]; let mut slice = None; @@ -2742,13 +2741,13 @@ impl Parser { let mut first = true; let mut before_slice = true; - while *self.token != token::RBRACKET { + while self.token != token::RBRACKET { if first { first = false; } else { self.expect(&token::COMMA); } let mut is_slice = false; if before_slice { - if *self.token == token::DOTDOT { + if self.token == token::DOTDOT { self.bump(); is_slice = true; before_slice = false; @@ -2756,17 +2755,17 @@ impl Parser { } if is_slice { - if *self.token == token::COMMA || *self.token == token::RBRACKET { + if self.token == token::COMMA || self.token == token::RBRACKET { slice = Some(@ast::Pat { id: ast::DUMMY_NODE_ID, node: PatWildMulti, - span: *self.span, + span: self.span, }) } else { let subpat = self.parse_pat(); match subpat { @ast::Pat { id, node: PatWild, span } => { - self.obsolete(*self.span, ObsoleteVecDotDotWildcard); + self.obsolete(self.span, ObsoleteVecDotDotWildcard); slice = Some(@ast::Pat { id: id, node: PatWildMulti, @@ -2795,32 +2794,29 @@ impl Parser { } // parse the fields of a struct-like pattern - fn parse_pat_fields(&self) -> (~[ast::FieldPat], bool) { + fn parse_pat_fields(&mut self) -> (~[ast::FieldPat], bool) { let mut fields = ~[]; let mut etc = false; let mut first = true; - while *self.token != token::RBRACE { + while self.token != token::RBRACE { if first { first = false; } else { self.expect(&token::COMMA); // accept trailing commas - if *self.token == token::RBRACE { break } + if self.token == token::RBRACE { break } } - etc = *self.token == token::UNDERSCORE || *self.token == token::DOTDOT; - if *self.token == token::UNDERSCORE { - self.obsolete(*self.span, ObsoleteStructWildcard); + etc = self.token == token::UNDERSCORE || self.token == token::DOTDOT; + if self.token == token::UNDERSCORE { + self.obsolete(self.span, ObsoleteStructWildcard); } if etc { self.bump(); - if *self.token != token::RBRACE { - self.fatal( - format!( - "expected `\\}`, found `{}`", - self.this_token_to_str() - ) - ); + if self.token != token::RBRACE { + let token_str = self.this_token_to_str(); + self.fatal(format!("expected `\\}`, found `{}`", + token_str)) } etc = true; break; @@ -2840,11 +2836,12 @@ impl Parser { let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1), fieldname); let subpat; - if *self.token == token::COLON { + if self.token == token::COLON { match bind_type { - BindByRef(..) | BindByValue(MutMutable) => - self.fatal(format!("unexpected `{}`", - self.this_token_to_str())), + BindByRef(..) | BindByValue(MutMutable) => { + let token_str = self.this_token_to_str(); + self.fatal(format!("unexpected `{}`", token_str)) + } _ => {} } @@ -2854,7 +2851,7 @@ impl Parser { subpat = @ast::Pat { id: ast::DUMMY_NODE_ID, node: PatIdent(bind_type, fieldpath, None), - span: *self.last_span + span: self.last_span }; } fields.push(ast::FieldPat { ident: fieldname, pat: subpat }); @@ -2863,13 +2860,13 @@ impl Parser { } // parse a pattern. - pub fn parse_pat(&self) -> @Pat { + pub fn parse_pat(&mut self) -> @Pat { maybe_whole!(self, nt_pat); let lo = self.span.lo; let mut hi; let pat; - match *self.token { + match self.token { // parse _ token::UNDERSCORE => { self.bump(); @@ -2968,7 +2965,7 @@ impl Parser { token::LPAREN => { // parse (pat,pat,pat,...) as tuple self.bump(); - if *self.token == token::RPAREN { + if self.token == token::RPAREN { hi = self.span.hi; self.bump(); let lit = @codemap::Spanned { @@ -2979,7 +2976,7 @@ impl Parser { } else { let mut fields = ~[self.parse_pat()]; if self.look_ahead(1, |t| *t != token::RPAREN) { - while *self.token == token::COMMA { + while self.token == token::COMMA { self.bump(); fields.push(self.parse_pat()); } @@ -3013,8 +3010,7 @@ impl Parser { _ => {} } - let tok = self.token; - if !is_ident_or_path(tok) + if !is_ident_or_path(&self.token) || self.is_keyword(keywords::True) || self.is_keyword(keywords::False) { // Parse an expression pattern or exp .. exp. @@ -3023,7 +3019,7 @@ impl Parser { // preceded by unary-minus) or identifiers. let val = self.parse_literal_maybe_minus(); if self.eat(&token::DOTDOT) { - let end = if is_ident_or_path(tok) { + let end = if is_ident_or_path(&self.token) { let path = self.parse_path(LifetimeAndTypesWithColons) .path; let hi = self.span.hi; @@ -3055,7 +3051,7 @@ impl Parser { self.eat(&token::DOTDOT); let end = self.parse_expr_res(RESTRICT_NO_BAR_OP); pat = PatRange(start, end); - } else if is_plain_ident(&*self.token) && !can_be_enum_or_struct { + } else if is_plain_ident(&self.token) && !can_be_enum_or_struct { let name = self.parse_path(NoTypesAllowed).path; let sub; if self.eat(&token::AT) { @@ -3070,7 +3066,7 @@ impl Parser { // parse an enum pat let enum_path = self.parse_path(LifetimeAndTypesWithColons) .path; - match *self.token { + match self.token { token::LBRACE => { self.bump(); let (fields, etc) = @@ -3080,7 +3076,7 @@ impl Parser { } _ => { let mut args: ~[@Pat] = ~[]; - match *self.token { + match self.token { token::LPAREN => { let is_star = self.look_ahead(1, |t| { match *t { @@ -3098,7 +3094,7 @@ impl Parser { // This is a "top constructor only" pat self.bump(); if is_star { - self.obsolete(*self.span, ObsoleteEnumWildcard); + self.obsolete(self.span, ObsoleteEnumWildcard); } self.bump(); self.expect(&token::RPAREN); @@ -3141,11 +3137,11 @@ impl Parser { // parse ident or ident @ pat // used by the copy foo and ref foo patterns to give a good // error message when parsing mistakes like ref foo(a,b) - fn parse_pat_ident(&self, + fn parse_pat_ident(&mut self, binding_mode: ast::BindingMode) -> ast::Pat_ { - if !is_plain_ident(&*self.token) { - self.span_fatal(*self.last_span, + if !is_plain_ident(&self.token) { + self.span_fatal(self.last_span, "expected identifier, found path"); } // why a path here, and not just an identifier? @@ -3162,9 +3158,9 @@ impl Parser { // leads to a parse error. Note that if there is no explicit // binding mode then we do not end up here, because the lookahead // will direct us over to parse_enum_variant() - if *self.token == token::LPAREN { + if self.token == token::LPAREN { self.span_fatal( - *self.last_span, + self.last_span, "expected identifier, found enum pattern"); } @@ -3172,7 +3168,7 @@ impl Parser { } // parse a local variable declaration - fn parse_local(&self) -> @Local { + fn parse_local(&mut self) -> @Local { let lo = self.span.lo; let pat = self.parse_pat(); @@ -3193,22 +3189,22 @@ impl Parser { } // parse a "let" stmt - fn parse_let(&self) -> @Decl { + fn parse_let(&mut self) -> @Decl { let lo = self.span.lo; let local = self.parse_local(); while self.eat(&token::COMMA) { let _ = self.parse_local(); - self.obsolete(*self.span, ObsoleteMultipleLocalDecl); + self.obsolete(self.span, ObsoleteMultipleLocalDecl); } return @spanned(lo, self.last_span.hi, DeclLocal(local)); } // parse a structure field - fn parse_name_and_ty(&self, + fn parse_name_and_ty(&mut self, pr: visibility, attrs: ~[Attribute]) -> struct_field { let lo = self.span.lo; - if !is_plain_ident(&*self.token) { + if !is_plain_ident(&self.token) { self.fatal("expected ident"); } let name = self.parse_ident(); @@ -3224,13 +3220,13 @@ impl Parser { // parse a statement. may include decl. // precondition: any attributes are parsed already - pub fn parse_stmt(&self, item_attrs: ~[Attribute]) -> @Stmt { + pub fn parse_stmt(&mut self, item_attrs: ~[Attribute]) -> @Stmt { maybe_whole!(self, nt_stmt); - fn check_expected_item(p: &Parser, found_attrs: bool) { + fn check_expected_item(p: &mut Parser, found_attrs: bool) { // If we have attributes then we should have an item if found_attrs { - p.span_err(*p.last_span, "expected item after attributes"); + p.span_err(p.last_span, "expected item after attributes"); } } @@ -3240,8 +3236,8 @@ impl Parser { self.expect_keyword(keywords::Let); let decl = self.parse_let(); return @spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)); - } else if is_ident(&*self.token) - && !token::is_any_keyword(self.token) + } else if is_ident(&self.token) + && !token::is_any_keyword(&self.token) && self.look_ahead(1, |t| *t == token::NOT) { // parse a macro invocation. Looks like there's serious // overlap here; if this clause doesn't catch it (and it @@ -3263,7 +3259,7 @@ impl Parser { let pth = self.parse_path(NoTypesAllowed).path; self.bump(); - let id = if *self.token == token::LPAREN { + let id = if self.token == token::LPAREN { token::special_idents::invalid // no special identifier } else { self.parse_ident() @@ -3318,18 +3314,18 @@ impl Parser { } // is this expression a successfully-parsed statement? - fn expr_is_complete(&self, e: @Expr) -> bool { - return *self.restriction == RESTRICT_STMT_EXPR && + fn expr_is_complete(&mut self, e: @Expr) -> bool { + return self.restriction == RESTRICT_STMT_EXPR && !classify::expr_requires_semi_to_be_stmt(e); } // parse a block. No inner attrs are allowed. - pub fn parse_block(&self) -> P { + pub fn parse_block(&mut self) -> P { maybe_whole!(no_clone self, nt_block); let lo = self.span.lo; if self.eat_keyword(keywords::Unsafe) { - self.obsolete(*self.span, ObsoleteUnsafeBlock); + self.obsolete(self.span, ObsoleteUnsafeBlock); } self.expect(&token::LBRACE); @@ -3337,14 +3333,14 @@ impl Parser { } // parse a block. Inner attrs are allowed. - fn parse_inner_attrs_and_block(&self) + fn parse_inner_attrs_and_block(&mut self) -> (~[Attribute], P) { maybe_whole!(pair_empty self, nt_block); let lo = self.span.lo; if self.eat_keyword(keywords::Unsafe) { - self.obsolete(*self.span, ObsoleteUnsafeBlock); + self.obsolete(self.span, ObsoleteUnsafeBlock); } self.expect(&token::LBRACE); let (inner, next) = self.parse_inner_attrs_and_next(); @@ -3356,12 +3352,12 @@ impl Parser { // I guess that also means "already parsed the 'impure'" if // necessary, and this should take a qualifier. // some blocks start with "#{"... - fn parse_block_tail(&self, lo: BytePos, s: BlockCheckMode) -> P { + fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P { self.parse_block_tail_(lo, s, ~[]) } // parse the rest of a block expression or function body - fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode, + fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode, first_item_attrs: ~[Attribute]) -> P { let mut stmts = ~[]; let mut expr = None; @@ -3383,14 +3379,14 @@ impl Parser { let mut attributes_box = attrs_remaining; - while (*self.token != token::RBRACE) { + while (self.token != token::RBRACE) { // parsing items even when they're not allowed lets us give // better error messages and recover more gracefully. attributes_box.push_all(self.parse_outer_attributes()); - match *self.token { + match self.token { token::SEMI => { if !attributes_box.is_empty() { - self.span_err(*self.last_span, "expected item after attributes"); + self.span_err(self.last_span, "expected item after attributes"); attributes_box = ~[]; } self.bump(); // empty @@ -3409,7 +3405,7 @@ impl Parser { self.commit_stmt(stmt, &[], &[token::SEMI, token::RBRACE]); } - match *self.token { + match self.token { token::SEMI => { self.bump(); stmts.push(@codemap::Spanned { @@ -3428,7 +3424,7 @@ impl Parser { StmtMac(ref m, _) => { // statement macro; might be an expr let has_semi; - match *self.token { + match self.token { token::SEMI => { has_semi = true; } @@ -3468,7 +3464,7 @@ impl Parser { } if !attributes_box.is_empty() { - self.span_err(*self.last_span, "expected item after attributes"); + self.span_err(self.last_span, "expected item after attributes"); } let hi = self.span.hi; @@ -3490,19 +3486,19 @@ impl Parser { // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:") // Returns "Some(stuff)" otherwise (e.g. "T:stuff"). // NB: The None/Some distinction is important for issue #7264. - fn parse_optional_ty_param_bounds(&self) -> Option> { + fn parse_optional_ty_param_bounds(&mut self) -> Option> { if !self.eat(&token::COLON) { return None; } let mut result = opt_vec::Empty; loop { - match *self.token { + match self.token { token::LIFETIME(lifetime) => { if "static" == self.id_to_str(lifetime) { result.push(RegionTyParamBound); } else { - self.span_err(*self.span, + self.span_err(self.span, "`'static` is the only permissible region bound here"); } self.bump(); @@ -3523,7 +3519,7 @@ impl Parser { } // matches typaram = IDENT optbounds - fn parse_ty_param(&self) -> TyParam { + fn parse_ty_param(&mut self) -> TyParam { let ident = self.parse_ident(); let opt_bounds = self.parse_optional_ty_param_bounds(); // For typarams we don't care about the difference b/w "" and "". @@ -3535,7 +3531,7 @@ impl Parser { // matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > ) // | ( < lifetimes , typaramseq ( , )? > ) // where typaramseq = ( typaram ) | ( typaram , typaramseq ) - pub fn parse_generics(&self) -> ast::Generics { + pub fn parse_generics(&mut self) -> ast::Generics { if self.eat(&token::LT) { let lifetimes = self.parse_lifetimes(); let ty_params = self.parse_seq_to_gt( @@ -3547,7 +3543,7 @@ impl Parser { } } - fn parse_generic_values_after_lt(&self) -> (OptVec, ~[P]) { + fn parse_generic_values_after_lt(&mut self) -> (OptVec, ~[P]) { let lifetimes = self.parse_lifetimes(); let result = self.parse_seq_to_gt( Some(token::COMMA), @@ -3555,23 +3551,24 @@ impl Parser { (lifetimes, opt_vec::take_vec(result)) } - fn parse_fn_args(&self, named_args: bool, allow_variadic: bool) -> (~[arg], bool) { - let sp = *self.span; + fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) + -> (~[arg], bool) { + let sp = self.span; let mut args: ~[Option] = self.parse_unspanned_seq( &token::LPAREN, &token::RPAREN, seq_sep_trailing_disallowed(token::COMMA), |p| { - if *p.token == token::DOTDOTDOT { + if p.token == token::DOTDOTDOT { p.bump(); if allow_variadic { - if *p.token != token::RPAREN { - p.span_fatal(*p.span, + if p.token != token::RPAREN { + p.span_fatal(p.span, "`...` must be last in argument list for variadic function"); } } else { - p.span_fatal(*p.span, + p.span_fatal(p.span, "only foreign functions are allowed to be variadic"); } None @@ -3602,7 +3599,7 @@ impl Parser { } // parse the argument list and result type of a function declaration - pub fn parse_fn_decl(&self, allow_variadic: bool) -> P { + pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P { let (args, variadic) = self.parse_fn_args(true, allow_variadic); let (ret_style, ret_ty) = self.parse_ret_ty(); @@ -3615,32 +3612,28 @@ impl Parser { }) } - fn is_self_ident(&self) -> bool { - match *self.token { + fn is_self_ident(&mut self) -> bool { + match self.token { token::IDENT(id, false) => id.name == special_idents::self_.name, _ => false } } - fn expect_self_ident(&self) { + fn expect_self_ident(&mut self) { if !self.is_self_ident() { - self.fatal( - format!( - "expected `self` but found `{}`", - self.this_token_to_str() - ) - ); + let token_str = self.this_token_to_str(); + self.fatal(format!("expected `self` but found `{}`", token_str)) } self.bump(); } // parse the argument list and result type of a function // that may have a self type. - fn parse_fn_decl_with_self(&self, parse_arg_fn: |&Parser| -> arg) + fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> arg) -> (explicit_self, P) { fn maybe_parse_explicit_self(cnstr: |v: Mutability| -> ast::explicit_self_, - p: &Parser) + p: &mut Parser) -> ast::explicit_self_ { // We need to make sure it isn't a type if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) || @@ -3657,10 +3650,11 @@ impl Parser { } } - fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ { + fn maybe_parse_borrowed_explicit_self(this: &mut Parser) + -> ast::explicit_self_ { // The following things are possible to see here: // - // fn(&self) + // fn(&mut self) // fn(&mut self) // fn(&'lt self) // fn(&'lt mut self) @@ -3671,7 +3665,7 @@ impl Parser { this.bump(); this.expect_self_ident(); sty_region(None, MutImmutable) - } else if this.look_ahead(1, |t| this.token_is_mutability(t)) && + } else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) && this.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) { @@ -3679,7 +3673,7 @@ impl Parser { let mutability = this.parse_mutability(); this.expect_self_ident(); sty_region(None, mutability) - } else if this.look_ahead(1, |t| this.token_is_lifetime(t)) && + } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) && this.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) { @@ -3687,8 +3681,10 @@ impl Parser { let lifetime = this.parse_lifetime(); this.expect_self_ident(); sty_region(Some(lifetime), MutImmutable) - } else if this.look_ahead(1, |t| this.token_is_lifetime(t)) && - this.look_ahead(2, |t| this.token_is_mutability(t)) && + } else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) && + this.look_ahead(2, |t| { + Parser::token_is_mutability(t) + }) && this.look_ahead(3, |t| token::is_keyword(keywords::Self, t)) { this.bump(); @@ -3706,7 +3702,7 @@ impl Parser { // A bit of complexity and lookahead is needed here in order to be // backwards compatible. let lo = self.span.lo; - let explicit_self = match *self.token { + let explicit_self = match self.token { token::BINOP(token::AND) => { maybe_parse_borrowed_explicit_self(self) } @@ -3716,7 +3712,7 @@ impl Parser { token::TILDE => { maybe_parse_explicit_self(|mutability| { if mutability != MutImmutable { - self.span_err(*self.last_span, + self.span_err(self.last_span, "mutability declaration not allowed here"); } sty_uniq(MutImmutable) @@ -3730,22 +3726,22 @@ impl Parser { // Possibly "*self" or "*mut self" -- not supported. Try to avoid // emitting cryptic "unexpected token" errors. self.bump(); - let mutability = if self.token_is_mutability(self.token) { + let mutability = if Parser::token_is_mutability(&self.token) { self.parse_mutability() } else { MutImmutable }; if self.is_self_ident() { - self.span_err(*self.span, "cannot pass self by unsafe pointer"); + self.span_err(self.span, "cannot pass self by unsafe pointer"); self.bump(); } sty_value(mutability) } - _ if self.token_is_mutability(self.token) && + _ if Parser::token_is_mutability(&self.token) && self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => { let mutability = self.parse_mutability(); self.expect_self_ident(); sty_value(mutability) } - _ if self.token_is_mutability(self.token) && + _ if Parser::token_is_mutability(&self.token) && self.look_ahead(1, |t| *t == token::TILDE) && self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => { let mutability = self.parse_mutability(); @@ -3761,7 +3757,7 @@ impl Parser { // If we parsed a self type, expect a comma before the argument list. let fn_inputs; if explicit_self != sty_static { - match *self.token { + match self.token { token::COMMA => { self.bump(); let sep = seq_sep_trailing_disallowed(token::COMMA); @@ -3775,21 +3771,16 @@ impl Parser { fn_inputs = ~[]; } _ => { - self.fatal( - format!( - "expected `,` or `)`, found `{}`", - self.this_token_to_str() - ) - ); + let token_str = self.this_token_to_str(); + self.fatal(format!("expected `,` or `)`, found `{}`", + token_str)) } } } else { let sep = seq_sep_trailing_disallowed(token::COMMA); - fn_inputs = self.parse_seq_to_before_end( - &token::RPAREN, - sep, - parse_arg_fn - ); + fn_inputs = self.parse_seq_to_before_end(&token::RPAREN, + sep, + parse_arg_fn); } self.expect(&token::RPAREN); @@ -3809,7 +3800,7 @@ impl Parser { } // parse the |arg, arg| header on a lambda - fn parse_fn_block_decl(&self) -> P { + fn parse_fn_block_decl(&mut self) -> P { let inputs_captures = { if self.eat(&token::OROR) { ~[] @@ -3825,7 +3816,11 @@ impl Parser { let output = if self.eat(&token::RARROW) { self.parse_ty(false) } else { - P(Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span }) + P(Ty { + id: ast::DUMMY_NODE_ID, + node: ty_infer, + span: self.span, + }) }; P(ast::fn_decl { @@ -3837,7 +3832,7 @@ impl Parser { } // Parses the `(arg, arg) -> return_type` header on a procedure. - fn parse_proc_decl(&self) -> P { + fn parse_proc_decl(&mut self) -> P { let inputs = self.parse_unspanned_seq(&token::LPAREN, &token::RPAREN, @@ -3850,7 +3845,7 @@ impl Parser { P(Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, - span: *self.span, + span: self.span, }) }; @@ -3863,13 +3858,13 @@ impl Parser { } // parse the name and optional generic types of a function header. - fn parse_fn_header(&self) -> (Ident, ast::Generics) { + fn parse_fn_header(&mut self) -> (Ident, ast::Generics) { let id = self.parse_ident(); let generics = self.parse_generics(); (id, generics) } - fn mk_item(&self, lo: BytePos, hi: BytePos, ident: Ident, + fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident, node: item_, vis: visibility, attrs: ~[Attribute]) -> @item { @ast::item { ident: ident, @@ -3881,7 +3876,7 @@ impl Parser { } // parse an item-position function declaration. - fn parse_item_fn(&self, purity: purity, abis: AbiSet) -> item_info { + fn parse_item_fn(&mut self, purity: purity, abis: AbiSet) -> item_info { let (ident, generics) = self.parse_fn_header(); let decl = self.parse_fn_decl(false); let (inner_attrs, body) = self.parse_inner_attrs_and_block(); @@ -3891,7 +3886,7 @@ impl Parser { } // parse a method in a trait impl, starting with `attrs` attributes. - fn parse_method(&self, already_parsed_attrs: Option<~[Attribute]>) -> @method { + fn parse_method(&mut self, already_parsed_attrs: Option<~[Attribute]>) -> @method { let next_attrs = self.parse_outer_attributes(); let attrs = match already_parsed_attrs { Some(mut a) => { a.push_all_move(next_attrs); a } @@ -3927,13 +3922,13 @@ impl Parser { } // parse trait Foo { ... } - fn parse_item_trait(&self) -> item_info { + fn parse_item_trait(&mut self) -> item_info { let ident = self.parse_ident(); let tps = self.parse_generics(); // Parse traits, if necessary. let traits; - if *self.token == token::COLON { + if self.token == token::COLON { self.bump(); traits = self.parse_trait_ref_list(&token::LBRACE); } else { @@ -3947,7 +3942,7 @@ impl Parser { // Parses two variants (with the region/type params always optional): // impl Foo { ... } // impl ToStr for ~[T] { ... } - fn parse_item_impl(&self) -> item_info { + fn parse_item_impl(&mut self) -> item_info { // First, parse type parameters if necessary. let generics = self.parse_generics(); @@ -3957,7 +3952,7 @@ impl Parser { // Special case: if the next identifier that follows is '(', don't // allow this to be parsed as a trait. - let could_be_trait = *self.token != token::LPAREN; + let could_be_trait = self.token != token::LPAREN; // Parse the trait. let mut ty = self.parse_ty(false); @@ -3991,7 +3986,7 @@ impl Parser { let mut meths = ~[]; let inner_attrs = if self.eat(&token::SEMI) { - self.obsolete(*self.last_span, ObsoleteEmptyImpl); + self.obsolete(self.last_span, ObsoleteEmptyImpl); None } else { self.expect(&token::LBRACE); @@ -4008,7 +4003,7 @@ impl Parser { } // parse a::B<~str,int> - fn parse_trait_ref(&self) -> trait_ref { + fn parse_trait_ref(&mut self) -> trait_ref { ast::trait_ref { path: self.parse_path(LifetimeAndTypesWithoutColons).path, ref_id: ast::DUMMY_NODE_ID, @@ -4016,7 +4011,7 @@ impl Parser { } // parse B + C<~str,int> + D - fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] { + fn parse_trait_ref_list(&mut self, ket: &token::Token) -> ~[trait_ref] { self.parse_seq_to_before_end( ket, seq_sep_trailing_disallowed(token::BINOP(token::PLUS)), @@ -4025,7 +4020,7 @@ impl Parser { } // parse struct Foo { ... } - fn parse_item_struct(&self) -> item_info { + fn parse_item_struct(&mut self) -> item_info { let class_name = self.parse_ident(); let generics = self.parse_generics(); @@ -4036,7 +4031,7 @@ impl Parser { // It's a record-like struct. is_tuple_like = false; fields = ~[]; - while *self.token != token::RBRACE { + while self.token != token::RBRACE { fields.push(self.parse_struct_decl_field()); } if fields.len() == 0 { @@ -4044,7 +4039,7 @@ impl Parser { get_ident_interner().get(class_name.name))); } self.bump(); - } else if *self.token == token::LPAREN { + } else if self.token == token::LPAREN { // It's a tuple-like struct. is_tuple_like = true; fields = self.parse_unspanned_seq( @@ -4052,7 +4047,7 @@ impl Parser { &token::RPAREN, seq_sep_trailing_allowed(token::COMMA), |p| { - let attrs = self.parse_outer_attributes(); + let attrs = p.parse_outer_attributes(); let lo = p.span.lo; let struct_field_ = ast::struct_field_ { kind: unnamed_field, @@ -4068,13 +4063,10 @@ impl Parser { is_tuple_like = true; fields = ~[]; } else { - self.fatal( - format!( - "expected `\\{`, `(`, or `;` after struct name \ - but found `{}`", - self.this_token_to_str() - ) - ); + let token_str = self.this_token_to_str(); + self.fatal(format!("expected `\\{`, `(`, or `;` after struct \ + name but found `{}`", + token_str)) } let _ = ast::DUMMY_NODE_ID; // XXX: Workaround for crazy bug. @@ -4088,27 +4080,28 @@ impl Parser { } // parse a structure field declaration - pub fn parse_single_struct_field(&self, + pub fn parse_single_struct_field(&mut self, vis: visibility, attrs: ~[Attribute]) -> struct_field { let a_var = self.parse_name_and_ty(vis, attrs); - match *self.token { + match self.token { token::COMMA => { self.bump(); } token::RBRACE => {} _ => { - self.span_fatal(*self.span, + let token_str = self.this_token_to_str(); + self.span_fatal(self.span, format!("expected `,`, or `\\}` but found `{}`", - self.this_token_to_str())); + token_str)) } } a_var } // parse an element of a struct definition - fn parse_struct_decl_field(&self) -> struct_field { + fn parse_struct_decl_field(&mut self) -> struct_field { let attrs = self.parse_outer_attributes(); @@ -4124,7 +4117,7 @@ impl Parser { } // parse visiility: PUB, PRIV, or nothing - fn parse_visibility(&self) -> visibility { + fn parse_visibility(&mut self) -> visibility { if self.eat_keyword(keywords::Pub) { public } else if self.eat_keyword(keywords::Priv) { private } else { inherited } @@ -4132,7 +4125,7 @@ impl Parser { // given a termination token and a vector of already-parsed // attributes (of length 0 or 1), parse all of the items in a module - fn parse_mod_items(&self, + fn parse_mod_items(&mut self, term: token::Token, first_item_attrs: ~[Attribute]) -> _mod { @@ -4150,7 +4143,7 @@ impl Parser { // don't think this other loop is even necessary.... let mut first = true; - while *self.token != term { + while self.token != term { let mut attrs = self.parse_outer_attributes(); if first { attrs = attrs_remaining + attrs; @@ -4167,21 +4160,22 @@ impl Parser { the module"); } _ => { - self.fatal(format!("expected item but found `{}`", - self.this_token_to_str())); + let token_str = self.this_token_to_str(); + self.fatal(format!("expected item but found `{}`", + token_str)) } } } if first && attrs_remaining_len > 0u { // We parsed attributes for the first item but didn't find it - self.span_err(*self.last_span, "expected item after attributes"); + self.span_err(self.last_span, "expected item after attributes"); } ast::_mod { view_items: view_items, items: items } } - fn parse_item_const(&self) -> item_info { + fn parse_item_const(&mut self) -> item_info { let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable}; let id = self.parse_ident(); self.expect(&token::COLON); @@ -4193,10 +4187,10 @@ impl Parser { } // parse a `mod { ... }` or `mod ;` item - fn parse_item_mod(&self, outer_attrs: &[Attribute]) -> item_info { - let id_span = *self.span; + fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> item_info { + let id_span = self.span; let id = self.parse_ident(); - if *self.token == token::SEMI { + if self.token == token::SEMI { self.bump(); // This mod is in an external file. Let's go get it! let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span); @@ -4212,7 +4206,7 @@ impl Parser { } } - fn push_mod_path(&self, id: Ident, attrs: &[Attribute]) { + fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) { let default_path = token::interner_get(id.name); let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") { @@ -4222,20 +4216,19 @@ impl Parser { self.mod_path_stack.push(file_path) } - fn pop_mod_path(&self) { + fn pop_mod_path(&mut self) { self.mod_path_stack.pop(); } // read a module from a source file. - fn eval_src_mod(&self, + fn eval_src_mod(&mut self, id: ast::Ident, outer_attrs: &[ast::Attribute], id_sp: Span) -> (ast::item_, ~[ast::Attribute]) { - let mut prefix = Path::new(self.sess.cm.span_to_filename(*self.span)); + let mut prefix = Path::new(self.sess.cm.span_to_filename(self.span)); prefix.pop(); - let mod_path_stack = &*self.mod_path_stack; - let mod_path = Path::new(".").join_many(*mod_path_stack); + let mod_path = Path::new(".").join_many(self.mod_path_stack); let dir_path = prefix.join(&mod_path); let file_path = match ::attr::first_attr_value_str_by_name( outer_attrs, "path") { @@ -4268,27 +4261,34 @@ impl Parser { id_sp) } - fn eval_src_mod_from_path(&self, + fn eval_src_mod_from_path(&mut self, 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 p0 = + let mut p0 = new_sub_parser_from_file(self.sess, self.cfg.clone(), &path, @@ -4297,19 +4297,24 @@ 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); } // parse a function declaration from a foreign module - fn parse_item_foreign_fn(&self, vis: ast::visibility, + fn parse_item_foreign_fn(&mut self, vis: ast::visibility, attrs: ~[Attribute]) -> @foreign_item { let lo = self.span.lo; // Parse obsolete purity. let purity = self.parse_fn_purity(); if purity != impure_fn { - self.obsolete(*self.last_span, ObsoleteUnsafeExternFn); + self.obsolete(self.last_span, ObsoleteUnsafeExternFn); } let (ident, generics) = self.parse_fn_header(); @@ -4325,7 +4330,7 @@ impl Parser { } // parse a static item from a foreign module - fn parse_item_foreign_static(&self, vis: ast::visibility, + fn parse_item_foreign_static(&mut self, vis: ast::visibility, attrs: ~[Attribute]) -> @foreign_item { let lo = self.span.lo; @@ -4346,7 +4351,7 @@ impl Parser { } // parse safe/unsafe and fn - fn parse_fn_purity(&self) -> purity { + fn parse_fn_purity(&mut self) -> purity { if self.eat_keyword(keywords::Fn) { impure_fn } else if self.eat_keyword(keywords::Unsafe) { self.expect_keyword(keywords::Fn); @@ -4358,7 +4363,7 @@ impl Parser { // at this point, this is essentially a wrapper for // parse_foreign_items. - fn parse_foreign_mod_items(&self, + fn parse_foreign_mod_items(&mut self, abis: AbiSet, first_item_attrs: ~[Attribute]) -> foreign_mod { @@ -4369,10 +4374,10 @@ impl Parser { foreign_items: foreign_items } = self.parse_foreign_items(first_item_attrs, true); if (! attrs_remaining.is_empty()) { - self.span_err(*self.last_span, + self.span_err(self.last_span, "expected item after attributes"); } - assert!(*self.token == token::RBRACE); + assert!(self.token == token::RBRACE); ast::foreign_mod { abis: abis, view_items: view_items, @@ -4381,7 +4386,7 @@ impl Parser { } // parse extern foo; or extern mod foo { ... } or extern { ... } - fn parse_item_foreign_mod(&self, + fn parse_item_foreign_mod(&mut self, lo: BytePos, opt_abis: Option, visibility: visibility, @@ -4392,16 +4397,17 @@ impl Parser { if self.is_keyword(keywords::Mod) { must_be_named_mod = true; self.expect_keyword(keywords::Mod); - } else if *self.token != token::LBRACE { - self.span_fatal(*self.span, + } else if self.token != token::LBRACE { + let token_str = self.this_token_to_str(); + self.span_fatal(self.span, format!("expected `\\{` or `mod` but found `{}`", - self.this_token_to_str())); + token_str)) } - let (named, maybe_path, ident) = match *self.token { + let (named, maybe_path, ident) = match self.token { token::IDENT(..) => { let the_ident = self.parse_ident(); - let path = if *self.token == token::EQ { + let path = if self.token == token::EQ { self.bump(); Some(self.parse_str()) } @@ -4410,10 +4416,11 @@ impl Parser { } _ => { if must_be_named_mod { - self.span_fatal(*self.span, + let token_str = self.this_token_to_str(); + self.span_fatal(self.span, format!("expected foreign module name but \ - found `{}`", - self.this_token_to_str())); + found `{}`", + token_str)) } (false, None, @@ -4425,7 +4432,7 @@ impl Parser { if items_allowed && self.eat(&token::LBRACE) { // `extern mod foo { ... }` is obsolete. if named { - self.obsolete(*self.last_span, ObsoleteNamedExternModule); + self.obsolete(self.last_span, ObsoleteNamedExternModule); } let abis = opt_abis.unwrap_or(AbiSet::C()); @@ -4434,16 +4441,17 @@ impl Parser { let m = self.parse_foreign_mod_items(abis, next); self.expect(&token::RBRACE); - return iovi_item(self.mk_item(lo, - self.last_span.hi, - ident, - item_foreign_mod(m), - visibility, - maybe_append(attrs, Some(inner)))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_foreign_mod(m), + visibility, + maybe_append(attrs, Some(inner))); + return iovi_item(item); } if opt_abis.is_some() { - self.span_err(*self.span, "an ABI may not be specified here"); + self.span_err(self.span, "an ABI may not be specified here"); } // extern mod foo; @@ -4458,7 +4466,7 @@ impl Parser { } // parse type Foo = Bar; - fn parse_item_type(&self) -> item_info { + fn parse_item_type(&mut self) -> item_info { let ident = self.parse_ident(); let tps = self.parse_generics(); self.expect(&token::EQ); @@ -4469,9 +4477,9 @@ impl Parser { // parse a structure-like enum variant definition // this should probably be renamed or refactored... - fn parse_struct_def(&self) -> @struct_def { + fn parse_struct_def(&mut self) -> @struct_def { let mut fields: ~[struct_field] = ~[]; - while *self.token != token::RBRACE { + while self.token != token::RBRACE { fields.push(self.parse_struct_decl_field()); } self.bump(); @@ -4483,11 +4491,11 @@ impl Parser { } // parse the part of an "enum" decl following the '{' - fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def { + fn parse_enum_def(&mut self, _generics: &ast::Generics) -> enum_def { let mut variants = ~[]; let mut all_nullary = true; let mut have_disr = false; - while *self.token != token::RBRACE { + while self.token != token::RBRACE { let variant_attrs = self.parse_outer_attributes(); let vlo = self.span.lo; @@ -4502,7 +4510,7 @@ impl Parser { // Parse a struct variant. all_nullary = false; kind = struct_variant_kind(self.parse_struct_def()); - } else if *self.token == token::LPAREN { + } else if self.token == token::LPAREN { all_nullary = false; let arg_tys = self.parse_unspanned_seq( &token::LPAREN, @@ -4547,7 +4555,7 @@ impl Parser { } // parse an "enum" declaration - fn parse_item_enum(&self) -> item_info { + fn parse_item_enum(&mut self) -> item_info { let id = self.parse_ident(); let generics = self.parse_generics(); self.expect(&token::LBRACE); @@ -4556,7 +4564,7 @@ impl Parser { (id, item_enum(enum_definition, generics), None) } - fn fn_expr_lookahead(&self, tok: &token::Token) -> bool { + fn fn_expr_lookahead(tok: &token::Token) -> bool { match *tok { token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true, _ => false @@ -4565,12 +4573,12 @@ impl Parser { // Parses a string as an ABI spec on an extern type or module. Consumes // the `extern` keyword, if one is found. - fn parse_opt_abis(&self) -> Option { + fn parse_opt_abis(&mut self) -> Option { if !self.eat_keyword(keywords::Extern) { return None } - match *self.token { + match self.token { token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => { self.bump(); @@ -4581,7 +4589,7 @@ impl Parser { Some(abi) => { if abis.contains(abi) { self.span_err( - *self.span, + self.span, format!("ABI `{}` appears twice", word)); } else { @@ -4591,7 +4599,7 @@ impl Parser { None => { self.span_err( - *self.span, + self.span, format!("illegal ABI: \ expected one of [{}], \ found `{}`", @@ -4613,11 +4621,11 @@ impl Parser { // flags; on failure, return iovi_none. // NB: this function no longer parses the items inside an // extern mod. - fn parse_item_or_view_item(&self, + fn parse_item_or_view_item(&mut self, attrs: ~[Attribute], macros_allowed: bool) -> item_or_view_item { - match *self.token { + match self.token { INTERPOLATED(token::nt_item(item)) => { self.bump(); let new_attrs = vec::append(attrs, item.attrs); @@ -4653,10 +4661,13 @@ impl Parser { let abis = opt_abis.unwrap_or(AbiSet::C()); let (ident, item_, extra_attrs) = self.parse_item_fn(extern_fn, abis); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, - item_, visibility, - maybe_append(attrs, - extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } else { // EXTERN MODULE ITEM (iovi_view_item) return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs, @@ -4668,19 +4679,27 @@ impl Parser { // STATIC ITEM self.bump(); let (ident, item_, extra_attrs) = self.parse_item_const(); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.is_keyword(keywords::Fn) && - self.look_ahead(1, |f| !self.fn_expr_lookahead(f)) { + self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) { // FUNCTION ITEM self.bump(); let (ident, item_, extra_attrs) = self.parse_item_fn(impure_fn, AbiSet::Rust()); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.is_keyword(keywords::Unsafe) && self.look_ahead(1u, |t| *t != token::LBRACE) { @@ -4689,57 +4708,85 @@ impl Parser { self.expect_keyword(keywords::Fn); let (ident, item_, extra_attrs) = self.parse_item_fn(unsafe_fn, AbiSet::Rust()); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.eat_keyword(keywords::Mod) { // MODULE ITEM let (ident, item_, extra_attrs) = self.parse_item_mod(attrs); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.eat_keyword(keywords::Type) { // TYPE ITEM let (ident, item_, extra_attrs) = self.parse_item_type(); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.eat_keyword(keywords::Enum) { // ENUM ITEM let (ident, item_, extra_attrs) = self.parse_item_enum(); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.eat_keyword(keywords::Trait) { // TRAIT ITEM let (ident, item_, extra_attrs) = self.parse_item_trait(); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.eat_keyword(keywords::Impl) { // IMPL ITEM let (ident, item_, extra_attrs) = self.parse_item_impl(); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } if self.eat_keyword(keywords::Struct) { // STRUCT ITEM let (ident, item_, extra_attrs) = self.parse_item_struct(); - return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, - visibility, - maybe_append(attrs, extra_attrs))); + let item = self.mk_item(lo, + self.last_span.hi, + ident, + item_, + visibility, + maybe_append(attrs, extra_attrs)); + return iovi_item(item); } self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility) } // parse a foreign item; on failure, return iovi_none. - fn parse_foreign_item(&self, + fn parse_foreign_item(&mut self, attrs: ~[Attribute], macros_allowed: bool) -> item_or_view_item { @@ -4763,13 +4810,13 @@ impl Parser { // this is the fall-through for parsing items. fn parse_macro_use_or_failure( - &self, + &mut self, attrs: ~[Attribute], macros_allowed: bool, lo : BytePos, visibility : visibility ) -> item_or_view_item { - if macros_allowed && !token::is_any_keyword(self.token) + if macros_allowed && !token::is_any_keyword(&self.token) && self.look_ahead(1, |t| *t == token::NOT) && (self.look_ahead(2, |t| is_plain_ident(t)) || self.look_ahead(2, |t| *t == token::LPAREN) @@ -4783,15 +4830,15 @@ impl Parser { // a 'special' identifier (like what `macro_rules!` uses) // is optional. We should eventually unify invoc syntax // and remove this. - let id = if is_plain_ident(&*self.token) { + let id = if is_plain_ident(&self.token) { self.parse_ident() } else { token::special_idents::invalid // no special identifier }; // eat a matched-delimiter token tree: - let tts = match *self.token { + let tts = match self.token { token::LPAREN | token::LBRACE => { - let ket = token::flip_delimiter(&*self.token); + let ket = token::flip_delimiter(&self.token); self.bump(); self.parse_seq_to_end(&ket, seq_sep_none(), @@ -4805,8 +4852,13 @@ impl Parser { span: mk_sp(self.span.lo, self.span.hi) }; let item_ = item_mac(m); - return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_, - visibility, attrs)); + let item = self.mk_item(lo, + self.last_span.hi, + id, + item_, + visibility, + attrs); + return iovi_item(item); } // FAILURE TO PARSE ITEM @@ -4818,12 +4870,12 @@ impl Parser { s.push_str("priv") } s.push_char('`'); - self.span_fatal(*self.last_span, s); + self.span_fatal(self.last_span, s); } return iovi_none(attrs); } - pub fn parse_item(&self, attrs: ~[Attribute]) -> Option<@ast::item> { + pub fn parse_item(&mut self, attrs: ~[Attribute]) -> Option<@ast::item> { match self.parse_item_or_view_item(attrs, true) { iovi_none(_) => None, iovi_view_item(_) => @@ -4835,7 +4887,7 @@ impl Parser { } // parse, e.g., "use a::b::{z,y}" - fn parse_use(&self) -> view_item_ { + fn parse_use(&mut self) -> view_item_ { return view_item_use(self.parse_view_paths()); } @@ -4845,10 +4897,10 @@ impl Parser { // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE // | MOD? non_global_path MOD_SEP STAR // | MOD? non_global_path - fn parse_view_path(&self) -> @view_path { + fn parse_view_path(&mut self) -> @view_path { let lo = self.span.lo; - if *self.token == token::LBRACE { + if self.token == token::LBRACE { // use {foo,bar} let idents = self.parse_unspanned_seq( &token::LBRACE, &token::RBRACE, @@ -4866,12 +4918,12 @@ impl Parser { let first_ident = self.parse_ident(); let mut path = ~[first_ident]; debug!("parsed view_path: {}", self.id_to_str(first_ident)); - match *self.token { + match self.token { token::EQ => { // x = foo::bar self.bump(); path = ~[self.parse_ident()]; - while *self.token == token::MOD_SEP { + while self.token == token::MOD_SEP { self.bump(); let id = self.parse_ident(); path.push(id); @@ -4895,10 +4947,10 @@ impl Parser { token::MOD_SEP => { // foo::bar or foo::{a,b,c} or foo::* - while *self.token == token::MOD_SEP { + while self.token == token::MOD_SEP { self.bump(); - match *self.token { + match self.token { token::IDENT(i, _) => { self.bump(); path.push(i); @@ -4969,11 +5021,11 @@ impl Parser { } // matches view_paths = view_path | view_path , view_paths - fn parse_view_paths(&self) -> ~[@view_path] { + fn parse_view_paths(&mut self) -> ~[@view_path] { let mut vp = ~[self.parse_view_path()]; - while *self.token == token::COMMA { + while self.token == token::COMMA { self.bump(); - self.obsolete(*self.last_span, ObsoleteMultipleImport); + self.obsolete(self.last_span, ObsoleteMultipleImport); vp.push(self.parse_view_path()); } return vp; @@ -4983,7 +5035,7 @@ impl Parser { // text that can't be parsed as an item // - mod_items uses extern_mod_allowed = true // - block_tail_ uses extern_mod_allowed = false - fn parse_items_and_view_items(&self, + fn parse_items_and_view_items(&mut self, first_item_attrs: ~[Attribute], mut extern_mod_allowed: bool, macros_allowed: bool) @@ -5067,7 +5119,7 @@ impl Parser { // Parses a sequence of foreign items. Stops when it finds program // text that can't be parsed as an item - fn parse_foreign_items(&self, first_item_attrs: ~[Attribute], + fn parse_foreign_items(&mut self, first_item_attrs: ~[Attribute], macros_allowed: bool) -> ParsedItemsAndViewItems { let mut attrs = vec::append(first_item_attrs, @@ -5076,7 +5128,7 @@ impl Parser { loop { match self.parse_foreign_item(attrs, macros_allowed) { iovi_none(returned_attrs) => { - if *self.token == token::RBRACE { + if self.token == token::RBRACE { attrs = returned_attrs; break } @@ -5108,7 +5160,7 @@ impl Parser { // Parses a source module as a crate. This is the main // entry point for the parser. - pub fn parse_crate_mod(&self) -> Crate { + pub fn parse_crate_mod(&mut self) -> Crate { let lo = self.span.lo; // parse the crate's inner attrs, maybe (oops) one // of the attrs of an item: @@ -5125,8 +5177,8 @@ impl Parser { } } - pub fn parse_optional_str(&self) -> Option<(@str, ast::StrStyle)> { - let (s, style) = match *self.token { + pub fn parse_optional_str(&mut self) -> Option<(@str, ast::StrStyle)> { + let (s, style) = match self.token { token::LIT_STR(s) => (s, ast::CookedStr), token::LIT_STR_RAW(s, n) => (s, ast::RawStr(n)), _ => return None @@ -5135,7 +5187,7 @@ impl Parser { Some((ident_to_str(&s), style)) } - pub fn parse_str(&self) -> (@str, StrStyle) { + pub fn parse_str(&mut self) -> (@str, StrStyle) { match self.parse_optional_str() { Some(s) => { s } _ => self.fatal("expected string literal") diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 5138115746e1f..a6239ab38068b 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 7cea2ed3f9ca6..38473eb5bcdc6 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::span_handler, + span_diagnostic: @diagnostic::span_handler, 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, 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) { + 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(s.s, n, off); + 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(s: @ps, b: breaks, elts: &[T], op: |@ps, &T|) { +pub fn commasep(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(s: @ps, b: breaks, elts: &[T], op: |@ps, &T|) { pub fn commasep_cmnt( - 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( 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( 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) { +pub fn print_opt_lifetime(s: &mut ps, lifetime: &Option) { 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(ref mt) => { word(&mut s.s, "@"); print_mt(s, mt); } + 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) { +pub fn print_type_ref(s: &mut ps, ty: &P) { 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], 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,36 @@ 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::ExprVstoreUniq => word(&mut s.s, "~"), + ast::ExprVstoreBox => word(&mut s.s, "@"), ast::ExprVstoreMutBox => { - word(s.s, "@"); - word(s.s, "mut"); + word(&mut s.s, "@"); + word(&mut s.s, "mut"); } - ast::ExprVstoreSlice => word(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 +1112,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 +1139,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 +1151,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 +1162,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 +1222,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 +1254,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 +1264,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 +1296,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 +1343,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 +1363,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 +1390,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 +1422,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 +1516,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 +1531,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 +1539,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 +1560,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>) { maybe_print_comment(s, path.span.lo); if path.global { - word(s.s, "::"); + word(&mut s.s, "::"); } let mut first = true; @@ -1552,7 +1589,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 +1604,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 +1627,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>) { 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 +1666,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 +1675,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 +1688,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 +1702,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 +1742,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 +1762,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, abis: AbiSet, @@ -1760,7 +1802,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) { // It is unfortunate to duplicate the commasep logic, but we want the // self type and the args all in the same box. @@ -1778,12 +1820,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) { popen(s); print_fn_args(s, decl, opt_explicit_self); if decl.variadic { - word(s.s, ", ..."); + word(&mut s.s, ", ..."); } pclose(s); @@ -1798,10 +1840,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 +1857,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 +1875,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, +pub fn print_bounds(s: &mut ps, bounds: &OptVec, 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 +1890,24 @@ pub fn print_bounds(s: @ps, bounds: &OptVec, 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 +1926,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 +1952,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 +1966,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 +1998,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); } if !mta.is_empty() { @@ -1973,24 +2015,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), @@ -2004,8 +2046,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); @@ -2014,7 +2056,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, opt_sigil: Option, opt_region: &Option, @@ -2030,7 +2072,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() { @@ -2044,20 +2086,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); } @@ -2076,12 +2118,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); } @@ -2103,7 +2145,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) { let cm; match s.cm { Some(ccm) => cm = ccm, _ => return } @@ -2124,10 +2166,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) => { @@ -2139,11 +2181,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; } _ => () @@ -2154,45 +2196,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); } } @@ -2202,7 +2244,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 { +pub fn next_lit(s: &mut ps, pos: BytePos) -> Option { match s.literals { Some(ref lits) => { while s.cur_cmnt_and_lit.cur_lit < lits.len() { @@ -2217,7 +2259,7 @@ pub fn next_lit(s: @ps, pos: BytePos) -> Option { } } -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) => { @@ -2231,33 +2273,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); } @@ -2269,30 +2311,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, 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 to_str(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: @ps) -> Option { +pub fn next_comment(s: &mut ps) -> Option { match s.comments { Some(ref cmnts) => { if s.cur_cmnt_and_lit.cur_cmnt < cmnts.len() { @@ -2305,7 +2359,7 @@ pub fn next_comment(s: @ps) -> Option { } } -pub fn print_opt_purity(s: @ps, opt_purity: Option) { +pub fn print_opt_purity(s: &mut ps, opt_purity: Option) { match opt_purity { Some(ast::impure_fn) => { } Some(purity) => { @@ -2315,7 +2369,7 @@ pub fn print_opt_purity(s: @ps, opt_purity: Option) { } } -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) { match opt_abis { Some(abis) if !abis.is_rust() => { @@ -2326,7 +2380,7 @@ pub fn print_opt_abis_and_extern_if_nondefault(s: @ps, }; } -pub fn print_extern_opt_abis(s: @ps, opt_abis: Option) { +pub fn print_extern_opt_abis(s: &mut ps, opt_abis: Option) { match opt_abis { Some(abis) => { word_nbsp(s, "extern"); @@ -2336,23 +2390,23 @@ pub fn print_extern_opt_abis(s: @ps, opt_abis: Option) { }; } -pub fn print_opt_sigil(s: @ps, opt_sigil: Option) { +pub fn print_opt_sigil(s: &mut ps, opt_sigil: Option) { 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, opt_purity: Option, abis: AbiSet, onceness: ast::Onceness, opt_sigil: Option, vis: ast::visibility) { - word(s.s, visibility_qualified(vis, "")); + word(&mut s.s, visibility_qualified(vis, "")); if abis != AbiSet::Rust() { word_nbsp(s, "extern"); @@ -2366,7 +2420,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); } @@ -2385,14 +2439,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 => {} diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index c144b36a86f5b..b694e1f702b4e 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 { - priv map: @mut HashMap, - priv vect: @mut ~[T], + priv map: @RefCell>, + priv vect: @RefCell<~[T]>, } // when traits can extend traits, we should extend index to get [] impl Interner { pub fn new() -> Interner { Interner { - map: @mut HashMap::new(), - vect: @mut ~[], + map: @RefCell::new(HashMap::new()), + vect: @RefCell::new(~[]), } } @@ -40,37 +41,41 @@ impl Interner { } 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>(&self, val: &Q) -> Option { - 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 Interner { // A StrInterner differs from Interner 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>, + priv vect: @RefCell<~[@str]>, } // when traits can extend traits, we should extend index 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>(&self, val: &Q) -> Option { - 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 2d13cdb9bbb7f..21dd26b63ac16 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 (p,ps) = string_to_parser_and_sess(source_str); (p.parse_crate_mod(),ps) } diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs index 72ce66c20bd71..90b01f8888bef 100644 --- a/src/test/auxiliary/cci_nested_lib.rs +++ b/src/test/auxiliary/cci_nested_lib.rs @@ -10,6 +10,8 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + pub struct Entry { key: A, value: B @@ -17,11 +19,12 @@ pub struct Entry { pub struct alist { eq_fn: extern "Rust" fn(A,A) -> bool, - data: @mut ~[Entry] + data: @RefCell<~[Entry]>, } pub fn alist_add(lst: &alist, k: A, v: B) { - lst.data.push(Entry{key:k, value:v}); + let mut data = lst.data.borrow_mut(); + data.get().push(Entry{key:k, value:v}); } pub fn alist_get B { let eq_fn = lst.eq_fn; - for entry in lst.data.iter() { + let data = lst.data.borrow(); + for entry in data.get().iter() { if eq_fn(entry.key.clone(), k.clone()) { return entry.value.clone(); } @@ -41,12 +45,18 @@ pub fn alist_get() -> alist { fn eq_int(a: int, b: int) -> bool { a == b } - return alist {eq_fn: eq_int, data: @mut ~[]}; + return alist { + eq_fn: eq_int, + data: @RefCell::new(~[]), + }; } #[inline] pub fn new_int_alist_2() -> alist { #[inline] fn eq_int(a: int, b: int) -> bool { a == b } - return alist {eq_fn: eq_int, data: @mut ~[]}; + return alist { + eq_fn: eq_int, + data: @RefCell::new(~[]), + }; } diff --git a/src/test/auxiliary/issue-2631-a.rs b/src/test/auxiliary/issue-2631-a.rs index f5d2fb9ffd228..15dde899ce374 100644 --- a/src/test/auxiliary/issue-2631-a.rs +++ b/src/test/auxiliary/issue-2631-a.rs @@ -14,11 +14,12 @@ extern mod extra; +use std::cell::RefCell; use std::hashmap::HashMap; -pub type header_map = HashMap<~str, @mut ~[@~str]>; +pub type header_map = HashMap<~str, @RefCell<~[@~str]>>; // the unused ty param is necessary so this gets monomorphized pub fn request(req: &header_map) { - let _x = (*((**req.get(&~"METHOD")).clone())[0u]).clone(); + let _x = (*((**req.get(&~"METHOD")).clone()).get()[0u]).clone(); } diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 39bcfde2826d1..75587f17b1033 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -86,7 +86,7 @@ impl Sudoku { return Sudoku::new(g) } - pub fn write(&self, writer: @mut io::Writer) { + pub fn write(&self, writer: &mut io::Writer) { for row in range(0u8, 9u8) { write!(writer, "{}", self.grid[row][0]); for col in range(1u8, 9u8) { @@ -280,5 +280,5 @@ fn main() { Sudoku::read(BufferedReader::new(io::stdin())) }; sudoku.solve(); - sudoku.write(@mut io::stdout() as @mut io::Writer); + sudoku.write(&mut io::stdout()); } diff --git a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs index bfc1884ac5a7f..9d628c1f6c750 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs @@ -49,13 +49,5 @@ fn b() { q.x += 1; // and OK to mutate it } -fn c() { - // Here the receiver is in aliased memory but due to write - // barriers we can still consider it immutable. - let q = @mut Point {x: 3, y: 4}; - *q + 3; - q.times(3); -} - fn main() { } diff --git a/src/test/compile-fail/borrowck-loan-rcvr.rs b/src/test/compile-fail/borrowck-loan-rcvr.rs index 5c6f7082ed03b..a0071938ce437 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr.rs @@ -48,16 +48,5 @@ fn b() { l.x += 1; } -fn c() { - // Loaning @mut as & is considered legal due to dynamic checks... - let q = @mut point {x: 3, y: 4}; - q.impurem(); - - // ...but we still detect errors statically when we can. - q.blockm(|| { - q.x = 10; //~ ERROR cannot assign - }) -} - fn main() { } diff --git a/src/test/compile-fail/borrowck-mut-boxed-vec.rs b/src/test/compile-fail/borrowck-mut-boxed-vec.rs deleted file mode 100644 index 84c2db8bd576b..0000000000000 --- a/src/test/compile-fail/borrowck-mut-boxed-vec.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -fn main() { - let v = @mut [ 1, 2, 3 ]; - for _x in v.iter() { - v[1] = 4; //~ ERROR cannot assign - } -} diff --git a/src/test/compile-fail/borrowck-mut-deref-comp.rs b/src/test/compile-fail/borrowck-mut-deref-comp.rs index 7cf2e57ab8045..77318e6a636a1 100644 --- a/src/test/compile-fail/borrowck-mut-deref-comp.rs +++ b/src/test/compile-fail/borrowck-mut-deref-comp.rs @@ -12,7 +12,7 @@ struct foo(~int); -fn borrow(x: @mut foo) { +fn borrow(x: @foo) { let _y = &***x; *x = foo(~4); //~ ERROR cannot assign } diff --git a/src/test/compile-fail/borrowck-object-mutability.rs b/src/test/compile-fail/borrowck-object-mutability.rs index e6cb8d62d0493..1d1b993f5d1fe 100644 --- a/src/test/compile-fail/borrowck-object-mutability.rs +++ b/src/test/compile-fail/borrowck-object-mutability.rs @@ -30,11 +30,6 @@ fn managed_receiver(x: @Foo) { x.borrowed_mut(); //~ ERROR cannot borrow } -fn managed_mut_receiver(x: @mut Foo) { - x.borrowed(); - x.borrowed_mut(); -} - fn owned_receiver(x: ~Foo) { x.borrowed(); x.borrowed_mut(); //~ ERROR cannot borrow diff --git a/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail-2.rs b/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail-2.rs deleted file mode 100644 index 451f023f5fcf7..0000000000000 --- a/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail-2.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let mut b = ~3; - let _x = &mut *b; - let _y = &mut *b; //~ ERROR cannot borrow -} diff --git a/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail-3.rs b/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail-3.rs deleted file mode 100644 index c455de888a330..0000000000000 --- a/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail-3.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let mut a = ~3; - let mut b = &mut a; - let _c = &mut *b; - let mut d = /*move*/ a; //~ ERROR cannot move out - *d += 1; -} diff --git a/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail.rs b/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail.rs deleted file mode 100644 index e18808dfe538a..0000000000000 --- a/src/test/compile-fail/borrowck-wg-borrow-mut-to-imm-fail.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let mut b = ~3; - let _x = &mut *b; - let mut y = /*move*/ b; //~ ERROR cannot move out - *y += 1; -} diff --git a/src/test/compile-fail/borrowck-wg-move-base-2.rs b/src/test/compile-fail/borrowck-wg-move-base-2.rs deleted file mode 100644 index 4050b4c5971a0..0000000000000 --- a/src/test/compile-fail/borrowck-wg-move-base-2.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn foo(x: &mut int) { - let mut a = 3; - let mut _y = &mut *x; - let _z = &mut *_y; - _y = &mut a; //~ ERROR cannot assign -} - -fn main() { -} diff --git a/src/test/compile-fail/cast-immutable-mutable-trait.rs b/src/test/compile-fail/cast-immutable-mutable-trait.rs deleted file mode 100644 index 817696c6d20de..0000000000000 --- a/src/test/compile-fail/cast-immutable-mutable-trait.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -trait T { - fn foo(@mut self); -} - -struct S { - unused: int -} - -impl T for S { - fn foo(@mut self) { - } -} - -fn main() { - let s = @S { unused: 0 }; - let _s2 = s as @mut T; //~ error: types differ in mutability - let _s3 = &s as &mut T; //~ error: types differ in mutability -} diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs index a4ebfef1774c6..2277f7080af75 100644 --- a/src/test/compile-fail/fn-variance-1.rs +++ b/src/test/compile-fail/fn-variance-1.rs @@ -8,19 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[feature(managed_boxes)]; +fn takes_imm(x: &int) { } -fn takes_mut(x: @mut int) { } -fn takes_imm(x: @int) { } +fn takes_mut(x: &mut int) { } fn apply(t: T, f: |T|) { f(t) } fn main() { - apply(@3, takes_mut); //~ ERROR (values differ in mutability) - apply(@3, takes_imm); + apply(&3, takes_mut); //~ ERROR (values differ in mutability) + apply(&3, takes_imm); - apply(@mut 3, takes_mut); - apply(@mut 3, takes_imm); //~ ERROR (values differ in mutability) + apply(&mut 3, takes_mut); + apply(&mut 3, takes_imm); //~ ERROR (values differ in mutability) } diff --git a/src/test/compile-fail/issue-10487.rs b/src/test/compile-fail/issue-10487.rs index d116b7b67ca99..302e883942e6c 100644 --- a/src/test/compile-fail/issue-10487.rs +++ b/src/test/compile-fail/issue-10487.rs @@ -12,6 +12,5 @@ static x: ~[int] = ~[123, 456]; //~ ERROR: cannot allocate vectors in constant expressions static y: @[int] = @[123, 456]; //~ ERROR: cannot allocate vectors in constant expressions -static z: @mut [int] = @mut [123, 456]; //~ ERROR: cannot allocate vectors in constant expressions fn main() {} diff --git a/src/test/compile-fail/issue-2548.rs b/src/test/compile-fail/issue-2548.rs index 21b6959692f30..def712d9e8de4 100644 --- a/src/test/compile-fail/issue-2548.rs +++ b/src/test/compile-fail/issue-2548.rs @@ -12,10 +12,10 @@ // A test case for #2548. -struct foo { - x: @mut int, - +use std::cell::Cell; +struct foo { + x: @Cell, } #[unsafe_destructor] @@ -23,17 +23,17 @@ impl Drop for foo { fn drop(&mut self) { unsafe { println("Goodbye, World!"); - *self.x += 1; + self.x.set(self.x.get() + 1); } } } -fn foo(x: @mut int) -> foo { +fn foo(x: @Cell) -> foo { foo { x: x } } fn main() { - let x = @mut 0; + let x = @Cell::new(0); { let mut res = foo(x); @@ -43,5 +43,5 @@ fn main() { assert_eq!(v.len(), 2); } - assert_eq!(*x, 1); + assert_eq!(x.get(), 1); } diff --git a/src/test/compile-fail/issue-3668.rs b/src/test/compile-fail/issue-3668.rs index 4665687db85b6..fe57d7171a68f 100644 --- a/src/test/compile-fail/issue-3668.rs +++ b/src/test/compile-fail/issue-3668.rs @@ -10,7 +10,7 @@ #[feature(managed_boxes)]; -struct P { child: Option<@mut P> } +struct P { child: Option<@P> } trait PTrait { fn getChildOption(&self) -> Option<@P>; } diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs index 2ea12ab9fdc92..de277b4c36efd 100644 --- a/src/test/compile-fail/kindck-destructor-owned.rs +++ b/src/test/compile-fail/kindck-destructor-owned.rs @@ -1,12 +1,11 @@ #[feature(managed_boxes)]; struct Foo { - f: @mut int, + f: @int, } impl Drop for Foo { //~ ERROR cannot implement a destructor on a structure that does not satisfy Send fn drop(&mut self) { - *self.f = 10; } } diff --git a/src/test/compile-fail/lub-in-args.rs b/src/test/compile-fail/lub-in-args.rs deleted file mode 100644 index 0ce8ee40d3bfa..0000000000000 --- a/src/test/compile-fail/lub-in-args.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -fn two_args(x: T, y: T) { } - -fn main() { - let a: @mut int = @mut 3; - let b: @int = @3; - - // NOTE: - // - // The fact that this test fails to compile reflects a known - // shortcoming of the current inference algorithm. These errors - // are *not* desirable. - - two_args(a, b); //~ ERROR (values differ in mutability) -} diff --git a/src/test/compile-fail/object-pointer-types.rs b/src/test/compile-fail/object-pointer-types.rs index a1a577a1856f7..2270cb6f498b1 100644 --- a/src/test/compile-fail/object-pointer-types.rs +++ b/src/test/compile-fail/object-pointer-types.rs @@ -15,7 +15,6 @@ trait Foo { fn borrowed_mut(&mut self); fn managed(@self); - fn managed_mut(@mut self); fn owned(~self); } @@ -24,7 +23,6 @@ fn borrowed_receiver(x: &Foo) { x.borrowed(); x.borrowed_mut(); // See [1] x.managed(); //~ ERROR does not implement any method - x.managed_mut(); //~ ERROR does not implement any method x.owned(); //~ ERROR does not implement any method } @@ -32,7 +30,6 @@ fn borrowed_mut_receiver(x: &mut Foo) { x.borrowed(); x.borrowed_mut(); x.managed(); //~ ERROR does not implement any method - x.managed_mut(); //~ ERROR does not implement any method x.owned(); //~ ERROR does not implement any method } @@ -40,15 +37,6 @@ fn managed_receiver(x: @Foo) { x.borrowed(); x.borrowed_mut(); // See [1] x.managed(); - x.managed_mut(); //~ ERROR does not implement any method - x.owned(); //~ ERROR does not implement any method -} - -fn managed_mut_receiver(x: @mut Foo) { - x.borrowed(); - x.borrowed_mut(); - x.managed(); //~ ERROR does not implement any method - x.managed_mut(); x.owned(); //~ ERROR does not implement any method } @@ -56,7 +44,6 @@ fn owned_receiver(x: ~Foo) { x.borrowed(); x.borrowed_mut(); // See [1] x.managed(); //~ ERROR does not implement any method - x.managed_mut(); //~ ERROR does not implement any method x.owned(); } diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs index 6c19ef9700fab..9c9b4a9f4d5b0 100644 --- a/src/test/compile-fail/pinned-deep-copy.rs +++ b/src/test/compile-fail/pinned-deep-copy.rs @@ -10,20 +10,22 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + struct r { - i: @mut int, + i: @Cell, } #[unsafe_destructor] impl Drop for r { fn drop(&mut self) { unsafe { - *(self.i) = *(self.i) + 1; + self.i.set(self.i.get() + 1); } } } -fn r(i: @mut int) -> r { +fn r(i: @Cell) -> r { r { i: i } @@ -34,7 +36,7 @@ struct A { } fn main() { - let i = @mut 0; + let i = @Cell::new(0); { // Can't do this copy let x = ~~~A {y: r(i)}; diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs index 6a6b8f95e63c8..b36933c4957f2 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs @@ -11,7 +11,7 @@ #[feature(managed_boxes)]; struct invariant<'a> { - f: 'static |x: @mut &'a int| + f: 'static |x: &mut &'a int| } fn to_same_lifetime<'r>(bi: invariant<'r>) { diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs index 4210c52e7f6e4..449cbc6970fdb 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs @@ -11,7 +11,7 @@ #[feature(managed_boxes)]; struct invariant<'a> { - f: 'static || -> @mut &'a int + f: 'static || -> &mut &'a int } fn to_same_lifetime<'r>(bi: invariant<'r>) { diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 9771fea04ef52..c604e66507e0a 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -10,15 +10,17 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + struct r { - i: @mut int, + i: @Cell, } #[unsafe_destructor] impl Drop for r { fn drop(&mut self) { unsafe { - *(self.i) = *(self.i) + 1; + self.i.set(self.i.get() + 1); } } } @@ -27,12 +29,12 @@ fn f(_i: ~[T], _j: ~[T]) { } fn main() { - let i1 = @mut 0; - let i2 = @mut 1; + let i1 = @Cell::new(0); + let i2 = @Cell::new(1); let r1 = ~[~r { i: i1 }]; let r2 = ~[~r { i: i2 }]; f(r1.clone(), r2.clone()); //~^ ERROR failed to find an implementation of - info!("{:?}", (r2, *i1)); - info!("{:?}", (r1, *i2)); + info!("{:?}", (r2, i1.get())); + info!("{:?}", (r1, i2.get())); } diff --git a/src/test/pretty/block-disambig.rs b/src/test/pretty/block-disambig.rs index 8d6eaef8b340f..3f789fa456a9c 100644 --- a/src/test/pretty/block-disambig.rs +++ b/src/test/pretty/block-disambig.rs @@ -14,6 +14,8 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + fn test1() { let val = @0; { } *val; } fn test2() -> int { let val = @0; { } *val } @@ -21,9 +23,9 @@ fn test2() -> int { let val = @0; { } *val } struct S { eax: int } fn test3() { - let regs = @mut S {eax: 0}; + let regs = @Cell::new(S {eax: 0}); match true { true => { } _ => { } } - (*regs).eax = 1; + regs.set(S {eax: 1}); } fn test4() -> bool { let regs = @true; if true { } *regs || false } @@ -51,10 +53,13 @@ fn test8() -> int { } } -fn test9() { let regs = @mut 0; match true { true => { } _ => { } } *regs += 1; } +fn test9() { + let regs = @Cell::new(0); + match true { true => { } _ => { } } regs.set(regs.get() + 1); +} fn test10() -> int { - let regs = @mut ~[0]; + let regs = @~[0]; match true { true => { } _ => { } } (*regs)[0] } diff --git a/src/test/run-fail/borrowck-wg-autoderef-and-autoborrowvec-combined-fail-issue-6272.rs b/src/test/run-fail/borrowck-wg-autoderef-and-autoborrowvec-combined-fail-issue-6272.rs deleted file mode 100644 index c9bc061995d3e..0000000000000 --- a/src/test/run-fail/borrowck-wg-autoderef-and-autoborrowvec-combined-fail-issue-6272.rs +++ /dev/null @@ -1,23 +0,0 @@ -// error-pattern:borrowed - -// Issue #6272. Tests that freezing correctly accounts for all the -// implicit derefs that can occur and freezes the innermost box. See -// the companion test -// -// run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs -// -// for a detailed explanation of what is going on here. - -#[feature(managed_boxes)]; - -fn main() { - let a = @mut [3i]; - let b = @mut [a]; - let c = @mut b; - - // this should freeze `a` only - let _x: &mut [int] = c[0]; - - // hence this should fail - a[0] = a[0]; -} diff --git a/src/test/run-fail/borrowck-wg-fail-2.rs b/src/test/run-fail/borrowck-wg-fail-2.rs deleted file mode 100644 index 284882ff6f5d5..0000000000000 --- a/src/test/run-fail/borrowck-wg-fail-2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// error-pattern:borrowed - -// Test that write guards trigger when there is a write to a field -// of a frozen structure. - -#[feature(managed_boxes)]; - -struct S { - x: int -} - -fn main() { - let x = @mut S { x: 3 }; - let _y: &S = x; - let z = x; - z.x = 5; -} diff --git a/src/test/run-fail/borrowck-wg-fail-3.rs b/src/test/run-fail/borrowck-wg-fail-3.rs deleted file mode 100644 index 2643ed261f944..0000000000000 --- a/src/test/run-fail/borrowck-wg-fail-3.rs +++ /dev/null @@ -1,13 +0,0 @@ -// error-pattern:borrowed - -// Test that write guards trigger when there is a write to a directly -// frozen @mut box. - -#[feature(managed_boxes)]; - -fn main() { - let x = @mut 3; - let _y: &mut int = x; - let z = x; - *z = 5; -} diff --git a/src/test/run-fail/borrowck-wg-fail-object-arg.rs b/src/test/run-fail/borrowck-wg-fail-object-arg.rs deleted file mode 100644 index 4a5664d08b690..0000000000000 --- a/src/test/run-fail/borrowck-wg-fail-object-arg.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[feature(managed_boxes)]; - -// error-pattern:borrowed - -trait Foo { - fn foo(&self, @mut int); -} - -impl Foo for int { - fn foo(&self, x: @mut int) { - *x += *self; - } -} - -fn it_takes_two(_f: &Foo, _g: &mut Foo) { -} - -fn main() { - let x = @mut 3_i; - let y = x as @mut Foo; - let z = y; - - it_takes_two(y, z); -} diff --git a/src/test/run-fail/borrowck-wg-fail-object.rs b/src/test/run-fail/borrowck-wg-fail-object.rs deleted file mode 100644 index 9e32dbf64206e..0000000000000 --- a/src/test/run-fail/borrowck-wg-fail-object.rs +++ /dev/null @@ -1,23 +0,0 @@ -#[feature(managed_boxes)]; - -// error-pattern:borrowed - -trait Foo { - fn foo(&self, @mut int); -} - -impl Foo for int { - fn foo(&self, x: @mut int) { - *x += *self; - } -} - -fn main() { - let x = @mut 3_i; - let y = x as @mut Foo; - - // The call to `y.foo(...)` should freeze `y` (and thus also `x`, - // since `x === y`). It is thus an error when `foo` tries to - // mutate `x`. - y.foo(x); -} diff --git a/src/test/run-fail/borrowck-wg-fail.rs b/src/test/run-fail/borrowck-wg-fail.rs deleted file mode 100644 index e1273381e93c7..0000000000000 --- a/src/test/run-fail/borrowck-wg-fail.rs +++ /dev/null @@ -1,15 +0,0 @@ -#[feature(managed_boxes)]; - -// error-pattern:borrowed - -// Test that write guards trigger when mut box is frozen -// as part of argument coercion. - -fn f(_x: &int, y: @mut int) { - *y = 2; -} - -fn main() { - let x = @mut 3; - f(x, x); -} diff --git a/src/test/run-fail/borrowck-wg-imm-then-mut.rs b/src/test/run-fail/borrowck-wg-imm-then-mut.rs deleted file mode 100644 index c41b9b37bb582..0000000000000 --- a/src/test/run-fail/borrowck-wg-imm-then-mut.rs +++ /dev/null @@ -1,21 +0,0 @@ -#[feature(managed_boxes)]; - -// error-pattern:borrowed - -// Test that if you imm borrow then mut borrow it fails. - -fn add1(a:@mut int) -{ - add2(a); // already frozen -} - -fn add2(_:&mut int) -{ -} - -pub fn main() -{ - let a = @mut 3; - let _b = &*a; // freezes a - add1(a); -} diff --git a/src/test/run-fail/borrowck-wg-mut-then-imm.rs b/src/test/run-fail/borrowck-wg-mut-then-imm.rs deleted file mode 100644 index aceadb0459c82..0000000000000 --- a/src/test/run-fail/borrowck-wg-mut-then-imm.rs +++ /dev/null @@ -1,21 +0,0 @@ -#[feature(managed_boxes)]; - -// error-pattern:borrowed - -// Test that if you mut borrow then imm borrow it fails. - -fn add1(a:@mut int) -{ - add2(a); // already frozen -} - -fn add2(_:&int) -{ -} - -pub fn main() -{ - let a = @mut 3; - let _b = &mut *a; // freezes a - add1(a); -} diff --git a/src/test/run-fail/borrowck-wg-one-mut-one-imm-slice-method.rs b/src/test/run-fail/borrowck-wg-one-mut-one-imm-slice-method.rs deleted file mode 100644 index d33e39e09a852..0000000000000 --- a/src/test/run-fail/borrowck-wg-one-mut-one-imm-slice-method.rs +++ /dev/null @@ -1,39 +0,0 @@ -// error-pattern:borrowed - -// Test that write guards trigger when there is a coercion to -// a slice on the receiver of a method. - -#[feature(managed_boxes)]; - -trait MyMutSlice { - fn my_mut_slice(self) -> Self; -} - -impl<'a, T> MyMutSlice for &'a mut [T] { - fn my_mut_slice(self) -> &'a mut [T] { - self - } -} - -trait MySlice { - fn my_slice(self) -> Self; -} - -impl<'a, T> MySlice for &'a [T] { - fn my_slice(self) -> &'a [T] { - self - } -} - -fn add(x:&mut [int], y:&[int]) -{ - x[0] = x[0] + y[0]; -} - -pub fn main() -{ - let z = @mut [1,2,3]; - let z2 = z; - add(z.my_mut_slice(), z2.my_slice()); - println!("{}", z[0]); -} diff --git a/src/test/run-fail/borrowck-wg-one-mut-one-imm-slices.rs b/src/test/run-fail/borrowck-wg-one-mut-one-imm-slices.rs deleted file mode 100644 index 63287981bdcc8..0000000000000 --- a/src/test/run-fail/borrowck-wg-one-mut-one-imm-slices.rs +++ /dev/null @@ -1,18 +0,0 @@ -// error-pattern:borrowed - -// Test that write guards trigger when arguments are coerced to slices. - -#[feature(managed_boxes)]; - -fn add(x:&mut [int], y:&[int]) -{ - x[0] = x[0] + y[0]; -} - -pub fn main() -{ - let z = @mut [1,2,3]; - let z2 = z; - add(z, z2); - println!("{}", z[0]); -} diff --git a/src/test/run-fail/borrowck-wg-one-mut-one-imm.rs b/src/test/run-fail/borrowck-wg-one-mut-one-imm.rs deleted file mode 100644 index 0820b94e181c4..0000000000000 --- a/src/test/run-fail/borrowck-wg-one-mut-one-imm.rs +++ /dev/null @@ -1,19 +0,0 @@ -// error-pattern:borrowed - -// Test that write guards trigger when we are indexing into -// an @mut vector. - -#[feature(managed_boxes)]; - -fn add(x:&mut int, y:&int) -{ - *x = *x + *y; -} - -pub fn main() -{ - let z = @mut [1,2,3]; - let z2 = z; - add(&mut z[0], &z2[0]); - println!("{}", z[0]); -} diff --git a/src/test/run-fail/borrowck-wg-two-array-indices.rs b/src/test/run-fail/borrowck-wg-two-array-indices.rs deleted file mode 100644 index 5ee9cd37e87b8..0000000000000 --- a/src/test/run-fail/borrowck-wg-two-array-indices.rs +++ /dev/null @@ -1,19 +0,0 @@ -// error-pattern:borrowed - -// Test that arguments trigger when there are *two mutable* borrows -// of indices. - -#[feature(managed_boxes)]; - -fn add(x:&mut int, y:&mut int) -{ - *x = *x + *y; -} - -pub fn main() -{ - let z = @mut [1,2,3]; - let z2 = z; - add(&mut z[0], &mut z2[0]); - println!("{}", z[0]); -} diff --git a/src/test/run-fail/unwind-misc-1.rs b/src/test/run-fail/unwind-misc-1.rs index b87303467cee5..09e7d0bc28c1f 100644 --- a/src/test/run-fail/unwind-misc-1.rs +++ b/src/test/run-fail/unwind-misc-1.rs @@ -14,7 +14,7 @@ #[feature(managed_boxes)]; fn main() { - let _count = @mut 0u; + let _count = @0u; let mut map = std::hashmap::HashMap::new(); let mut arr = ~[]; for _i in range(0u, 10u) { diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index 8f7f8c4fa58da..02ce1fd4b262a 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -10,6 +10,8 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + struct Pair { a: A, b: B } @@ -17,12 +19,15 @@ struct Pair { struct RecEnum(Rec); struct Rec { val: A, - rec: Option<@mut RecEnum> + rec: Option<@RefCell>> } fn make_cycle(a: A) { - let g: @mut RecEnum = @mut RecEnum(Rec {val: a, rec: None}); - g.rec = Some(g); + let g: @RefCell> = @RefCell::new(RecEnum(Rec {val: a, rec: None})); + { + let mut gb = g.borrow_mut(); + gb.get().rec = Some(g); + } } struct Invoker { diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index 1810f33eadbd9..8058556a469fb 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -35,8 +35,8 @@ fn test_ebml<'a, A: Encodable + Decodable> >(a1: &A) { - let mut wr = @mut std::io::mem::MemWriter::new(); - let mut ebml_w = EBWriter::Encoder(wr); + let mut wr = std::io::mem::MemWriter::new(); + let mut ebml_w = EBWriter::Encoder(&mut wr); a1.encode(&mut ebml_w); let bytes = wr.inner_ref().as_slice(); diff --git a/src/test/compile-fail/borrowck-assign-to-subfield.rs b/src/test/run-pass/borrowck-assign-to-subfield.rs similarity index 75% rename from src/test/compile-fail/borrowck-assign-to-subfield.rs rename to src/test/run-pass/borrowck-assign-to-subfield.rs index 40db36787bb4c..d388f070f8d87 100644 --- a/src/test/compile-fail/borrowck-assign-to-subfield.rs +++ b/src/test/run-pass/borrowck-assign-to-subfield.rs @@ -8,14 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[feature(managed_boxes)]; - fn main() { struct A { a: int, w: B, - x: @B, - z: @mut B } struct B { a: int @@ -23,8 +19,6 @@ fn main() { let mut p = A { a: 1, w: B {a: 1}, - x: @B {a: 1}, - z: @mut B {a: 1} }; // even though `x` is not declared as a mutable field, @@ -33,9 +27,4 @@ fn main() { // this is true for an interior field too p.w.a = 2; - - // in these cases we pass through a box, so the mut - // of the box is dominant - p.x.a = 2; //~ ERROR cannot assign to immutable field - p.z.a = 2; } diff --git a/src/test/run-pass/borrowck-preserve-box-in-arm-not-taken.rs b/src/test/run-pass/borrowck-preserve-box-in-arm-not-taken.rs index 3f6bcb4d5b794..8871035908bbf 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-arm-not-taken.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-arm-not-taken.rs @@ -12,15 +12,18 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + pub fn main() { - let x: @mut @Option<~int> = @mut @None; - match x { - @@Some(ref _y) => { + let x: @RefCell<@Option<~int>> = @RefCell::new(@None); + let mut xb = x.borrow_mut(); + match *xb.get() { + @Some(ref _y) => { // here, the refcount of `*x` is bumped so // `_y` remains valid even if `*x` is modified. - *x = @None; + *xb.get() = @None; } - @@None => { + @None => { // here, no bump of the ref count of `*x` is needed, but in // fact a bump occurs anyway because of how pattern marching // works. diff --git a/src/test/run-pass/borrowck-preserve-box-in-pat.rs b/src/test/run-pass/borrowck-preserve-box-in-pat.rs index 2fd2c689a3c50..b333bcae5823a 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-pat.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-pat.rs @@ -12,23 +12,25 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; use std::ptr; struct F { f: ~int } pub fn main() { - let x = @mut @F {f: ~3}; - match x { - @@F{f: ref b_x} => { + let x = @RefCell::new(@F {f: ~3}); + let mut xb = x.borrow_mut(); + match *xb.get() { + @F{f: ref b_x} => { assert_eq!(**b_x, 3); - assert_eq!(ptr::to_unsafe_ptr(&(x.f)), ptr::to_unsafe_ptr(b_x)); + assert_eq!(ptr::to_unsafe_ptr(&(xb.get().f)), ptr::to_unsafe_ptr(b_x)); - *x = @F {f: ~4}; + *xb.get() = @F {f: ~4}; info!("ptr::to_unsafe_ptr(*b_x) = {:x}", ptr::to_unsafe_ptr(&(**b_x)) as uint); assert_eq!(**b_x, 3); - assert!(ptr::to_unsafe_ptr(&(*x.f)) != ptr::to_unsafe_ptr(&(**b_x))); + assert!(ptr::to_unsafe_ptr(&(*xb.get().f)) != ptr::to_unsafe_ptr(&(**b_x))); } } } diff --git a/src/test/run-pass/borrowck-root-while-cond-2.rs b/src/test/run-pass/borrowck-root-while-cond-2.rs index 19b87584e2d43..9511d1b40e60c 100644 --- a/src/test/run-pass/borrowck-root-while-cond-2.rs +++ b/src/test/run-pass/borrowck-root-while-cond-2.rs @@ -14,6 +14,6 @@ struct F { f: @G } struct G { g: ~[int] } pub fn main() { - let rec = @mut F {f: @G {g: ~[1, 2, 3]}}; + let rec = @F {f: @G {g: ~[1, 2, 3]}}; while rec.f.g.len() == 23 {} } diff --git a/src/test/run-pass/borrowck-root-while-cond.rs b/src/test/run-pass/borrowck-root-while-cond.rs index 35ab64584f53d..a2d4991abc018 100644 --- a/src/test/run-pass/borrowck-root-while-cond.rs +++ b/src/test/run-pass/borrowck-root-while-cond.rs @@ -15,6 +15,6 @@ fn borrow<'r,T>(x: &'r T) -> &'r T {x} struct Rec { f: @int } pub fn main() { - let rec = @mut Rec {f: @22}; + let rec = @Rec {f: @22}; while *borrow(rec.f) == 23 {} } diff --git a/src/test/run-pass/borrowck-univariant-enum.rs b/src/test/run-pass/borrowck-univariant-enum.rs index aaa08ea49b32a..97d92f421c148 100644 --- a/src/test/run-pass/borrowck-univariant-enum.rs +++ b/src/test/run-pass/borrowck-univariant-enum.rs @@ -10,6 +10,8 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + enum newtype { newtype(int) } @@ -19,12 +21,12 @@ pub fn main() { // Test that borrowck treats enums with a single variant // specially. - let x = @mut 5; - let y = @mut newtype(3); - let z = match *y { + let x = @Cell::new(5); + let y = @Cell::new(newtype(3)); + let z = match y.get() { newtype(b) => { - *x += 1; - *x * b + x.set(x.get() + 1); + x.get() * b } }; assert_eq!(z, 18); diff --git a/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs b/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs deleted file mode 100644 index 27d337a28bf89..0000000000000 --- a/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Issue #6272. Tests that freezing correctly accounts for all the -// implicit derefs that can occur. -// -// In this particular case, the expression: -// -// let x: &mut [int] = c[0]; -// -// is seen by borrowck as this sequence of derefs -// and pointer offsets: -// -// &*((**c)[0]) -// -// or, written using `x.*` for `*x` (so that everything -// is a postfix operation): -// -// &c.*.*.[0].* -// ^ ^ -// | | -// b a -// -// Here I also indicated where the evaluation yields the boxes `a` and -// `b`. It is important then that we only freeze the innermost box -// (`a`), and not the other ones (`b`, `c`). -// -// Also see the companion test: -// -// run-fail/borrowck-wg-autoderef-and-autoborrowvec-combined-fail-issue-6272.rs - -#[feature(managed_boxes)]; - -pub fn main() { - let a = @mut 3i; - let b = @mut [a]; - let c = @mut [3]; - - // this should freeze `a` only - let _x: &mut int = a; - - // hence these writes should not fail: - b[0] = b[0]; - c[0] = c[0]; -} diff --git a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-2.rs b/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-2.rs deleted file mode 100644 index d721704ba5518..0000000000000 --- a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -struct Cat; - -fn bar(_: &Cat) { -} - -fn foo(cat: &mut Cat) { - bar(&*cat); -} - -pub fn main() { - let mut mimi = ~Cat; - foo(mimi); -} diff --git a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs b/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs deleted file mode 100644 index dcf497e81f743..0000000000000 --- a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs +++ /dev/null @@ -1,18 +0,0 @@ -struct Wizard { - spells: ~[&'static str] -} - -impl Wizard { - pub fn cast(&mut self) { - for &spell in self.spells.iter() { - println(spell); - } - } -} - -pub fn main() { - let mut harry = Wizard { - spells: ~[ "expelliarmus", "expecto patronum", "incendio" ] - }; - harry.cast(); -} diff --git a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm.rs b/src/test/run-pass/borrowck-wg-borrow-mut-to-imm.rs deleted file mode 100644 index 668f602b3d35c..0000000000000 --- a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn g(x: &Option) { - println(x.unwrap().to_str()); -} - -fn f(x: &mut Option) { - g(&*x); -} - -pub fn main() { - let mut x = ~Some(3); - f(x); -} diff --git a/src/test/run-pass/borrowck-wg-simple.rs b/src/test/run-pass/borrowck-wg-simple.rs deleted file mode 100644 index f561dba242327..0000000000000 --- a/src/test/run-pass/borrowck-wg-simple.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[feature(managed_boxes)]; - -fn f(x: &int) { - println(x.to_str()); -} - -pub fn main() { - let x = @mut 3; - f(x); -} diff --git a/src/test/run-pass/borrowck-wg-two-imm-borrows.rs b/src/test/run-pass/borrowck-wg-two-imm-borrows.rs deleted file mode 100644 index efd0572c8c633..0000000000000 --- a/src/test/run-pass/borrowck-wg-two-imm-borrows.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Test that we can borrow the same @mut box twice, so long as both are imm. - -#[feature(managed_boxes)]; - -fn add(x:&int, y:&int) -{ - *x + *y; -} - -pub fn main() -{ - let z = @mut [1,2,3]; - let z2 = z; - add(&z[0], &z2[0]); - println!("{}", z[0]); -} diff --git a/src/test/run-pass/cast-mutable-trait.rs b/src/test/run-pass/cast-mutable-trait.rs deleted file mode 100644 index 09d10502b846b..0000000000000 --- a/src/test/run-pass/cast-mutable-trait.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -trait T { - fn foo(@mut self); -} - -struct S { - unused: int -} - -impl T for S { - fn foo(@mut self) { - } -} - -fn bar(t: @mut T) { - t.foo(); -} - -pub fn main() { - let s = @mut S { unused: 0 }; - let s2 = s as @mut T; - s2.foo(); - bar(s2); - bar(s as @mut T); -} diff --git a/src/test/run-pass/class-cast-to-trait-multiple-types.rs b/src/test/run-pass/class-cast-to-trait-multiple-types.rs index e44d7c41931c4..8c14276894475 100644 --- a/src/test/run-pass/class-cast-to-trait-multiple-types.rs +++ b/src/test/run-pass/class-cast-to-trait-multiple-types.rs @@ -11,86 +11,92 @@ #[feature(managed_boxes)]; trait noisy { - fn speak(&self) -> int; + fn speak(&mut self) -> int; } struct dog { - priv barks : @mut uint, + priv barks: uint, - volume : @mut int, + volume: int, } impl dog { - fn bark(&self) -> int { - info!("Woof {} {}", *self.barks, *self.volume); - *self.barks += 1u; - if *self.barks % 3u == 0u { - *self.volume += 1; + fn bark(&mut self) -> int { + info!("Woof {} {}", self.barks, self.volume); + self.barks += 1u; + if self.barks % 3u == 0u { + self.volume += 1; } - if *self.barks % 10u == 0u { - *self.volume -= 2; + if self.barks % 10u == 0u { + self.volume -= 2; } - info!("Grrr {} {}", *self.barks, *self.volume); - *self.volume + info!("Grrr {} {}", self.barks, self.volume); + self.volume } } impl noisy for dog { - fn speak(&self) -> int { self.bark() } + fn speak(&mut self) -> int { + self.bark() + } } fn dog() -> dog { dog { - volume: @mut 0, - barks: @mut 0u + volume: 0, + barks: 0u } } #[deriving(Clone)] struct cat { - priv meows : @mut uint, + priv meows: uint, - how_hungry : @mut int, - name : ~str, + how_hungry: int, + name: ~str, } impl noisy for cat { - fn speak(&self) -> int { self.meow() as int } + fn speak(&mut self) -> int { + self.meow() as int + } } impl cat { - pub fn meow_count(&self) -> uint { *self.meows } + pub fn meow_count(&self) -> uint { + self.meows + } } impl cat { - fn meow(&self) -> uint { - info!("Meow"); - *self.meows += 1u; - if *self.meows % 5u == 0u { - *self.how_hungry += 1; - } - *self.meows + fn meow(&mut self) -> uint { + info!("Meow"); + self.meows += 1u; + if self.meows % 5u == 0u { + self.how_hungry += 1; + } + self.meows } } -fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { +fn cat(in_x: uint, in_y: int, in_name: ~str) -> cat { cat { - meows: @mut in_x, - how_hungry: @mut in_y, + meows: in_x, + how_hungry: in_y, name: in_name } } -fn annoy_neighbors(critter: @noisy) { +fn annoy_neighbors(critter: &mut noisy) { for _i in range(0u, 10) { critter.speak(); } } pub fn main() { - let nyan : cat = cat(0u, 2, ~"nyan"); - let whitefang : dog = dog(); - annoy_neighbors(@nyan.clone() as @noisy); - annoy_neighbors(@whitefang as @noisy); + let mut nyan: cat = cat(0u, 2, ~"nyan"); + let mut whitefang: dog = dog(); + annoy_neighbors(&mut nyan); + annoy_neighbors(&mut whitefang); assert_eq!(nyan.meow_count(), 10u); - assert_eq!(*whitefang.volume, 1); + assert_eq!(whitefang.volume, 1); } diff --git a/src/test/run-pass/class-cast-to-trait.rs b/src/test/run-pass/class-cast-to-trait.rs index cc723f8037dd1..86764df6ae07a 100644 --- a/src/test/run-pass/class-cast-to-trait.rs +++ b/src/test/run-pass/class-cast-to-trait.rs @@ -58,6 +58,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { pub fn main() { - let nyan: @mut noisy = @mut cat(0u, 2, ~"nyan") as @mut noisy; - nyan.speak(); + let mut nyan = cat(0u, 2, ~"nyan"); + let mut nyan: &mut noisy = &mut nyan; + nyan.speak(); } diff --git a/src/test/run-pass/cycle-collection.rs b/src/test/run-pass/cycle-collection.rs index 29a972ae30e96..ca1e18eb87b97 100644 --- a/src/test/run-pass/cycle-collection.rs +++ b/src/test/run-pass/cycle-collection.rs @@ -10,14 +10,16 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + enum taggy { - cons(@mut taggy), + cons(@RefCell), nil, } fn f() { - let a_box = @mut nil; - *a_box = cons(a_box); + let a_box = @RefCell::new(nil); + a_box.set(cons(a_box)); } pub fn main() { diff --git a/src/test/run-pass/cycle-collection2.rs b/src/test/run-pass/cycle-collection2.rs deleted file mode 100644 index f10592bf80097..0000000000000 --- a/src/test/run-pass/cycle-collection2.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -struct foo { - z: Option<@Invokable>, -} - -struct Thing { - w: @mut foo, -} - -trait Invokable { - fn f(&self); -} - -impl Invokable for Thing { - fn f(&self) { - nop_foo(self.w); - } -} - -fn nop() { } -fn nop_foo(_x : @mut foo) { } - -pub fn main() { - let w = @mut foo { - z: None, - }; - let x = @Thing { - w: w, - } as @Invokable; - w.z = Some(x); -} diff --git a/src/test/run-pass/deref-lval.rs b/src/test/run-pass/deref-lval.rs index 997e2f03abd92..914805c126f37 100644 --- a/src/test/run-pass/deref-lval.rs +++ b/src/test/run-pass/deref-lval.rs @@ -10,4 +10,10 @@ #[feature(managed_boxes)]; -pub fn main() { let x = @mut 5; *x = 1000; info!("{:?}", *x); } +use std::cell::Cell; + +pub fn main() { + let x = @Cell::new(5); + x.set(1000); + info!("{:?}", x.get()); +} diff --git a/src/test/run-pass/deriving-encodable-decodable.rs b/src/test/run-pass/deriving-encodable-decodable.rs index 4f4e9c9ce00b7..9194304a376b1 100644 --- a/src/test/run-pass/deriving-encodable-decodable.rs +++ b/src/test/run-pass/deriving-encodable-decodable.rs @@ -58,8 +58,8 @@ struct G { fn roundtrip<'a, T: Rand + Eq + Encodable + Decodable>>() { let obj: T = random(); - let w = @mut MemWriter::new(); - let mut e = Encoder(w); + let mut w = MemWriter::new(); + let mut e = Encoder(&mut w); obj.encode(&mut e); let doc = ebml::reader::Doc(@w.inner_ref().to_owned()); let mut dec = Decoder(doc); diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs index 0cff8e8a3f877..d28e54d57ad4c 100644 --- a/src/test/run-pass/deriving-zero.rs +++ b/src/test/run-pass/deriving-zero.rs @@ -30,7 +30,7 @@ struct Lots { e: char, f: f64, g: (f32, char), - h: @mut (int, int), + h: @(int, int), i: bool, j: (), } diff --git a/src/test/run-pass/explicit-self-closures.rs b/src/test/run-pass/explicit-self-closures.rs index ce662bafd4957..c7e5681c0c1db 100644 --- a/src/test/run-pass/explicit-self-closures.rs +++ b/src/test/run-pass/explicit-self-closures.rs @@ -18,9 +18,6 @@ impl Box { pub fn set_many(&mut self, xs: &[uint]) { for x in xs.iter() { self.x = *x; } } - pub fn set_many2(@mut self, xs: &[uint]) { - for x in xs.iter() { self.x = *x; } - } } pub fn main() {} diff --git a/src/test/run-pass/expr-repeat-vstore.rs b/src/test/run-pass/expr-repeat-vstore.rs index 2831740deaf47..e1be481099c18 100644 --- a/src/test/run-pass/expr-repeat-vstore.rs +++ b/src/test/run-pass/expr-repeat-vstore.rs @@ -13,10 +13,4 @@ pub fn main() { println(v[2].to_str()); println(v[3].to_str()); println(v[4].to_str()); - let v: @mut [int] = @mut [ 3, ..5 ]; - println((v[0]).to_str()); - println((v[1]).to_str()); - println((v[2]).to_str()); - println((v[3]).to_str()); - println((v[4]).to_str()); } diff --git a/src/test/run-pass/exterior.rs b/src/test/run-pass/exterior.rs index 27f30fb8ba9ed..d9505e01de95b 100644 --- a/src/test/run-pass/exterior.rs +++ b/src/test/run-pass/exterior.rs @@ -10,15 +10,21 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + struct Point {x: int, y: int, z: int} -fn f(p: @mut Point) { assert!((p.z == 12)); p.z = 13; assert!((p.z == 13)); } +fn f(p: @Cell) { + assert!((p.get().z == 12)); + p.set(Point {x: 10, y: 11, z: 13}); + assert!((p.get().z == 13)); +} pub fn main() { let a: Point = Point {x: 10, y: 11, z: 12}; - let b: @mut Point = @mut a; - assert_eq!(b.z, 12); + let b: @Cell = @Cell::new(a); + assert_eq!(b.get().z, 12); f(b); assert_eq!(a.z, 12); - assert_eq!(b.z, 13); + assert_eq!(b.get().z, 13); } diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 49aa8d18e90ec..905fa42635b9b 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -40,7 +40,7 @@ mod map_reduce { } fn map_task(ctrl: SharedChan, input: ~str) { - let intermediates = @mut HashMap::new(); + let mut intermediates = HashMap::new(); fn emit(im: &mut HashMap<~str, int>, ctrl: SharedChan, key: ~str, @@ -58,7 +58,7 @@ mod map_reduce { } let ctrl_clone = ctrl.clone(); - ::map(input, |a,b| emit(intermediates, ctrl.clone(), a, b) ); + ::map(input, |a,b| emit(&mut intermediates, ctrl.clone(), a, b) ); ctrl_clone.send(mapper_done); } diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/run-pass/init-res-into-things.rs index 5181ec6f71d6b..ede67275ba9d7 100644 --- a/src/test/run-pass/init-res-into-things.rs +++ b/src/test/run-pass/init-res-into-things.rs @@ -10,11 +10,13 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + // Resources can't be copied, but storing into data structures counts // as a move unless the stored thing is used afterwards. struct r { - i: @mut int, + i: @Cell, } struct Box { x: r } @@ -22,30 +24,30 @@ struct Box { x: r } #[unsafe_destructor] impl Drop for r { fn drop(&mut self) { - *(self.i) = *(self.i) + 1; + self.i.set(self.i.get() + 1) } } -fn r(i: @mut int) -> r { +fn r(i: @Cell) -> r { r { i: i } } fn test_box() { - let i = @mut 0; + let i = @Cell::new(0); { let _a = @r(i); } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } fn test_rec() { - let i = @mut 0; + let i = @Cell::new(0); { let _a = Box {x: r(i)}; } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } fn test_tag() { @@ -53,37 +55,37 @@ fn test_tag() { t0(r), } - let i = @mut 0; + let i = @Cell::new(0); { let _a = t0(r(i)); } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } fn test_tup() { - let i = @mut 0; + let i = @Cell::new(0); { let _a = (r(i), 0); } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } fn test_unique() { - let i = @mut 0; + let i = @Cell::new(0); { let _a = ~r(i); } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } fn test_box_rec() { - let i = @mut 0; + let i = @Cell::new(0); { let _a = @Box { x: r(i) }; } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } pub fn main() { diff --git a/src/test/run-pass/issue-2631-b.rs b/src/test/run-pass/issue-2631-b.rs index bc76fa74dbdee..dc46bef4ed46c 100644 --- a/src/test/run-pass/issue-2631-b.rs +++ b/src/test/run-pass/issue-2631-b.rs @@ -16,11 +16,12 @@ extern mod req; use req::request; +use std::cell::RefCell; use std::hashmap::HashMap; pub fn main() { let v = ~[@~"hi"]; let mut m: req::header_map = HashMap::new(); - m.insert(~"METHOD", @mut v); + m.insert(~"METHOD", @RefCell::new(v)); request::(&m); } diff --git a/src/test/run-pass/issue-2735-2.rs b/src/test/run-pass/issue-2735-2.rs index 85b6e80be7cf2..44222315dcd09 100644 --- a/src/test/run-pass/issue-2735-2.rs +++ b/src/test/run-pass/issue-2735-2.rs @@ -10,26 +10,28 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + // This test should behave exactly like issue-2735-3 struct defer { - b: @mut bool, + b: @Cell, } #[unsafe_destructor] impl Drop for defer { fn drop(&mut self) { - *self.b = true; + self.b.set(true); } } -fn defer(b: @mut bool) -> defer { +fn defer(b: @Cell) -> defer { defer { b: b } } pub fn main() { - let dtor_ran = @mut false; + let dtor_ran = @Cell::new(false); let _ = defer(dtor_ran); - assert!(*dtor_ran); + assert!(dtor_ran.get()); } diff --git a/src/test/run-pass/issue-2735-3.rs b/src/test/run-pass/issue-2735-3.rs index 401a43f8b2552..f48e763966b1a 100644 --- a/src/test/run-pass/issue-2735-3.rs +++ b/src/test/run-pass/issue-2735-3.rs @@ -10,26 +10,28 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + // This test should behave exactly like issue-2735-2 struct defer { - b: @mut bool, + b: @Cell, } #[unsafe_destructor] impl Drop for defer { fn drop(&mut self) { - *self.b = true; + self.b.set(true); } } -fn defer(b: @mut bool) -> defer { +fn defer(b: @Cell) -> defer { defer { b: b } } pub fn main() { - let dtor_ran = @mut false; + let dtor_ran = @Cell::new(false); defer(dtor_ran); - assert!(*dtor_ran); + assert!(dtor_ran.get()); } diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 5208995a0c7cf..dc2f59f14816c 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -62,8 +62,8 @@ fn square_from_char(c: char) -> square { } } -fn read_board_grid(input: rdr) -> ~[~[square]] { - let input = @mut input as @mut io::Reader; +fn read_board_grid(mut input: rdr) -> ~[~[square]] { + let mut input: &mut io::Reader = &mut input; let mut grid = ~[]; let mut line = [0, ..10]; input.read(line); diff --git a/src/test/run-pass/issue-3447.rs b/src/test/run-pass/issue-3447.rs index 7ae3e43c579ed..3d56abb3de686 100644 --- a/src/test/run-pass/issue-3447.rs +++ b/src/test/run-pass/issue-3447.rs @@ -10,11 +10,13 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + static S: &'static str = "str"; struct list { element: T, - next: Option<@mut list> + next: Option<@RefCell>> } impl list { @@ -24,7 +26,7 @@ impl list { next: None }; - self.next = Some(@mut newList); + self.next = Some(@RefCell::new(newList)); } } diff --git a/src/test/run-pass/issue-3860.rs b/src/test/run-pass/issue-3860.rs deleted file mode 100644 index 8a30cc9674860..0000000000000 --- a/src/test/run-pass/issue-3860.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -struct Foo { x: int } - -impl Foo { - pub fn stuff<'a>(&'a mut self) -> &'a mut Foo { - return self; - } -} - -pub fn main() { - let x = @mut Foo { x: 3 }; - // Neither of the next two lines should cause an error - let _ = x.stuff(); - x.stuff(); -} diff --git a/src/test/run-pass/issue-5275.rs b/src/test/run-pass/issue-5275.rs deleted file mode 100644 index 088376c1068b9..0000000000000 --- a/src/test/run-pass/issue-5275.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -// Regression test for issue #5275 - -fn foo(self_: &A) -> int { - if true { - fail!() - } else { - *bar(self_.bar) - } -} - -fn bar<'r>(_: &'r mut int) -> &'r int { - fail!() -} - -struct A { - bar: @mut int, -} - -pub fn main() {} diff --git a/src/test/run-pass/issue-5517.rs b/src/test/run-pass/issue-5517.rs deleted file mode 100644 index a5c318a20f47d..0000000000000 --- a/src/test/run-pass/issue-5517.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -pub fn main() { - let box1 = @mut 42; - let _x = *(&mut *box1) == 42 || *(&mut *box1) == 31337; -} diff --git a/src/test/run-pass/issue-979.rs b/src/test/run-pass/issue-979.rs index 08d8abc1d5081..ca83e783268e8 100644 --- a/src/test/run-pass/issue-979.rs +++ b/src/test/run-pass/issue-979.rs @@ -10,28 +10,30 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + struct r { - b: @mut int, + b: @Cell, } #[unsafe_destructor] impl Drop for r { fn drop(&mut self) { - *(self.b) += 1; + self.b.set(self.b.get() + 1); } } -fn r(b: @mut int) -> r { +fn r(b: @Cell) -> r { r { b: b } } pub fn main() { - let b = @mut 0; + let b = @Cell::new(0); { let _p = Some(r(b)); } - assert_eq!(*b, 1); + assert_eq!(b.get(), 1); } diff --git a/src/test/run-pass/issue-980.rs b/src/test/run-pass/issue-980.rs index 2f94dc776902a..f6dc4adcf9b5a 100644 --- a/src/test/run-pass/issue-980.rs +++ b/src/test/run-pass/issue-980.rs @@ -10,16 +10,20 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + enum maybe_pointy { no_pointy, - yes_pointy(@mut Pointy), + yes_pointy(@RefCell), } struct Pointy { - x : maybe_pointy + x: maybe_pointy } pub fn main() { - let m = @mut Pointy { x : no_pointy }; - m.x = yes_pointy(m); + let m = @RefCell::new(Pointy { x : no_pointy }); + m.set(Pointy { + x: yes_pointy(m) + }); } diff --git a/src/test/run-pass/lambda-infer-unresolved.rs b/src/test/run-pass/lambda-infer-unresolved.rs index a499c14802596..65f95f78ea86f 100644 --- a/src/test/run-pass/lambda-infer-unresolved.rs +++ b/src/test/run-pass/lambda-infer-unresolved.rs @@ -11,12 +11,10 @@ // This should typecheck even though the type of e is not fully // resolved when we finish typechecking the ||. -#[feature(managed_boxes)]; - struct Refs { refs: ~[int], n: int } pub fn main() { - let e = @mut Refs{refs: ~[], n: 0}; + let mut e = Refs{refs: ~[], n: 0}; let _f: || = || error!("{}", e.n); e.refs.push(1); } diff --git a/src/test/run-pass/log-linearized.rs b/src/test/run-pass/log-linearized.rs deleted file mode 100644 index e4dd3b56fca60..0000000000000 --- a/src/test/run-pass/log-linearized.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -// Tests that shapes respect linearize_ty_params(). - -enum option { - none, - some(T), -} - -struct Smallintmap {v: ~[option]} - -struct V { v: ~[option] } - -fn mk() -> @mut Smallintmap { - let v: ~[option] = ~[]; - return @mut Smallintmap {v: v}; -} - -fn f() { - let sim = mk::(); - error!("{:?}", sim); -} - -pub fn main() { - f::(); -} diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs index 6a88b804c22ee..fb352ea07085b 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/run-pass/logging-only-prints-once.rs @@ -11,25 +11,24 @@ // xfail-fast // exec-env:RUST_LOG=debug -#[feature(managed_boxes)]; - +use std::cell::Cell; use std::fmt; -struct Foo(@mut int); +struct Foo(Cell); impl fmt::Default for Foo { fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) { - assert!(***f == 0); - ***f = 1; + assert!(f.get() == 0); + f.set(1); } } pub fn main() { let (p,c) = Chan::new(); do spawn { - let f = Foo(@mut 0); + let mut f = Foo(Cell::new(0)); debug!("{}", f); - assert!(**f == 1); + assert!(f.get() == 1); c.send(()); } p.recv(); diff --git a/src/test/run-pass/mlist-cycle.rs b/src/test/run-pass/mlist-cycle.rs deleted file mode 100644 index 66e7fc4265b6c..0000000000000 --- a/src/test/run-pass/mlist-cycle.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-test -extern mod std; -use std::gc; -use std::gc::rustrt; - -struct cell {c: @list} - -enum list { link(@mut cell), nil, } - -pub fn main() { - let first: @cell = @mut cell{c: @nil()}; - let second: @cell = @mut cell{c: @link(first)}; - first._0 = @link(second); - rustrt::gc(); - let third: @cell = @mut cell{c: @nil()}; -} diff --git a/src/test/run-pass/new-vstore-mut-box-syntax.rs b/src/test/run-pass/new-vstore-mut-box-syntax.rs deleted file mode 100644 index 4a2756f5446eb..0000000000000 --- a/src/test/run-pass/new-vstore-mut-box-syntax.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -pub fn main() { - let _x: @mut [int] = @mut [ 1, 2, 3 ]; - -} diff --git a/src/test/run-pass/newtype-struct-drop-run.rs b/src/test/run-pass/newtype-struct-drop-run.rs index 8d1333941f7f2..f190a5102d2b4 100644 --- a/src/test/run-pass/newtype-struct-drop-run.rs +++ b/src/test/run-pass/newtype-struct-drop-run.rs @@ -12,19 +12,21 @@ // Make sure the destructor is run for newtype structs. -struct Foo(@mut int); +use std::cell::Cell; + +struct Foo(@Cell); #[unsafe_destructor] impl Drop for Foo { fn drop(&mut self) { - ***self = 23; + self.set(23); } } pub fn main() { - let y = @mut 32; + let y = @Cell::new(32); { let _x = Foo(y); } - assert_eq!(*y, 23); + assert_eq!(y.get(), 23); } diff --git a/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs b/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs index f0955ab8efa26..52792c8c42793 100644 --- a/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs +++ b/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs @@ -14,24 +14,12 @@ trait Foo { fn foo(&self) -> uint; - fn bar(&mut self) -> uint; } impl Foo for uint { fn foo(&self) -> uint { *self } - - fn bar(&mut self) -> uint { - *self += 1; - *self - } -} - -fn do_it_mut(obj: &mut Foo) { - let x = obj.bar(); - let y = obj.foo(); - assert_eq!(x, y); } fn do_it_imm(obj: &Foo, v: uint) { @@ -40,7 +28,6 @@ fn do_it_imm(obj: &Foo, v: uint) { } pub fn main() { - let x = @mut 22u as @mut Foo; - do_it_mut(x); - do_it_imm(x, 23u); + let x = @22u as @Foo; + do_it_imm(x, 22u); } diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs index ab9d5b9d2bff4..0806bcd185e4f 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/run-pass/option-unwrap.rs @@ -10,16 +10,17 @@ #[feature(managed_boxes)]; -struct dtor { - x: @mut int, +use std::cell::Cell; +struct dtor { + x: @Cell, } #[unsafe_destructor] impl Drop for dtor { fn drop(&mut self) { // abuse access to shared mutable state to write this code - *self.x -= 1; + self.x.set(self.x.get() - 1); } } @@ -31,12 +32,12 @@ fn unwrap(o: Option) -> T { } pub fn main() { - let x = @mut 1; + let x = @Cell::new(1); { let b = Some(dtor { x:x }); let _c = unwrap(b); } - assert_eq!(*x, 0); + assert_eq!(x.get(), 0); } diff --git a/src/test/run-pass/packed-struct-generic-size.rs b/src/test/run-pass/packed-struct-generic-size.rs index 1d3d8cf736f4d..cba923ef646f8 100644 --- a/src/test/run-pass/packed-struct-generic-size.rs +++ b/src/test/run-pass/packed-struct-generic-size.rs @@ -22,6 +22,6 @@ pub fn main() { assert_eq!(mem::size_of::>(), 11); - assert_eq!(mem::size_of::>(), - 1 + mem::size_of::<~str>() + mem::size_of::<@mut [int]>()); + assert_eq!(mem::size_of::>(), + 1 + mem::size_of::<~str>() + mem::size_of::<@[int]>()); } diff --git a/src/test/run-pass/packed-struct-size.rs b/src/test/run-pass/packed-struct-size.rs index c6550f24d5ccd..f694cc98ad350 100644 --- a/src/test/run-pass/packed-struct-size.rs +++ b/src/test/run-pass/packed-struct-size.rs @@ -49,7 +49,7 @@ struct S7_Option { a: f32, b: u8, c: u16, - d: Option<@mut f64> + d: Option<@f64> } // Placing packed structs in statics should work @@ -63,5 +63,5 @@ pub fn main() { assert_eq!(mem::size_of::(), 5); assert_eq!(mem::size_of::(), 13 + mem::size_of::<~str>()); assert_eq!(mem::size_of::(), 3 + mem::size_of::()); - assert_eq!(mem::size_of::(), 7 + mem::size_of::>()); + assert_eq!(mem::size_of::(), 7 + mem::size_of::>()); } diff --git a/src/test/run-pass/packed-tuple-struct-size.rs b/src/test/run-pass/packed-tuple-struct-size.rs index ad83de6ef4882..7d2be73edc398 100644 --- a/src/test/run-pass/packed-tuple-struct-size.rs +++ b/src/test/run-pass/packed-tuple-struct-size.rs @@ -30,7 +30,7 @@ enum Foo { struct S3_Foo(u8, u16, Foo); #[packed] -struct S7_Option(f32, u8, u16, Option<@mut f64>); +struct S7_Option(f32, u8, u16, Option<@f64>); pub fn main() { assert_eq!(mem::size_of::(), 4); @@ -44,5 +44,5 @@ pub fn main() { 3 + mem::size_of::()); assert_eq!(mem::size_of::(), - 7 + mem::size_of::>()); + 7 + mem::size_of::>()); } diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/run-pass/rcvr-borrowed-to-region.rs index d6d015d478588..8c1be0a621975 100644 --- a/src/test/run-pass/rcvr-borrowed-to-region.rs +++ b/src/test/run-pass/rcvr-borrowed-to-region.rs @@ -24,7 +24,7 @@ impl<'a> get for &'a int { } pub fn main() { - let x = @mut 6; + let x = @6; let y = x.get(); assert_eq!(y, 6); diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 6e5aa1aaf8b69..0d4277d2e1d63 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -12,6 +12,7 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; use std::libc::c_void; use std::ptr; use std::mem; @@ -458,8 +459,9 @@ impl TyVisitor for ptr_visit_adaptor { } } -struct my_visitor(@mut Stuff); +struct my_visitor(@RefCell); +#[deriving(Clone)] struct Stuff { ptr1: *c_void, ptr2: *c_void, @@ -469,7 +471,7 @@ struct Stuff { impl my_visitor { pub fn get(&mut self, f: |T|) { unsafe { - f((*(self.ptr1 as *T)).clone()); + f((*((**self).get().ptr1 as *T)).clone()); } } @@ -487,8 +489,9 @@ struct Inner { inner: V } impl movable_ptr for my_visitor { fn move_ptr(&mut self, adjustment: |*c_void| -> *c_void) { - self.ptr1 = adjustment(self.ptr1); - self.ptr2 = adjustment(self.ptr2); + let mut this = self.borrow_mut(); + this.get().ptr1 = adjustment(this.get().ptr1); + this.get().ptr2 = adjustment(this.get().ptr2); } } @@ -497,11 +500,17 @@ impl TyVisitor for my_visitor { fn visit_bot(&mut self) -> bool { true } fn visit_nil(&mut self) -> bool { true } fn visit_bool(&mut self) -> bool { - self.get::(|b| self.vals.push(b.to_str())); + self.get::(|b| { + let mut this = self.borrow_mut(); + this.get().vals.push(b.to_str()); + }); true } fn visit_int(&mut self) -> bool { - self.get::(|i| self.vals.push(i.to_str())); + self.get::(|i| { + let mut this = self.borrow_mut(); + this.get().vals.push(i.to_str()); + }); true } fn visit_i8(&mut self) -> bool { true } @@ -622,21 +631,22 @@ pub fn main() { unsafe { let r = (1,2,3,true,false, Triple {x:5,y:4,z:3}, (12,)); let p = ptr::to_unsafe_ptr(&r) as *c_void; - let u = my_visitor(@mut Stuff {ptr1: p, - ptr2: p, - vals: ~[]}); + let u = my_visitor(@RefCell::new(Stuff {ptr1: p, + ptr2: p, + vals: ~[]})); let mut v = ptr_visit_adaptor(Inner {inner: u}); let td = get_tydesc_for(r); error!("tydesc sz: {}, align: {}", (*td).size, (*td).align); visit_tydesc(td, &mut v as &mut TyVisitor); - let r = u.vals.clone(); + let mut ub = u.borrow_mut(); + let r = ub.get().vals.clone(); for s in r.iter() { println!("val: {}", *s); } - error!("{:?}", u.vals.clone()); - assert_eq!(u.vals.clone(), + error!("{:?}", ub.get().vals.clone()); + assert_eq!(ub.get().vals.clone(), ~[ ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"]); } } diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 03722cd0fbf2c..5acb072fd2d37 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -13,7 +13,7 @@ use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Disr, Opaque}; struct MyVisitor { - types: @mut ~[~str], + types: ~[~str], } impl TyVisitor for MyVisitor { @@ -153,7 +153,7 @@ fn visit_ty(v: &mut MyVisitor) { } pub fn main() { - let mut v = MyVisitor {types: @mut ~[]}; + let mut v = MyVisitor {types: ~[]}; visit_ty::(&mut v); visit_ty::(&mut v); @@ -164,5 +164,5 @@ pub fn main() { for s in v.types.iter() { println!("type: {}", (*s).clone()); } - assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); + assert_eq!(v.types.clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); } diff --git a/src/test/run-pass/resource-assign-is-not-copy.rs b/src/test/run-pass/resource-assign-is-not-copy.rs index 3025032fec1b8..bec101a6d45a9 100644 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ b/src/test/run-pass/resource-assign-is-not-copy.rs @@ -10,25 +10,27 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + struct r { - i: @mut int, + i: @Cell, } #[unsafe_destructor] impl Drop for r { fn drop(&mut self) { - *(self.i) += 1; + self.i.set(self.i.get() + 1); } } -fn r(i: @mut int) -> r { +fn r(i: @Cell) -> r { r { i: i } } pub fn main() { - let i = @mut 0; + let i = @Cell::new(0); // Even though these look like copies, they are guaranteed not to be { let a = r(i); @@ -36,5 +38,5 @@ pub fn main() { let (c, _d) = b; info!("{:?}", c); } - assert_eq!(*i, 1); + assert_eq!(i.get(), 1); } diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs deleted file mode 100644 index 898f6327aeb17..0000000000000 --- a/src/test/run-pass/resource-cycle.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -// Don't leak the unique pointers - -use std::cast; - -struct r { - v: *int, -} - -impl Drop for r { - fn drop(&mut self) { - unsafe { - info!("r's dtor: self = {:x}, self.v = {:x}, self.v's value = {:x}", - cast::transmute::<*mut r, uint>(self), - cast::transmute::<**int, uint>(&(self.v)), - cast::transmute::<*int, uint>(self.v)); - let _v2: ~int = cast::transmute(self.v); - } - } -} - -fn r(v: *int) -> r { - r { - v: v - } -} - -struct t(Node); - -struct Node { - next: Option<@mut t>, - r: r -} - -pub fn main() { - unsafe { - let i1 = ~0; - let i1p = cast::transmute_copy(&i1); - cast::forget(i1); - let i2 = ~0; - let i2p = cast::transmute_copy(&i2); - cast::forget(i2); - - let x1 = @mut t(Node{ - next: None, - r: { - let rs = r(i1p); - info!("r = {:x}", cast::transmute::<*r, uint>(&rs)); - rs } - }); - - info!("x1 = {:x}, x1.r = {:x}", - cast::transmute::<@mut t, uint>(x1), - cast::transmute::<*r, uint>(&x1.r)); - - let x2 = @mut t(Node{ - next: None, - r: { - let rs = r(i2p); - info!("r2 = {:x}", cast::transmute::<*r, uint>(&rs)); - rs - } - }); - - info!("x2 = {:x}, x2.r = {:x}", - cast::transmute::<@mut t, uint>(x2), - cast::transmute::<*r, uint>(&(x2.r))); - - x1.next = Some(x2); - x2.next = Some(x1); - } -} diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs deleted file mode 100644 index c7ad9711ed45d..0000000000000 --- a/src/test/run-pass/resource-cycle2.rs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -// Don't leak the unique pointers - -use std::cast; - -struct U { - a: int, - b: int, - c: *int -} - -struct r { - v: U, -} - -impl Drop for r { - fn drop(&mut self) { - unsafe { - let _v2: ~int = cast::transmute(self.v.c); - } - } -} - -fn r(v: U) -> r { - r { - v: v - } -} - -struct t(Node); - -struct Node { - next: Option<@mut t>, - r: r -} - -pub fn main() { - unsafe { - let i1 = ~0xA; - let i1p = cast::transmute_copy(&i1); - cast::forget(i1); - let i2 = ~0xA; - let i2p = cast::transmute_copy(&i2); - cast::forget(i2); - - let u1 = U {a: 0xB, b: 0xC, c: i1p}; - let u2 = U {a: 0xB, b: 0xC, c: i2p}; - - let x1 = @mut t(Node { - next: None, - r: r(u1) - }); - let x2 = @mut t(Node { - next: None, - r: r(u2) - }); - x1.next = Some(x2); - x2.next = Some(x1); - } -} diff --git a/src/test/run-pass/resource-cycle3.rs b/src/test/run-pass/resource-cycle3.rs deleted file mode 100644 index 8d11eca44922d..0000000000000 --- a/src/test/run-pass/resource-cycle3.rs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -// same as resource-cycle2, but be sure to give r multiple fields... - -// Don't leak the unique pointers - -use std::cast; - -struct U { - a: int, - b: int, - c: *int -} - -struct R { - v: U, - w: int, - x: *int, -} - -impl Drop for R { - fn drop(&mut self) { - unsafe { - let _v2: ~int = cast::transmute(self.v.c); - // let _v3: ~int = cast::transmute_copy(self.x); - } - } -} - -fn r(v: U, w: int, _x: *int) -> R { - unsafe { - R { - v: v, - w: w, - x: cast::transmute(0) - } - } -} - -struct t(Node); - -struct Node { - next: Option<@mut t>, - r: R -} - -pub fn main() { - unsafe { - let i1 = ~0xA; - let i1p = cast::transmute_copy(&i1); - cast::forget(i1); - let i2 = ~0xA; - let i2p = cast::transmute_copy(&i2); - cast::forget(i2); - - let u1 = U {a: 0xB, b: 0xC, c: i1p}; - let u2 = U {a: 0xB, b: 0xC, c: i2p}; - - let x1 = @mut t(Node{ - next: None, - r: r(u1, 42, i1p) - }); - let x2 = @mut t(Node{ - next: None, - r: r(u2, 42, i2p) - }); - x1.next = Some(x2); - x2.next = Some(x1); - } -} diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs index d85759dff192a..93183f8dba475 100644 --- a/src/test/run-pass/resource-destruct.rs +++ b/src/test/run-pass/resource-destruct.rs @@ -10,30 +10,32 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + struct shrinky_pointer { - i: @@mut int, + i: @@Cell, } #[unsafe_destructor] impl Drop for shrinky_pointer { fn drop(&mut self) { - error!("Hello!"); **(self.i) -= 1; + error!("Hello!"); self.i.set(self.i.get() - 1); } } impl shrinky_pointer { - pub fn look_at(&self) -> int { return **(self.i); } + pub fn look_at(&self) -> int { return self.i.get(); } } -fn shrinky_pointer(i: @@mut int) -> shrinky_pointer { +fn shrinky_pointer(i: @@Cell) -> shrinky_pointer { shrinky_pointer { i: i } } pub fn main() { - let my_total = @@mut 10; + let my_total = @@Cell::new(10); { let pt = shrinky_pointer(my_total); assert!((pt.look_at() == 10)); } - error!("my_total = {}", **my_total); - assert_eq!(**my_total, 9); + error!("my_total = {}", my_total.get()); + assert_eq!(my_total.get(), 9); } diff --git a/src/test/run-pass/resource-in-struct.rs b/src/test/run-pass/resource-in-struct.rs index c76a9659c26da..1c5ad9ce525df 100644 --- a/src/test/run-pass/resource-in-struct.rs +++ b/src/test/run-pass/resource-in-struct.rs @@ -13,7 +13,9 @@ // Ensures that class dtors run if the object is inside an enum // variant -type closable = @mut bool; +use std::cell::Cell; + +type closable = @Cell; struct close_res { i: closable, @@ -23,7 +25,7 @@ struct close_res { #[unsafe_destructor] impl Drop for close_res { fn drop(&mut self) { - *(self.i) = false; + self.i.set(false); } } @@ -38,8 +40,8 @@ enum option { none, some(T), } fn sink(_res: option) { } pub fn main() { - let c = @mut true; + let c = @Cell::new(true); sink(none); sink(some(close_res(c))); - assert!((!*c)); + assert!(!c.get()); } diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index a490cc6020fda..16e9cb538919c 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -13,12 +13,14 @@ // A port of task-killjoin to use a class with a dtor to manage // the join. +use std::cell::Cell; use std::comm::*; use std::ptr; use std::task; struct notify { - ch: Chan, v: @mut bool, + ch: Chan, + v: @Cell, } #[unsafe_destructor] @@ -36,7 +38,7 @@ impl Drop for notify { } } -fn notify(ch: Chan, v: @mut bool) -> notify { +fn notify(ch: Chan, v: @Cell) -> notify { notify { ch: ch, v: v @@ -45,10 +47,10 @@ fn notify(ch: Chan, v: @mut bool) -> notify { fn joinable(f: proc()) -> Port { fn wrapper(c: Chan, f: ||) { - let b = @mut false; + let b = @Cell::new(false); error!("wrapper: task=%? allocated v=%x", 0, - ptr::to_unsafe_ptr(&(*b)) as uint); + ptr::to_unsafe_ptr(&b) as uint); let _r = notify(c, b); f(); *b = true; diff --git a/src/test/run-pass/trait-cast.rs b/src/test/run-pass/trait-cast.rs index e5d9160899765..bf8b0b5522dca 100644 --- a/src/test/run-pass/trait-cast.rs +++ b/src/test/run-pass/trait-cast.rs @@ -12,7 +12,9 @@ // Test cyclic detector when using trait instances. -struct Tree(@mut TreeR); +use std::cell::RefCell; + +struct Tree(@RefCell); struct TreeR { left: Option, right: Option, @@ -38,8 +40,9 @@ impl to_str for int { impl to_str for Tree { fn to_str_(&self) -> ~str { - let (l, r) = (self.left, self.right); - let val = &self.val; + let this = self.borrow(); + let (l, r) = (this.get().left, this.get().right); + let val = &this.get().val; format!("[{}, {}, {}]", val.to_str_(), l.to_str_(), r.to_str_()) } } @@ -47,14 +50,18 @@ impl to_str for Tree { fn foo(x: T) -> ~str { x.to_str_() } pub fn main() { - let t1 = Tree(@mut TreeR{left: None, - right: None, - val: ~1 as ~to_str }); - let t2 = Tree(@mut TreeR{left: Some(t1), - right: Some(t1), - val: ~2 as ~to_str }); + let t1 = Tree(@RefCell::new(TreeR{left: None, + right: None, + val: ~1 as ~to_str})); + let t2 = Tree(@RefCell::new(TreeR{left: Some(t1), + right: Some(t1), + val: ~2 as ~to_str})); let expected = ~"[2, some([1, none, none]), some([1, none, none])]"; assert!(t2.to_str_() == expected); assert!(foo(t2) == expected); - t1.left = Some(t2); // create cycle + + { + let mut t1 = t1.borrow_mut(); + t1.get().left = Some(t2); // create cycle + } } diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs index ebf3da60db8f3..53836a6e17dfb 100644 --- a/src/test/run-pass/uniq-cc-generic.rs +++ b/src/test/run-pass/uniq-cc-generic.rs @@ -10,11 +10,12 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; use std::ptr; enum maybe_pointy { none, - p(@mut Pointy), + p(@RefCell), } struct Pointy { @@ -27,14 +28,17 @@ fn make_uniq_closure(a: A) -> proc() -> uint { result } -fn empty_pointy() -> @mut Pointy { - return @mut Pointy { +fn empty_pointy() -> @RefCell { + return @RefCell::new(Pointy { a : none, d : make_uniq_closure(~"hi") - } + }) } pub fn main() { let v = empty_pointy(); - v.a = p(v); + { + let mut vb = v.borrow_mut(); + vb.get().a = p(v); + } } diff --git a/src/test/run-pass/uniq-cc.rs b/src/test/run-pass/uniq-cc.rs index 20b5761e6bdb6..23a27dece46f1 100644 --- a/src/test/run-pass/uniq-cc.rs +++ b/src/test/run-pass/uniq-cc.rs @@ -10,9 +10,11 @@ #[feature(managed_boxes)]; +use std::cell::RefCell; + enum maybe_pointy { none, - p(@mut Pointy), + p(@RefCell), } struct Pointy { @@ -21,15 +23,18 @@ struct Pointy { d : proc()->(), } -fn empty_pointy() -> @mut Pointy { - return @mut Pointy { +fn empty_pointy() -> @RefCell { + return @RefCell::new(Pointy { a : none, c : ~22, d : proc() {}, - } + }) } pub fn main() { let v = empty_pointy(); - v.a = p(v); + { + let mut vb = v.borrow_mut(); + vb.get().a = p(v); + } } diff --git a/src/test/run-pass/unique-pinned-nocopy-2.rs b/src/test/run-pass/unique-pinned-nocopy-2.rs deleted file mode 100644 index a7c326ba11c42..0000000000000 --- a/src/test/run-pass/unique-pinned-nocopy-2.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[feature(managed_boxes)]; - -struct r { - i: @mut int, -} - -#[unsafe_destructor] -impl Drop for r { - fn drop(&mut self) { - *(self.i) = *(self.i) + 1; - } -} - -fn r(i: @mut int) -> r { - r { - i: i - } -} - -pub fn main() { - let i = @mut 0; - { - let _j = ~r(i); - } - assert_eq!(*i, 1); -} diff --git a/src/test/run-pass/vec-slice-drop.rs b/src/test/run-pass/vec-slice-drop.rs index c8493f0cb154b..f8e28dc792cfd 100644 --- a/src/test/run-pass/vec-slice-drop.rs +++ b/src/test/run-pass/vec-slice-drop.rs @@ -10,29 +10,31 @@ #[feature(managed_boxes)]; +use std::cell::Cell; + // Make sure that destructors get run on slice literals struct foo { - x: @mut int, + x: @Cell, } #[unsafe_destructor] impl Drop for foo { fn drop(&mut self) { - *self.x += 1; + self.x.set(self.x.get() + 1); } } -fn foo(x: @mut int) -> foo { +fn foo(x: @Cell) -> foo { foo { x: x } } pub fn main() { - let x = @mut 0; + let x = @Cell::new(0); { let l = &[foo(x)]; - assert_eq!(*l[0].x, 0); + assert_eq!(l[0].x.get(), 0); } - assert_eq!(*x, 1); + assert_eq!(x.get(), 1); } diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index 70803c9bd55d0..f62ab6f59a062 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -10,6 +10,7 @@ #[feature(managed_boxes)]; +use std::cell::Cell; use std::util; // Just a grab bag of stuff that you wouldn't want to actually write. @@ -22,11 +23,13 @@ fn funny() { } fn what() { - fn the(x: @mut bool) { return while !*x { *x = true; }; } - let i = @mut false; + fn the(x: @Cell) { + return while !x.get() { x.set(true); }; + } + let i = @Cell::new(false); let dont = {||the(i)}; dont(); - assert!((*i)); + assert!((i.get())); } fn zombiejesus() {