auto merge of #11251 : pcwalton/rust/remove-at-mut, r=pcwalton

r? @nikomatsakis 

for the borrow checker changes. Write guards are now eliminated.
This commit is contained in:
bors 2014-01-03 22:36:53 -08:00
commit 3dd7c49faf
277 changed files with 2431 additions and 3477 deletions

View File

@ -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<T>`][refcell].
`Freeze` objects have freezing enforced statically at compile-time. An example
of a non-`Freeze` type is [`RefCell<T>`][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,13 +1463,12 @@ 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;
let borrowed = &mut value;
*managed = *owned + 10;
*owned = *borrowed + 100;
*borrowed = *managed + 1000;
~~~
@ -2113,8 +2098,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

View File

@ -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<uint>,
is_pod: Cell<bool>,
}
#[no_freeze]
@ -63,7 +66,7 @@ pub struct Arena {
// access the head.
priv head: Chunk,
priv pod_head: Chunk,
priv chunks: @mut MutList<Chunk>,
priv chunks: RefCell<@List<Chunk>>,
}
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));
}
}

View File

@ -19,13 +19,6 @@ pub enum List<T> {
Nil,
}
#[deriving(Eq)]
#[allow(missing_doc)]
pub enum MutList<T> {
MutCons(T, @mut MutList<T>),
MutNil,
}
/// Create a list from a vector
pub fn from_vec<T:Clone + 'static>(v: &[T]) -> @List<T> {
v.rev_iter().fold(@Nil::<T>, |t, h| @Cons((*h).clone(), t))
@ -158,26 +151,6 @@ pub fn each<T>(l: @List<T>, f: |&T| -> bool) -> bool {
}
}
impl<T> MutList<T> {
/// 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::*;

View File

@ -426,18 +426,6 @@ impl<D:Decoder,T:Decodable<D> + 'static> Decodable<D> for @T {
}
}
impl<S:Encoder,T:Encodable<S>> Encodable<S> for @mut T {
fn encode(&self, s: &mut S) {
(**self).encode(s)
}
}
impl<D:Decoder,T:Decodable<D> + 'static> Decodable<D> for @mut T {
fn decode(d: &mut D) -> @mut T {
@mut Decodable::decode(d)
}
}
impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a [T] {
fn encode(&self, s: &mut S) {
s.emit_seq(self.len(), |s| {

View File

@ -113,7 +113,8 @@ impl<T: Writer> Terminal<T> {
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());
}

View File

@ -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<File, ~str> {
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))
}
}

View File

@ -949,7 +949,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

View File

@ -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);

View File

@ -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);
}
}
}
}
}

View File

@ -295,7 +295,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
middle::liveness::check_crate(ty_cx, method_map,
capture_map, crate));
let (root_map, write_guard_map) =
let root_map =
time(time_passes, "borrow checking", (), |_|
middle::borrowck::check_crate(ty_cx, method_map,
moves_map, moved_variables_set,
@ -330,7 +330,6 @@ pub fn phase_3_run_analysis_passes(sess: Session,
root_map: root_map,
method_map: method_map,
vtable_map: vtable_map,
write_guard_map: write_guard_map,
capture_map: capture_map
},
reachable: reachable_map
@ -464,9 +463,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 +526,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 +561,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 +601,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 +892,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::SpanHandler)
span_diagnostic_handler: @diagnostic::SpanHandler)
-> Session {
let target_cfg = build_target_config(sopts, demitter);
let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler,

View File

@ -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<Option<(NodeId, codemap::Span)>>,
entry_type: Cell<Option<EntryFnType>>,
span_diagnostic: @mut diagnostic::SpanHandler,
span_diagnostic: @diagnostic::SpanHandler,
filesearch: @filesearch::FileSearch,
building_library: Cell<bool>,
working_dir: Path,
@ -292,7 +292,7 @@ impl Session_ {
v
}
pub fn diagnostic(&self) -> @mut diagnostic::SpanHandler {
pub fn diagnostic(&self) -> @diagnostic::SpanHandler {
self.span_diagnostic
}
pub fn debugging_opt(&self, opt: uint) -> bool {

View File

@ -189,9 +189,8 @@ impl Visitor<()> for Context {
fn visit_expr(&mut self, e: @ast::Expr, _: ()) {
match e.node {
ast::ExprUnary(_, ast::UnBox(..), _) |
ast::ExprVstore(_, ast::ExprVstoreBox) |
ast::ExprVstore(_, ast::ExprVstoreMutBox) => {
ast::ExprUnary(_, ast::UnBox, _) |
ast::ExprVstore(_, ast::ExprVstoreBox) => {
self.gate_box(e.span);
}
_ => {}

View File

@ -86,7 +86,7 @@ fn dump_crates(crate_cache: &[cache_entry]) {
}
fn warn_if_multiple_versions(e: &mut Env,
diag: @mut SpanHandler,
diag: @SpanHandler,
crate_cache: &[cache_entry]) {
if crate_cache.len() != 0u {
let name = crate_cache[crate_cache.len() - 1].crateid.name.clone();

View File

@ -57,7 +57,7 @@ pub type encode_inlined_item<'a> = 'a |ecx: &EncodeContext,
ii: ast::inlined_item|;
pub struct EncodeParams<'a> {
diag: @mut SpanHandler,
diag: @SpanHandler,
tcx: ty::ctxt,
reexports2: middle::resolve::ExportMap2,
item_symbols: &'a RefCell<HashMap<ast::NodeId, ~str>>,
@ -83,7 +83,7 @@ struct Stats {
}
pub struct EncodeContext<'a> {
diag: @mut SpanHandler,
diag: @SpanHandler,
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<i64>]>) {
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<i64>]>) {
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(

View File

@ -231,8 +231,7 @@ impl Context {
}
}
pub fn note_crateid_attr(diag: @mut SpanHandler,
crateid: &CrateId) {
pub fn note_crateid_attr(diag: @SpanHandler, crateid: &CrateId) {
diag.handler().note(format!("crate_id: {}", crateid.to_str()));
}

View File

@ -342,7 +342,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
return ty::mk_self(st.tcx, did);
}
'@' => return ty::mk_box(st.tcx, parse_mt(st, |x,y| conv(x,y))),
'@' => return ty::mk_box(st.tcx, parse_ty(st, |x,y| conv(x,y))),
'~' => return ty::mk_uniq(st.tcx, parse_mt(st, |x,y| conv(x,y))),
'*' => return ty::mk_ptr(st.tcx, parse_mt(st, |x,y| conv(x,y))),
'&' => {

View File

@ -32,7 +32,7 @@ macro_rules! mywrite( ($wr:expr, $($arg:tt)*) => (
) )
pub struct ctxt {
diag: @mut SpanHandler,
diag: @SpanHandler,
// Def -> str Callback:
ds: extern "Rust" fn(DefId) -> ~str,
// The type context.
@ -292,7 +292,7 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) {
for t in ts.iter() { enc_ty(w, cx, *t); }
mywrite!(w, "]");
}
ty::ty_box(mt) => { mywrite!(w, "@"); enc_mt(w, cx, mt); }
ty::ty_box(typ) => { mywrite!(w, "@"); enc_ty(w, cx, typ); }
ty::ty_uniq(mt) => { mywrite!(w, "~"); enc_mt(w, cx, mt); }
ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
ty::ty_rptr(r, mt) => {

View File

@ -55,7 +55,6 @@ pub struct Maps {
root_map: middle::borrowck::root_map,
method_map: middle::typeck::method_map,
vtable_map: middle::typeck::vtable_map,
write_guard_map: middle::borrowck::write_guard_map,
capture_map: middle::moves::CaptureMap,
}
@ -1429,18 +1428,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),

View File

@ -368,11 +368,15 @@ impl<'a> CheckLoanCtxt<'a> {
cmt = b;
}
mc::cat_deref(_, _, mc::gc_ptr) => {
assert_eq!(cmt.mutbl, mc::McImmutable);
return;
}
mc::cat_rvalue(..) |
mc::cat_static_item |
mc::cat_copied_upvar(..) |
mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
mc::cat_deref(_, _, mc::gc_ptr(..)) |
mc::cat_deref(_, _, mc::region_ptr(..)) => {
assert_eq!(cmt.mutbl, mc::McDeclared);
return;
@ -411,20 +415,6 @@ impl<'a> CheckLoanCtxt<'a> {
check_for_aliasability_violation(this, expr, b);
}
mc::cat_deref(_, deref_count, mc::gc_ptr(ast::MutMutable)) => {
// Dynamically check writes to `@mut`
let key = root_map_key {
id: guarantor.id,
derefs: deref_count
};
debug!("Inserting write guard at {:?}", key);
let mut write_guard_map = this.bccx
.write_guard_map
.borrow_mut();
write_guard_map.get().insert(key);
}
_ => {}
}
@ -455,7 +445,7 @@ impl<'a> CheckLoanCtxt<'a> {
mc::cat_self(..) |
mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
mc::cat_static_item(..) |
mc::cat_deref(_, _, mc::gc_ptr(_)) |
mc::cat_deref(_, _, mc::gc_ptr) |
mc::cat_deref(_, _, mc::region_ptr(MutImmutable, _)) => {
// Aliasability is independent of base cmt
match cmt.freely_aliasable() {

View File

@ -102,7 +102,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
cmt: mc::cmt) -> bool {
match cmt.cat {
mc::cat_deref(_, _, mc::region_ptr(..)) |
mc::cat_deref(_, _, mc::gc_ptr(..)) |
mc::cat_deref(_, _, mc::gc_ptr) |
mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
mc::cat_stack_upvar(..) |
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {

View File

@ -16,10 +16,8 @@
use middle::borrowck::*;
use mc = middle::mem_categorization;
use middle::ty;
use syntax::ast::{MutImmutable, MutMutable};
use syntax::ast;
use syntax::codemap::Span;
use util::ppaux::{note_and_explain_region};
type R = Result<(),()>;
@ -89,12 +87,11 @@ impl<'a> GuaranteeLifetimeContext<'a> {
Ok(())
}
mc::cat_deref(base, derefs, mc::gc_ptr(ptr_mutbl)) => {
mc::cat_deref(base, derefs, mc::gc_ptr) => {
let base_scope = self.scope(base);
// L-Deref-Managed-Imm-User-Root
let omit_root = (
ptr_mutbl == MutImmutable &&
self.bccx.is_subregion_of(self.loan_region, base_scope) &&
self.is_rvalue_or_immutable(base) &&
!self.is_moved(base)
@ -103,7 +100,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
if !omit_root {
// L-Deref-Managed-Imm-Compiler-Root
// L-Deref-Managed-Mut-Compiler-Root
self.check_root(cmt, base, derefs, ptr_mutbl, discr_scope)
self.check_root(cmt, base, derefs, discr_scope)
} else {
debug!("omitting root, base={}, base_scope={:?}",
base.repr(self.tcx()), base_scope);
@ -192,14 +189,12 @@ impl<'a> GuaranteeLifetimeContext<'a> {
cmt_deref: mc::cmt,
cmt_base: mc::cmt,
derefs: uint,
ptr_mutbl: ast::Mutability,
discr_scope: Option<ast::NodeId>) -> R {
debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, ptr_mutbl={:?}, \
debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, \
discr_scope={:?})",
cmt_deref.repr(self.tcx()),
cmt_base.repr(self.tcx()),
derefs,
ptr_mutbl,
discr_scope);
// Make sure that the loan does not exceed the maximum time
@ -235,19 +230,6 @@ impl<'a> GuaranteeLifetimeContext<'a> {
}
};
// If we are borrowing the inside of an `@mut` box,
// we need to dynamically mark it to prevent incompatible
// borrows from happening later.
let opt_dyna = match ptr_mutbl {
MutImmutable => None,
MutMutable => {
match self.loan_mutbl {
MutableMutability => Some(DynaMut),
ImmutableMutability | ConstMutability => Some(DynaImm)
}
}
};
// FIXME(#3511) grow to the nearest cleanup scope---this can
// cause observable errors if freezing!
if !self.bccx.tcx.region_maps.is_cleanup_scope(root_scope) {
@ -256,29 +238,12 @@ impl<'a> GuaranteeLifetimeContext<'a> {
let cleanup_scope =
self.bccx.tcx.region_maps.cleanup_scope(root_scope);
if opt_dyna.is_some() {
self.tcx().sess.span_warn(
self.span,
format!("Dynamic freeze scope artifically extended \
(see Issue \\#6248)"));
note_and_explain_region(
self.bccx.tcx,
"managed value only needs to be frozen for ",
ty::ReScope(root_scope),
"...");
note_and_explain_region(
self.bccx.tcx,
"...but due to Issue #6248, it will be frozen for ",
ty::ReScope(cleanup_scope),
"");
}
root_scope = cleanup_scope;
}
// Add a record of what is required
let rm_key = root_map_key {id: cmt_deref.id, derefs: derefs};
let root_info = RootInfo {scope: root_scope, freeze: opt_dyna};
let root_info = RootInfo {scope: root_scope};
let mut root_map = self.bccx.root_map.borrow_mut();
root_map.get().insert(rm_key, root_info);
@ -357,7 +322,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
}
mc::cat_downcast(cmt) |
mc::cat_deref(cmt, _, mc::uniq_ptr) |
mc::cat_deref(cmt, _, mc::gc_ptr(..)) |
mc::cat_deref(cmt, _, mc::gc_ptr) |
mc::cat_interior(cmt, _) |
mc::cat_stack_upvar(cmt) |
mc::cat_discr(cmt, _) => {

View File

@ -132,59 +132,11 @@ impl<'a> RestrictionsContext<'a> {
Safe
}
mc::cat_deref(_, _, mc::gc_ptr(MutImmutable)) => {
mc::cat_deref(_, _, mc::gc_ptr) => {
// R-Deref-Imm-Managed
Safe
}
mc::cat_deref(cmt_base, _, pk @ mc::gc_ptr(MutMutable)) => {
// R-Deref-Managed-Borrowed
//
// Technically, no restrictions are *necessary* here.
// The validity of the borrow is guaranteed
// dynamically. However, nonetheless we add a
// restriction to make a "best effort" to report
// static errors. For example, if there is code like
//
// let v = @mut ~[1, 2, 3];
// for e in v.iter() {
// v.push(e + 1);
// }
//
// Then the code below would add restrictions on `*v`,
// which means that an error would be reported
// here. This of course is not perfect. For example,
// a function like the following would not report an error
// at compile-time but would fail dynamically:
//
// let v = @mut ~[1, 2, 3];
// let w = v;
// for e in v.iter() {
// w.push(e + 1);
// }
//
// In addition, we only add a restriction for those cases
// where we can construct a sensible loan path, so an
// example like the following will fail dynamically:
//
// impl V {
// fn get_list(&self) -> @mut ~[int];
// }
// ...
// let v: &V = ...;
// for e in v.get_list().iter() {
// v.get_list().push(e + 1);
// }
match opt_loan_path(cmt_base) {
None => Safe,
Some(lp_base) => {
let lp = @LpExtend(lp_base, cmt.mutbl, LpDeref(pk));
SafeIf(lp, ~[Restriction {loan_path: lp,
set: restrictions}])
}
}
}
mc::cat_deref(cmt_base, _, pk @ mc::region_ptr(MutMutable, lt)) => {
// R-Deref-Mut-Borrowed
if !self.bccx.is_subregion_of(self.loan_region, lt) {

View File

@ -20,7 +20,7 @@ use middle::dataflow::DataFlowOperator;
use util::ppaux::{note_and_explain_region, Repr, UserString};
use std::cell::{Cell, RefCell};
use std::hashmap::{HashSet, HashMap};
use std::hashmap::HashMap;
use std::ops::{BitOr, BitAnd};
use std::result::{Result};
use syntax::ast;
@ -67,14 +67,13 @@ impl Visitor<()> for BorrowckCtxt {
}
}
pub fn check_crate(
tcx: ty::ctxt,
method_map: typeck::method_map,
moves_map: moves::MovesMap,
moved_variables_set: moves::MovedVariablesSet,
capture_map: moves::CaptureMap,
crate: &ast::Crate) -> (root_map, write_guard_map)
{
pub fn check_crate(tcx: ty::ctxt,
method_map: typeck::method_map,
moves_map: moves::MovesMap,
moved_variables_set: moves::MovedVariablesSet,
capture_map: moves::CaptureMap,
crate: &ast::Crate)
-> root_map {
let mut bccx = BorrowckCtxt {
tcx: tcx,
method_map: method_map,
@ -82,7 +81,6 @@ pub fn check_crate(
moved_variables_set: moved_variables_set,
capture_map: capture_map,
root_map: root_map(),
write_guard_map: @RefCell::new(HashSet::new()),
stats: @BorrowStats {
loaned_paths_same: Cell::new(0),
loaned_paths_imm: Cell::new(0),
@ -106,7 +104,7 @@ pub fn check_crate(
make_stat(bccx, bccx.stats.stable_paths.get()));
}
return (bccx.root_map, bccx.write_guard_map);
return bccx.root_map;
fn make_stat(bccx: &mut BorrowckCtxt, stat: uint) -> ~str {
let stat_f = stat as f64;
@ -171,7 +169,6 @@ pub struct BorrowckCtxt {
moved_variables_set: moves::MovedVariablesSet,
capture_map: moves::CaptureMap,
root_map: root_map,
write_guard_map: write_guard_map,
// Statistics:
stats: @BorrowStats
@ -213,10 +210,6 @@ pub struct root_map_key {
derefs: uint
}
// A set containing IDs of expressions of gc'd type that need to have a write
// guard.
pub type write_guard_map = @RefCell<HashSet<root_map_key>>;
pub type BckResult<T> = Result<T, BckError>;
#[deriving(Eq)]
@ -402,7 +395,6 @@ impl BitAnd<RestrictionSet,RestrictionSet> for RestrictionSet {
pub struct RootInfo {
scope: ast::NodeId,
freeze: Option<DynaFreezeKind> // Some() if we should freeze box at runtime
}
pub type root_map = @RefCell<HashMap<root_map_key, RootInfo>>;
@ -411,20 +403,6 @@ pub fn root_map() -> root_map {
return @RefCell::new(HashMap::new());
}
pub enum DynaFreezeKind {
DynaImm,
DynaMut
}
impl ToStr for DynaFreezeKind {
fn to_str(&self) -> ~str {
match *self {
DynaMut => ~"mutable",
DynaImm => ~"immutable"
}
}
}
///////////////////////////////////////////////////////////////////////////
// Errors
@ -691,20 +669,9 @@ impl BorrowckCtxt {
span,
format!("{} in an aliasable location", prefix));
}
mc::AliasableManaged(ast::MutMutable) => {
// FIXME(#6269) reborrow @mut to &mut
self.tcx.sess.span_err(
span,
format!("{} in a `@mut` pointer; \
try borrowing as `&mut` first", prefix));
}
mc::AliasableManaged(m) => {
self.tcx.sess.span_err(
span,
format!("{} in a `@{}` pointer; \
try an `@mut` instead",
prefix,
self.mut_to_keyword(m)));
mc::AliasableManaged => {
self.tcx.sess.span_err(span, format!("{} in a `@` pointer",
prefix))
}
mc::AliasableBorrowed(m) => {
self.tcx.sess.span_err(
@ -788,7 +755,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));
}

View File

@ -116,7 +116,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
if is_const {
match e.node {
ExprUnary(_, UnDeref, _) => { }
ExprUnary(_, UnBox(_), _) | ExprUnary(_, UnUniq, _) => {
ExprUnary(_, UnBox, _) | ExprUnary(_, UnUniq, _) => {
sess.span_err(e.span,
"cannot do allocations in constant expressions");
return;
@ -197,8 +197,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
immutable values");
},
ExprVstore(_, ExprVstoreUniq) |
ExprVstore(_, ExprVstoreBox) |
ExprVstore(_, ExprVstoreMutBox) => {
ExprVstore(_, ExprVstoreBox) => {
sess.span_err(e.span, "cannot allocate vectors in constant expressions")
},
@ -266,13 +265,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")
},
}
}
_ => ()
}
},

View File

@ -20,7 +20,7 @@ use syntax::visit::Visitor;
use syntax::ast::*;
use std::cell::RefCell;
use std::hashmap::{HashMap, HashSet};
use std::hashmap::HashMap;
//
// This pass classifies expressions by their constant-ness.
@ -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 {
{
@ -129,7 +132,6 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt,
root_map: @RefCell::new(HashMap::new()),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
write_guard_map: @RefCell::new(HashSet::new()),
capture_map: @RefCell::new(HashMap::new())
};
let e = match csearch::maybe_get_item_ast(tcx, enum_def,
@ -155,17 +157,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 {
{
@ -179,7 +185,6 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
root_map: @RefCell::new(HashMap::new()),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
write_guard_map: @RefCell::new(HashSet::new()),
capture_map: @RefCell::new(HashMap::new())
};
let e = match csearch::maybe_get_item_ast(tcx, def_id,
@ -234,7 +239,6 @@ impl ConstEvalVisitor {
ast::ExprVstoreSlice => self.classify(e),
ast::ExprVstoreUniq |
ast::ExprVstoreBox |
ast::ExprVstoreMutBox |
ast::ExprVstoreMutSlice => non_const
}
}

View File

@ -118,7 +118,7 @@ impl<O:DataFlowOperator> pprust::pp_ann for DataFlowContext<O> {
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<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
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);
}
}

View File

@ -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(..))
@ -130,7 +132,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);

View File

@ -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!()
}
}

View File

@ -306,7 +306,7 @@ pub fn check_expr(cx: &mut Context, e: @Expr) {
}
match e.node {
ExprUnary(_, UnBox(_), interior) => {
ExprUnary(_, UnBox, interior) => {
let interior_type = ty::expr_ty(cx.tcx, interior);
let _ = check_durable(cx.tcx, interior_type, interior.span);
}

View File

@ -207,7 +207,7 @@ pub fn collect_language_items(crate: &ast::Crate,
}
lets_do_this! {
There are 43 lang items.
There are 37 lang items.
// ID, Variant name, Name, Method name;
0, FreezeTraitLangItem, "freeze", freeze_trait;
@ -243,24 +243,18 @@ lets_do_this! {
26, ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn;
27, MallocFnLangItem, "malloc", malloc_fn;
28, FreeFnLangItem, "free", free_fn;
29, BorrowAsImmFnLangItem, "borrow_as_imm", borrow_as_imm_fn;
30, BorrowAsMutFnLangItem, "borrow_as_mut", borrow_as_mut_fn;
31, ReturnToMutFnLangItem, "return_to_mut", return_to_mut_fn;
32, CheckNotBorrowedFnLangItem, "check_not_borrowed", check_not_borrowed_fn;
33, StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
34, RecordBorrowFnLangItem, "record_borrow", record_borrow_fn;
35, UnrecordBorrowFnLangItem, "unrecord_borrow", unrecord_borrow_fn;
29, StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
36, StartFnLangItem, "start", start_fn;
30, StartFnLangItem, "start", start_fn;
37, TyDescStructLangItem, "ty_desc", ty_desc;
38, TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
39, OpaqueStructLangItem, "opaque", opaque;
31, TyDescStructLangItem, "ty_desc", ty_desc;
32, TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
33, OpaqueStructLangItem, "opaque", opaque;
40, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
34, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
41, TypeIdLangItem, "type_id", type_id;
35, TypeIdLangItem, "type_id", type_id;
42, EhPersonalityLangItem, "eh_personality", eh_personality_fn;
36, EhPersonalityLangItem, "eh_personality", eh_personality_fn;
}

View File

@ -1076,7 +1076,7 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
}
}
ast::ExprUnary(_, ast::UnUniq, _) |
ast::ExprUnary(_, ast::UnBox(..), _) => BoxAllocation,
ast::ExprUnary(_, ast::UnBox, _) => BoxAllocation,
_ => return
};
@ -1246,7 +1246,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| {

View File

@ -85,7 +85,7 @@ pub struct CopiedUpvar {
#[deriving(Eq, IterBytes)]
pub enum PointerKind {
uniq_ptr,
gc_ptr(ast::Mutability),
gc_ptr,
region_ptr(ast::Mutability, ty::Region),
unsafe_ptr(ast::Mutability)
}
@ -178,17 +178,11 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
Some(deref_ptr(region_ptr(ast::MutImmutable, r)))
}
ty::ty_box(ref mt) |
ty::ty_evec(ref mt, ty::vstore_box) => {
Some(deref_ptr(gc_ptr(mt.mutbl)))
}
ty::ty_trait(_, _, ty::BoxTraitStore, m, _) => {
Some(deref_ptr(gc_ptr(m)))
}
ty::ty_box(_) |
ty::ty_evec(_, ty::vstore_box) |
ty::ty_trait(_, _, ty::BoxTraitStore, _, _) |
ty::ty_estr(ty::vstore_box) => {
Some(deref_ptr(gc_ptr(ast::MutImmutable)))
Some(deref_ptr(gc_ptr))
}
ty::ty_ptr(ref mt) => {
@ -681,7 +675,10 @@ impl mem_categorization_ctxt {
uniq_ptr => {
base_cmt.mutbl.inherit()
}
gc_ptr(m) | region_ptr(m, _) | unsafe_ptr(m) => {
gc_ptr => {
McImmutable
}
region_ptr(m, _) | unsafe_ptr(m) => {
MutabilityCategory::from_mutbl(m)
}
};
@ -759,12 +756,15 @@ impl mem_categorization_ctxt {
// for unique ptrs, we inherit mutability from the
// owning reference.
let m = match ptr {
uniq_ptr => {
base_cmt.mutbl.inherit()
}
gc_ptr(m) | region_ptr(m, _) | unsafe_ptr(m) => {
MutabilityCategory::from_mutbl(m)
}
uniq_ptr => {
base_cmt.mutbl.inherit()
}
gc_ptr => {
McImmutable
}
region_ptr(m, _) | unsafe_ptr(m) => {
MutabilityCategory::from_mutbl(m)
}
};
// the deref is explicit in the resulting cmt
@ -1103,7 +1103,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
}
pub enum AliasableReason {
AliasableManaged(ast::Mutability),
AliasableManaged,
AliasableBorrowed(ast::Mutability),
AliasableOther
}
@ -1122,7 +1122,7 @@ impl cmt_ {
cat_self(..) |
cat_arg(..) |
cat_deref(_, _, unsafe_ptr(..)) |
cat_deref(_, _, gc_ptr(..)) |
cat_deref(_, _, gc_ptr) |
cat_deref(_, _, region_ptr(..)) => {
self
}
@ -1166,8 +1166,8 @@ impl cmt_ {
Some(AliasableOther)
}
cat_deref(_, _, gc_ptr(m)) => {
Some(AliasableManaged(m))
cat_deref(_, _, gc_ptr) => {
Some(AliasableManaged)
}
cat_deref(_, _, region_ptr(m @ MutImmutable, _)) => {
@ -1229,7 +1229,7 @@ impl Repr for categorization {
pub fn ptr_sigil(ptr: PointerKind) -> ~str {
match ptr {
uniq_ptr => ~"~",
gc_ptr(_) => ~"@",
gc_ptr => ~"@",
region_ptr(_, _) => ~"&",
unsafe_ptr(_) => ~"*"
}

View File

@ -413,7 +413,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
@ -519,7 +520,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",

View File

@ -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 => {}

View File

@ -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) => {

View File

@ -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"));
{
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;
match *map_node {
ast_map::node_foreign_item(_, abis, _, _) => {
must_monomorphise = abis.is_intrinsic()
}
_ => {
must_monomorphise = false;
}
}
}
} else {

View File

@ -22,12 +22,10 @@ use middle::trans::base;
use middle::trans::build;
use middle::trans::datum;
use middle::trans::glue;
use middle::trans::write_guard;
use middle::trans::debuginfo;
use middle::ty::substs;
use middle::ty;
use middle::typeck;
use middle::borrowck::root_map_key;
use util::ppaux::Repr;
use middle::trans::type_::Type;
@ -363,27 +361,6 @@ impl CleanupFunction for ImmediateTypeDroppingCleanupFunction {
}
}
/// A cleanup function that releases a write guard, returning a value to
/// mutable status.
pub struct WriteGuardReleasingCleanupFunction {
root_key: root_map_key,
frozen_val_ref: ValueRef,
bits_val_ref: ValueRef,
filename_val: ValueRef,
line_val: ValueRef,
}
impl CleanupFunction for WriteGuardReleasingCleanupFunction {
fn clean(&self, bcx: @Block) -> @Block {
write_guard::return_to_mut(bcx,
self.root_key,
self.frozen_val_ref,
self.bits_val_ref,
self.filename_val,
self.line_val)
}
}
/// A cleanup function that frees some memory in the garbage-collected heap.
pub struct GCHeapFreeingCleanupFunction {
ptr: ValueRef,
@ -527,42 +504,7 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option<ast::NodeId>,
grow_scope_clean(scope_info);
})
}
pub fn add_clean_return_to_mut(bcx: @Block,
scope_id: ast::NodeId,
root_key: root_map_key,
frozen_val_ref: ValueRef,
bits_val_ref: ValueRef,
filename_val: ValueRef,
line_val: ValueRef) {
//! When an `@mut` has been frozen, we have to
//! call the lang-item `return_to_mut` when the
//! freeze goes out of scope. We need to pass
//! in both the value which was frozen (`frozen_val`) and
//! the value (`bits_val_ref`) which was returned when the
//! box was frozen initially. Here, both `frozen_val_ref` and
//! `bits_val_ref` are in fact pointers to stack slots.
debug!("add_clean_return_to_mut({}, {}, {})",
bcx.to_str(),
bcx.val_to_str(frozen_val_ref),
bcx.val_to_str(bits_val_ref));
in_scope_cx(bcx, Some(scope_id), |scope_info| {
{
let mut cleanups = scope_info.cleanups.borrow_mut();
cleanups.get().push(clean_temp(
frozen_val_ref,
@WriteGuardReleasingCleanupFunction {
root_key: root_key,
frozen_val_ref: frozen_val_ref,
bits_val_ref: bits_val_ref,
filename_val: filename_val,
line_val: line_val,
} as @CleanupFunction,
normal_exit_only));
}
grow_scope_clean(scope_info);
})
}
pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) {
let free_fn = match heap {
heap_managed | heap_managed_unique => {

View File

@ -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, _), ..
}, _) => {
@ -371,9 +377,7 @@ fn const_expr_unadjusted(cx: @CrateContext,
let ty = ty::expr_ty(cx.tcx, e);
let is_float = ty::type_is_fp(ty);
return (match u {
ast::UnBox(_) |
ast::UnUniq |
ast::UnDeref => {
ast::UnBox | ast::UnUniq | ast::UnDeref => {
let (dv, _dt) = const_deref(cx, te, ty, true);
dv
}

View File

@ -552,7 +552,7 @@ impl Datum {
* by-ref datum of type T, pointing at the contents. */
let (content_ty, header) = match ty::get(self.ty).sty {
ty::ty_box(mt) => (mt.ty, true),
ty::ty_box(typ) => (typ, true),
ty::ty_uniq(mt) => (mt.ty, false),
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => {
let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty);

View File

@ -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));
@ -1411,13 +1421,17 @@ fn describe_enum_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 {
@ -2128,8 +2142,8 @@ fn type_metadata(cx: &CrateContext,
ty::ty_enum(def_id, _) => {
prepare_enum_metadata(cx, t, def_id, usage_site_span).finalize(cx)
},
ty::ty_box(ref mt) => {
create_pointer_to_box_metadata(cx, t, mt.ty)
ty::ty_box(typ) => {
create_pointer_to_box_metadata(cx, t, typ)
},
ty::ty_evec(ref mt, ref vstore) => {
match *vstore {
@ -2296,16 +2310,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

View File

@ -378,18 +378,12 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
let source_data = Load(bcx, source_data_ptr); // always a ptr
let target_data = match source_store {
ty::BoxTraitStore(..) => {
// For deref of @T or @mut T, create a dummy datum and
// use the datum's deref method. This is more work
// than just calling GEPi ourselves, but it ensures
// that any write guards will be appropriate
// processed. Note that we don't know the type T, so
// For deref of @T, create a dummy datum and use the datum's
// deref method. This is more work than just calling GEPi
// ourselves. Note that we don't know the type T, so
// just substitute `i8`-- it doesn't really matter for
// our purposes right now.
let source_ty =
ty::mk_box(tcx,
ty::mt {
ty: ty::mk_i8(),
mutbl: source_mutbl});
let source_ty = ty::mk_box(tcx, ty::mk_i8());
let source_datum =
Datum {val: source_data,
ty: source_ty,
@ -596,8 +590,7 @@ fn trans_rvalue_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
ast::ExprPath(_) | ast::ExprSelf => {
return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id));
}
ast::ExprVstore(contents, ast::ExprVstoreBox) |
ast::ExprVstore(contents, ast::ExprVstoreMutBox) => {
ast::ExprVstore(contents, ast::ExprVstoreBox) => {
return tvec::trans_uniq_or_managed_vstore(bcx, heap_managed,
expr, contents);
}
@ -1412,9 +1405,8 @@ fn trans_unary_datum(bcx: @Block,
};
immediate_rvalue_bcx(bcx, llneg, un_ty)
}
ast::UnBox(_) => {
trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty,
heap_managed)
ast::UnBox => {
trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, heap_managed)
}
ast::UnUniq => {
let heap = heap_for_unique(bcx, un_ty);

View File

@ -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);

View File

@ -157,7 +157,10 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
if (field == abi::tydesc_field_free_glue ||
field == abi::tydesc_field_drop_glue) {
match ty::get(t).sty {
ty::ty_box(mt) |
ty::ty_box(typ)
if ! ty::type_needs_drop(tcx, typ) =>
return ty::mk_imm_box(tcx, ty::mk_u32()),
ty::ty_evec(mt, ty::vstore_box)
if ! ty::type_needs_drop(tcx, mt.ty) =>
return ty::mk_imm_box(tcx, ty::mk_u32()),
@ -356,10 +359,10 @@ pub fn make_free_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block {
// NB: v0 is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("make_free_glue");
match ty::get(t).sty {
ty::ty_box(body_mt) => {
ty::ty_box(body_ty) => {
let v = Load(bcx, v);
let body = GEPi(bcx, v, [0u, abi::box_field_body]);
let bcx = drop_ty(bcx, body, body_mt.ty);
let bcx = drop_ty(bcx, body, body_ty);
trans_free(bcx, v)
}
ty::ty_opaque_box => {

View File

@ -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,

View File

@ -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);

View File

@ -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),

View File

@ -189,8 +189,11 @@ impl Reflector {
self.visit(~"evec_" + name, extra)
}
}
ty::ty_box(ref mt) => {
let extra = self.c_mt(mt);
ty::ty_box(typ) => {
let extra = self.c_mt(&ty::mt {
ty: typ,
mutbl: ast::MutImmutable,
});
self.visit("box", extra)
}
ty::ty_uniq(ref mt) => {

View File

@ -236,8 +236,8 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty);
Type::smart_ptr(cx, &v_ty).ptr_to()
}
ty::ty_box(ref mt) => {
let ty = type_of(cx, mt.ty);
ty::ty_box(typ) => {
let ty = type_of(cx, typ);
Type::smart_ptr(cx, &ty).ptr_to()
}
ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(),

View File

@ -15,26 +15,15 @@
//! `RUST_LOG=rustc::middle::trans::write_guard`).
use lib::llvm::ValueRef;
use middle::borrowck::{RootInfo, root_map_key, DynaImm, DynaMut};
use middle::lang_items::CheckNotBorrowedFnLangItem;
use middle::lang_items::{BorrowAsImmFnLangItem, BorrowAsMutFnLangItem};
use middle::lang_items::{RecordBorrowFnLangItem, UnrecordBorrowFnLangItem};
use middle::lang_items::ReturnToMutFnLangItem;
use middle::borrowck::{RootInfo, root_map_key};
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::callee;
use middle::trans::common::*;
use middle::trans::datum::*;
use middle::trans::expr;
use middle::ty;
use syntax::codemap::Span;
use syntax::ast;
use middle::trans::type_::Type;
pub fn root_and_write_guard(datum: &Datum,
mut bcx: @Block,
bcx: @Block,
span: Span,
expr_id: ast::NodeId,
derefs: uint) -> @Block {
@ -45,69 +34,16 @@ pub fn root_and_write_guard(datum: &Datum,
//
// (Note: root'd values are always boxes)
let ccx = bcx.ccx();
bcx = {
let root_map = ccx.maps.root_map.borrow();
match root_map.get().find(&key) {
None => bcx,
Some(&root_info) => root(datum, bcx, span, key, root_info)
}
};
// Perform the write guard, if necessary.
//
// (Note: write-guarded values are always boxes)
let write_guard_map = ccx.maps.write_guard_map.borrow();
if write_guard_map.get().contains(&key) {
perform_write_guard(datum, bcx, span)
} else {
bcx
let root_map = ccx.maps.root_map.borrow();
match root_map.get().find(&key) {
None => bcx,
Some(&root_info) => root(datum, bcx, span, key, root_info)
}
}
pub fn return_to_mut(mut bcx: @Block,
root_key: root_map_key,
frozen_val_ref: ValueRef,
bits_val_ref: ValueRef,
filename_val: ValueRef,
line_val: ValueRef) -> @Block {
debug!("write_guard::return_to_mut(root_key={:?}, {}, {}, {})",
root_key,
bcx.to_str(),
bcx.val_to_str(frozen_val_ref),
bcx.val_to_str(bits_val_ref));
let box_ptr = Load(bcx, PointerCast(bcx, frozen_val_ref, Type::i8p().ptr_to()));
let bits_val = Load(bcx, bits_val_ref);
if bcx.tcx().sess.debug_borrows() {
bcx = callee::trans_lang_call( bcx,
langcall(bcx, None, "unborrow", UnrecordBorrowFnLangItem),
[
box_ptr,
bits_val,
filename_val,
line_val
],
Some(expr::Ignore)).bcx;
}
callee::trans_lang_call(
bcx,
langcall(bcx, None, "unborrow", ReturnToMutFnLangItem),
[
box_ptr,
bits_val,
filename_val,
line_val
],
Some(expr::Ignore)
).bcx
}
fn root(datum: &Datum,
mut bcx: @Block,
span: Span,
bcx: @Block,
_: Span,
root_key: root_map_key,
root_info: RootInfo) -> @Block {
//! In some cases, borrowck will decide that an @T/@[]/@str
@ -129,73 +65,6 @@ fn root(datum: &Datum,
scratch.val,
scratch.ty);
// Now, consider also freezing it.
match root_info.freeze {
None => {}
Some(freeze_kind) => {
let (filename, line) = filename_and_line_num_from_span(bcx, span);
// in this case, we don't have to zero, because
// scratch.val will be NULL should the cleanup get
// called without the freezing actually occurring, and
// return_to_mut checks for this condition.
let scratch_bits = scratch_datum(bcx, ty::mk_uint(),
"__write_guard_bits", false);
let freeze_item = match freeze_kind {
DynaImm => BorrowAsImmFnLangItem,
DynaMut => BorrowAsMutFnLangItem,
};
let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to()));
let llresult = unpack_result!(bcx, callee::trans_lang_call(
bcx,
langcall(bcx, Some(span), "freeze", freeze_item),
[
box_ptr,
filename,
line
],
Some(expr::SaveIn(scratch_bits.val))));
if bcx.tcx().sess.debug_borrows() {
bcx = callee::trans_lang_call(
bcx,
langcall(bcx, Some(span), "freeze", RecordBorrowFnLangItem),
[
box_ptr,
llresult,
filename,
line
],
Some(expr::Ignore)).bcx;
}
add_clean_return_to_mut(cleanup_bcx,
root_info.scope,
root_key,
scratch.val,
scratch_bits.val,
filename,
line);
}
}
bcx
}
fn perform_write_guard(datum: &Datum,
bcx: @Block,
span: Span) -> @Block {
debug!("perform_write_guard");
let llval = datum.to_value_llval(bcx);
let (filename, line) = filename_and_line_num_from_span(bcx, span);
callee::trans_lang_call(
bcx,
langcall(bcx, Some(span), "write guard", CheckNotBorrowedFnLangItem),
[PointerCast(bcx, llval, Type::i8p()), filename, line],
Some(expr::Ignore)).bcx
}

View File

@ -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::SpanHandler,
diag: @syntax::diagnostic::SpanHandler,
interner: RefCell<HashMap<intern_key, ~t_box_>>,
next_id: Cell<uint>,
cstore: @metadata::cstore::CStore,
@ -637,7 +637,7 @@ pub enum sty {
ty_float(ast::float_ty),
ty_estr(vstore),
ty_enum(DefId, substs),
ty_box(mt),
ty_box(t),
ty_uniq(mt),
ty_evec(mt, vstore),
ty_ptr(mt),
@ -1102,8 +1102,9 @@ pub fn mk_t(cx: ctxt, st: sty) -> t {
_ => {}
}
}
&ty_box(ref m) | &ty_uniq(ref m) | &ty_evec(ref m, _) |
&ty_ptr(ref m) | &ty_unboxed_vec(ref m) => {
&ty_box(ref tt) => flags |= get(*tt).flags,
&ty_uniq(ref m) | &ty_evec(ref m, _) | &ty_ptr(ref m) |
&ty_unboxed_vec(ref m) => {
flags |= get(m.ty).flags;
}
&ty_rptr(r, ref m) => {
@ -1242,10 +1243,10 @@ pub fn mk_enum(cx: ctxt, did: ast::DefId, substs: substs) -> t {
mk_t(cx, ty_enum(did, substs))
}
pub fn mk_box(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_box(tm)) }
pub fn mk_box(cx: ctxt, ty: t) -> t { mk_t(cx, ty_box(ty)) }
pub fn mk_imm_box(cx: ctxt, ty: t) -> t {
mk_box(cx, mt {ty: ty, mutbl: ast::MutImmutable})
mk_box(cx, ty)
}
pub fn mk_uniq(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_uniq(tm)) }
@ -1368,8 +1369,11 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
ty_estr(_) | ty_type | ty_opaque_box | ty_self(_) |
ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {
}
ty_box(ref tm) | ty_evec(ref tm, _) | ty_unboxed_vec(ref tm) |
ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_uniq(ref tm) => {
ty_box(ref ty) => {
maybe_walk_ty(*ty, f);
}
ty_evec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
ty_rptr(_, ref tm) | ty_uniq(ref tm) => {
maybe_walk_ty(tm.ty, f);
}
ty_enum(_, ref substs) | ty_struct(_, ref substs) |
@ -2035,8 +2039,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
closure_contents(cx, c)
}
ty_box(mt) => {
tc_mt(cx, mt, cache).managed_pointer()
ty_box(typ) => {
tc_ty(cx, typ, cache).managed_pointer()
}
ty_trait(_, _, store, mutbl, bounds) => {
@ -2334,7 +2338,9 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
ty_unboxed_vec(_) => {
false
}
ty_box(ref mt) |
ty_box(typ) => {
type_requires(cx, seen, r_ty, typ)
}
ty_uniq(ref mt) |
ty_rptr(_, ref mt) => {
type_requires(cx, seen, r_ty, mt.ty)
@ -2610,7 +2616,14 @@ pub fn deref(cx: ctxt, t: t, explicit: bool) -> Option<mt> {
pub fn deref_sty(cx: ctxt, sty: &sty, explicit: bool) -> Option<mt> {
match *sty {
ty_rptr(_, mt) | ty_box(mt) | ty_uniq(mt) => {
ty_box(typ) => {
Some(mt {
ty: typ,
mutbl: ast::MutImmutable,
})
}
ty_rptr(_, mt) | ty_uniq(mt) => {
Some(mt)
}
@ -3244,7 +3257,6 @@ pub fn expr_kind(tcx: ctxt,
ast::ExprAddrOf(..) |
ast::ExprBinary(..) |
ast::ExprVstore(_, ast::ExprVstoreBox) |
ast::ExprVstore(_, ast::ExprVstoreMutBox) |
ast::ExprVstore(_, ast::ExprVstoreUniq) => {
RvalueDatumExpr
}
@ -3556,16 +3568,19 @@ pub fn provided_source(cx: ctxt, id: ast::DefId) -> Option<ast::DefId> {
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 +3690,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 +3875,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)
}
ast_map::node_foreign_item(nitem, _, _, path) => {
vec::append_one((*path).clone(),
ast_map::path_name(nitem.ident))
// 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::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 +3955,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<Disr> = None;
@enum_definition.variants.iter().map(|&variant| {
{
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<Disr> = None;
@enum_definition.variants.iter().map(|&variant| {
let mut discriminant = match last_discriminant {
Some(val) => val + 1,
None => INITIAL_DISCRIMINANT_VALUE
};
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 => {}
};
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
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")
}).collect()
}
_ => cx.sess.bug("enum_variants: id not bound to an enum")
}
}
};
@ -4040,11 +4062,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 +4148,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 +4688,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<ast::DefId> {
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
};
@ -4799,9 +4830,8 @@ pub fn hash_crate_independent(tcx: ctxt, t: t, local_hash: @str) -> u64 {
hash.input([8]);
did(&mut hash, d);
}
ty_box(m) => {
ty_box(_) => {
hash.input([9]);
mt(&mut hash, m);
}
ty_uniq(m) => {
hash.input([10]);

View File

@ -140,8 +140,8 @@ pub fn super_fold_mt<T:TypeFolder>(this: &mut T,
pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
sty: &ty::sty) -> ty::sty {
match *sty {
ty::ty_box(ref tm) => {
ty::ty_box(this.fold_mt(tm))
ty::ty_box(typ) => {
ty::ty_box(this.fold_ty(typ))
}
ty::ty_uniq(ref tm) => {
ty::ty_uniq(this.fold_mt(tm))

View File

@ -401,9 +401,10 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
let typ = match ast_ty.node {
ast::ty_nil => ty::mk_nil(),
ast::ty_bot => ty::mk_bot(),
ast::ty_box(ref mt) => {
mk_pointer(this, rscope, mt, ty::vstore_box,
|tmt| ty::mk_box(tcx, tmt))
ast::ty_box(ty) => {
let mt = ast::mt { ty: ty, mutbl: ast::MutImmutable };
mk_pointer(this, rscope, &mt, ty::vstore_box,
|tmt| ty::mk_box(tcx, tmt.ty))
}
ast::ty_uniq(ty) => {
let mt = ast::mt { ty: ty, mutbl: ast::MutImmutable };
@ -689,10 +690,8 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(
ty::mt {ty: self_info.untransformed_self_ty,
mutbl: mutability}))
}
ast::sty_box(mutability) => {
Some(ty::mk_box(this.tcx(),
ty::mt {ty: self_info.untransformed_self_ty,
mutbl: mutability}))
ast::sty_box(_) => {
Some(ty::mk_box(this.tcx(), self_info.untransformed_self_ty))
}
ast::sty_uniq(_) => {
Some(ty::mk_uniq(this.tcx(),

View File

@ -667,8 +667,8 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
span: Span,
expected: ty::t) {
let fcx = pcx.fcx;
let check_inner: |ty::mt| = |e_inner| {
check_pat(pcx, inner, e_inner.ty);
let check_inner: |ty::t| = |e_inner| {
check_pat(pcx, inner, e_inner);
fcx.write_ty(pat_id, expected);
};
match *structure_of(fcx, span, expected) {
@ -676,10 +676,10 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
check_inner(e_inner);
}
ty::ty_uniq(e_inner) if pointer_kind == Send => {
check_inner(e_inner);
check_inner(e_inner.ty);
}
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
check_inner(e_inner);
check_inner(e_inner.ty);
}
_ => {
check_pat(pcx, inner, ty::mk_err());

View File

@ -1092,9 +1092,9 @@ impl<'a> LookupContext<'a> {
substs, RegionTraitStore(r), mt.mutbl,
ty::EmptyBuiltinBounds())
}
ty::ty_box(mt) => { // must be sty_box
ty::ty_box(_) => { // must be sty_box
ty::mk_trait(self.tcx(), trait_def_id,
substs, BoxTraitStore, mt.mutbl,
substs, BoxTraitStore, ast::MutImmutable,
ty::EmptyBuiltinBounds())
}
ty::ty_uniq(mt) => { // must be sty_uniq
@ -1224,9 +1224,8 @@ impl<'a> LookupContext<'a> {
sty_box(m) => {
debug!("(is relevant?) explicit self is a box");
match ty::get(rcvr_ty).sty {
ty::ty_box(mt) => {
mutability_matches(mt.mutbl, m) &&
rcvr_matches_ty(self.fcx, mt.ty, candidate)
ty::ty_box(typ) => {
rcvr_matches_ty(self.fcx, typ, candidate)
}
ty::ty_trait(self_did, _, BoxTraitStore, self_m, _) => {
@ -1309,10 +1308,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

View File

@ -1330,8 +1330,7 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) {
// Some extra checks to detect weird cycles and so forth:
match *sty {
ty::ty_box(inner) | ty::ty_uniq(inner) |
ty::ty_rptr(_, inner) => {
ty::ty_box(inner) => {
match ty::get(t1).sty {
ty::ty_infer(ty::TyVar(v1)) => {
ty::occurs_check(fcx.ccx.tcx, sp, v1,
@ -1340,6 +1339,15 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) {
_ => ()
}
}
ty::ty_uniq(inner) | ty::ty_rptr(_, inner) => {
match ty::get(t1).sty {
ty::ty_infer(ty::TyVar(v1)) => {
ty::occurs_check(fcx.ccx.tcx, sp, v1,
ty::mk_box(fcx.ccx.tcx, inner.ty));
}
_ => ()
}
}
ty::ty_enum(ref did, _) => {
// Watch out for a type like `enum t = @t`. Such a
// type would otherwise infinitely auto-deref. Only
@ -2620,15 +2628,12 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
}
ast::ExprVec(ref args, mutbl) => {
let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
let mutability;
let mut any_error = false;
let mut any_bot = false;
match vst {
ast::ExprVstoreMutBox | ast::ExprVstoreMutSlice => {
mutability = ast::MutMutable
}
_ => mutability = mutbl
}
let mutability = match vst {
ast::ExprVstoreMutSlice => ast::MutMutable,
_ => mutbl,
};
let t: ty::t = fcx.infcx().next_ty_var();
for e in args.iter() {
check_expr_has_type(fcx, *e, t);
@ -2642,11 +2647,9 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
}
if any_error {
ty::mk_err()
}
else if any_bot {
} else if any_bot {
ty::mk_bot()
}
else {
} else {
ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutability}, tt)
}
}
@ -2655,10 +2658,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
let _ = ty::eval_repeat_count(fcx, count_expr);
let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
let mutability = match vst {
ast::ExprVstoreMutBox | ast::ExprVstoreMutSlice => {
ast::MutMutable
}
_ => mutbl
ast::ExprVstoreMutSlice => ast::MutMutable,
_ => mutbl,
};
let t: ty::t = fcx.infcx().next_ty_var();
check_expr_has_type(fcx, element, t);
@ -2733,8 +2734,9 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
ast::ExprUnary(callee_id, unop, oprnd) => {
let exp_inner = unpack_expected(fcx, expected, |sty| {
match unop {
ast::UnBox(_) | ast::UnUniq => match *sty {
ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => Some(mt.ty),
ast::UnBox | ast::UnUniq => match *sty {
ty::ty_box(ty) => Some(ty),
ty::ty_uniq(ref mt) => Some(mt.ty),
_ => None
},
ast::UnNot | ast::UnNeg => expected,
@ -2746,9 +2748,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
if !ty::type_is_error(oprnd_t) &&
!ty::type_is_bot(oprnd_t) {
match unop {
ast::UnBox(mutbl) => {
oprnd_t = ty::mk_box(tcx,
ty::mt {ty: oprnd_t, mutbl: mutbl});
ast::UnBox => {
oprnd_t = ty::mk_box(tcx, oprnd_t)
}
ast::UnUniq => {
oprnd_t = ty::mk_uniq(tcx,
@ -3912,7 +3913,7 @@ pub fn ast_expr_vstore_to_vstore(fcx: @FnCtxt,
-> ty::vstore {
match v {
ast::ExprVstoreUniq => ty::vstore_uniq,
ast::ExprVstoreBox | ast::ExprVstoreMutBox => ty::vstore_box,
ast::ExprVstoreBox => ty::vstore_box,
ast::ExprVstoreSlice | ast::ExprVstoreMutSlice => {
let r = fcx.infcx().next_region_var(infer::AddrOfSlice(e.span));
ty::vstore_slice(r)

View File

@ -582,7 +582,13 @@ pub fn early_resolve_expr(ex: @ast::Expr,
let ty = structurally_resolved_type(fcx, ex.span,
fcx.expr_ty(src));
match (&ty::get(ty).sty, store) {
(&ty::ty_box(mt), ty::BoxTraitStore) |
(&ty::ty_box(..), ty::BoxTraitStore)
if !mutability_allowed(ast::MutImmutable,
target_mutbl) => {
fcx.tcx().sess.span_err(ex.span,
format!("types differ in mutability"));
}
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(..))
if !mutability_allowed(mt.mutbl, target_mutbl) => {
@ -590,9 +596,15 @@ pub fn early_resolve_expr(ex: @ast::Expr,
format!("types differ in mutability"));
}
(&ty::ty_box(mt), ty::BoxTraitStore) |
(&ty::ty_uniq(mt), ty::UniqTraitStore) |
(&ty::ty_rptr(_, mt), ty::RegionTraitStore(..)) => {
(&ty::ty_box(..), ty::BoxTraitStore) |
(&ty::ty_uniq(..), ty::UniqTraitStore) |
(&ty::ty_rptr(..), ty::RegionTraitStore(..)) => {
let typ = match (&ty::get(ty).sty) {
&ty::ty_box(typ) => typ,
&ty::ty_uniq(mt) | &ty::ty_rptr(_, mt) => mt.ty,
_ => fail!("shouldn't get here"),
};
let location_info =
&location_info_for_expr(ex);
let vcx = fcx.vtable_context();
@ -601,7 +613,7 @@ pub fn early_resolve_expr(ex: @ast::Expr,
substs: ty::substs {
tps: target_substs.tps.clone(),
regions: target_substs.regions.clone(),
self_ty: Some(mt.ty)
self_ty: Some(typ)
}
};
@ -614,7 +626,7 @@ pub fn early_resolve_expr(ex: @ast::Expr,
location_info,
None,
&param_bounds,
mt.ty,
typ,
is_early);
if !is_early {

View File

@ -568,10 +568,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,
@ -628,7 +626,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;
}
@ -732,14 +731,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 {

View File

@ -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))
}
}

View File

@ -241,7 +241,7 @@ impl Coerce {
let r_borrow = self.infcx.next_region_var(Coercion(self.trace));
let inner_ty = match *sty_a {
ty::ty_box(mt_a) => mt_a.ty,
ty::ty_box(typ) => typ,
ty::ty_uniq(mt_a) => mt_a.ty,
ty::ty_rptr(_, mt_a) => mt_a.ty,
_ => {

View File

@ -515,8 +515,8 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
Ok(ty::mk_struct(tcx, a_id, substs))
}
(&ty::ty_box(ref a_mt), &ty::ty_box(ref b_mt)) => {
this.mts(a_mt, b_mt).and_then(|mt| Ok(ty::mk_box(tcx, mt)))
(&ty::ty_box(a_inner), &ty::ty_box(b_inner)) => {
this.tys(a_inner, b_inner).and_then(|typ| Ok(ty::mk_box(tcx, typ)))
}
(&ty::ty_uniq(ref a_mt), &ty::ty_uniq(ref b_mt)) => {

View File

@ -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,_)

View File

@ -637,7 +637,10 @@ impl<'a> ConstraintContext<'a> {
self.add_constraints_from_mt(mt, variance);
}
ty::ty_box(ref mt) |
ty::ty_box(typ) => {
self.add_constraints_from_ty(typ, variance);
}
ty::ty_uniq(ref mt) |
ty::ty_ptr(ref mt) => {
self.add_constraints_from_mt(mt, variance);

View File

@ -72,7 +72,8 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region)
-> (~str, Option<Span>) {
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!("<block at {}>",
cx.sess.codemap.span_to_str(blk.span))
@ -451,7 +454,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
ty_uint(ast::ty_u) => ~"uint",
ty_uint(t) => ast_util::uint_ty_to_str(t),
ty_float(t) => ast_util::float_ty_to_str(t),
ty_box(ref tm) => ~"@" + mt_to_str(cx, tm),
ty_box(typ) => ~"@" + ty_to_str(cx, typ),
ty_uniq(ref tm) => ~"~" + mt_to_str(cx, tm),
ty_ptr(ref tm) => ~"*" + mt_to_str(cx, tm),
ty_rptr(r, ref tm) => {
@ -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);

View File

@ -594,7 +594,7 @@ pub enum Type {
/// aka ty_bot
Bottom,
Unique(~Type),
Managed(Mutability, ~Type),
Managed(~Type),
RawPointer(Mutability, ~Type),
BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: ~Type},
// region, raw, other boxes, mutable
@ -620,7 +620,7 @@ impl Clean<Type> for ast::Ty {
ty_rptr(ref l, ref m) =>
BorrowedRef {lifetime: l.clean(), mutability: m.mutbl.clean(),
type_: ~m.ty.clean()},
ty_box(ref m) => Managed(m.mutbl.clean(), ~m.ty.clean()),
ty_box(ty) => Managed(~ty.clean()),
ty_uniq(ty) => Unique(~ty.clean()),
ty_vec(ty) => Vector(~ty.clean()),
ty_fixed_length_vec(ty, ref e) => FixedVector(~ty.clean(),

View File

@ -88,7 +88,7 @@ pub fn run_core (libs: HashSet<Path>, 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)

View File

@ -340,13 +340,7 @@ impl fmt::Default for clean::Type {
clean::Unit => f.buf.write("()".as_bytes()),
clean::Bottom => f.buf.write("!".as_bytes()),
clean::Unique(ref t) => write!(f.buf, "~{}", **t),
clean::Managed(m, ref t) => {
write!(f.buf, "@{}{}",
match m {
clean::Mutable => "mut ",
clean::Immutable => "",
}, **t)
}
clean::Managed(ref t) => write!(f.buf, "@{}", **t),
clean::RawPointer(m, ref t) => {
write!(f.buf, "*{}{}",
match m {

View File

@ -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<Output, ~str> {
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);
}

View File

@ -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);

View File

@ -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 {

View File

@ -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)
}

View File

@ -58,12 +58,6 @@ impl<T> Clone for @T {
fn clone(&self) -> @T { *self }
}
impl<T> 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<T: Freeze + DeepClone + 'static> DeepClone for @T {
fn deep_clone(&self) -> @T { @(**self).deep_clone() }
}
// FIXME: #6525: should also be implemented for `T: Send + DeepClone`
impl<T: Freeze + DeepClone + 'static> 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;

View File

@ -16,10 +16,6 @@ pub trait Default {
fn default() -> Self;
}
impl<T: Default + 'static> Default for @mut T {
fn default() -> @mut T { @mut Default::default() }
}
impl<T: Default + 'static> Default for @T {
fn default() -> @T { @Default::default() }
}

View File

@ -371,15 +371,17 @@ mod test {
#[test]
#[should_fail]
#[ignore] // borrow issues with RefCell
fn push_bytes_fail_reset_len() {
// push_bytes unsafely sets the vector length. This is testing that
// upon failure the length is reset correctly.
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

View File

@ -31,13 +31,6 @@ pub fn ptr_eq<T>(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<T>(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<T:Eq> Eq for @T {
#[inline]
@ -46,14 +39,6 @@ impl<T:Eq> Eq for @T {
fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
}
#[cfg(not(test))]
impl<T:Eq> 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<T:Ord> Ord for @T {
#[inline]
@ -66,41 +51,18 @@ impl<T:Ord> Ord for @T {
fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
}
#[cfg(not(test))]
impl<T:Ord> 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<T: TotalOrd> TotalOrd for @T {
#[inline]
fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
}
#[cfg(not(test))]
impl<T: TotalOrd> TotalOrd for @mut T {
#[inline]
fn cmp(&self, other: &@mut T) -> Ordering { (**self).cmp(*other) }
}
#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @T {
#[inline]
fn equals(&self, other: &@T) -> bool { (**self).equals(*other) }
}
#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @mut T {
#[inline]
fn equals(&self, other: &@mut T) -> bool { (**self).equals(*other) }
}
#[test]
fn test() {
let x = @3;

View File

@ -1079,11 +1079,6 @@ pub fn pow_with_uint<T:NumCast+One+Zero+Div<T,T>+Mul<T,T>>(radix: uint, pow: uin
total
}
impl<T: Zero + 'static> Zero for @mut T {
fn zero() -> @mut T { @mut Zero::zero() }
fn is_zero(&self) -> bool { (**self).is_zero() }
}
impl<T: Zero + 'static> Zero for @T {
fn zero() -> @T { @Zero::zero() }
fn is_zero(&self) -> bool { (**self).is_zero() }

View File

@ -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 ())");

View File

@ -444,16 +444,20 @@ mod test {
#[test]
fn heap_cycles() {
use cell::RefCell;
use option::{Option, Some, None};
struct List {
next: Option<@mut List>,
next: Option<@RefCell<List>>,
}
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]

View File

@ -319,13 +319,6 @@ impl<A:IterBytes> IterBytes for @A {
}
}
impl<A:IterBytes> IterBytes for @mut A {
#[inline]
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
(**self).iter_bytes(lsb0, f)
}
}
impl<A:IterBytes> IterBytes for Rc<A> {
#[inline]
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {

View File

@ -15,6 +15,7 @@ use abi::AbiSet;
use opt_vec::OptVec;
use parse::token::{interner_get, str_to_ident};
use std::cell::RefCell;
use std::hashmap::HashMap;
use std::option::Option;
use std::to_str::ToStr;
@ -88,9 +89,9 @@ pub type SyntaxContext = u32;
// it should cut down on memory use *a lot*; applying a mark
// to a tree containing 50 identifiers would otherwise generate
pub struct SCTable {
table : ~[SyntaxContext_],
mark_memo : HashMap<(SyntaxContext,Mrk),SyntaxContext>,
rename_memo : HashMap<(SyntaxContext,Ident,Name),SyntaxContext>
table: RefCell<~[SyntaxContext_]>,
mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
rename_memo: RefCell<HashMap<(SyntaxContext,Ident,Name),SyntaxContext>>,
}
// NB: these must be placed in any SCTable...
@ -414,7 +415,6 @@ pub enum Vstore {
pub enum ExprVstore {
ExprVstoreUniq, // ~[1,2,3,4]
ExprVstoreBox, // @[1,2,3,4]
ExprVstoreMutBox, // @mut [1,2,3,4]
ExprVstoreSlice, // &[1,2,3,4]
ExprVstoreMutSlice, // &mut [1,2,3,4]
}
@ -443,7 +443,7 @@ pub enum BinOp {
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum UnOp {
UnBox(Mutability),
UnBox,
UnUniq,
UnDeref,
UnNot,
@ -874,7 +874,7 @@ pub struct TyBareFn {
pub enum ty_ {
ty_nil,
ty_bot, /* bottom type */
ty_box(mt),
ty_box(P<Ty>),
ty_uniq(P<Ty>),
ty_vec(P<Ty>),
ty_fixed_length_vec(P<Ty>, @Expr),

View File

@ -23,6 +23,7 @@ use print::pprust;
use visit::{Visitor, fn_kind};
use visit;
use std::cell::RefCell;
use std::hashmap::HashMap;
use std::vec;
@ -94,7 +95,7 @@ pub fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str {
fn pretty_ty(ty: &Ty, itr: @ident_interner, out: &mut ~str) {
let (prefix, subty) = match ty.node {
ty_uniq(ty) => ("$UP$", &*ty),
ty_box(mt { ty, .. }) => ("$SP$", &*ty),
ty_box(ty) => ("$SP$", &*ty),
ty_ptr(mt { ty, mutbl }) => (if mutbl == MutMutable {"$RPmut$"} else {"$RP$"},
&*ty),
ty_rptr(_, mt { ty, mutbl }) => (if mutbl == MutMutable {"$BPmut$"} else {"$BP$"},
@ -192,17 +193,17 @@ impl ast_node {
}
}
pub type map = @mut HashMap<NodeId, ast_node>;
pub type map = @RefCell<HashMap<NodeId, ast_node>>;
pub struct Ctx {
map: map,
path: path,
diag: @mut SpanHandler,
path: RefCell<path>,
diag: @SpanHandler,
}
impl Ctx {
fn extend(&self, elt: path_elt) -> @path {
@vec::append(self.path.clone(), [elt])
@vec::append(self.path.get(), [elt])
}
fn map_method(&mut self,
@ -215,8 +216,10 @@ impl Ctx {
} else {
node_method(m, impl_did, impl_path)
};
self.map.insert(m.id, entry);
self.map.insert(m.self_id, node_local(special_idents::self_));
let mut map = self.map.borrow_mut();
map.get().insert(m.id, entry);
map.get().insert(m.self_id, node_local(special_idents::self_));
}
fn map_struct_def(&mut self,
@ -231,10 +234,11 @@ impl Ctx {
Some(ctor_id) => {
match parent_node {
node_item(item, _) => {
self.map.insert(ctor_id,
node_struct_ctor(struct_def,
item,
p));
let mut map = self.map.borrow_mut();
map.get().insert(ctor_id,
node_struct_ctor(struct_def,
item,
p));
}
_ => fail!("struct def parent wasn't an item")
}
@ -243,13 +247,17 @@ impl Ctx {
}
fn map_expr(&mut self, ex: @Expr) {
self.map.insert(ex.id, node_expr(ex));
{
let mut map = self.map.borrow_mut();
map.get().insert(ex.id, node_expr(ex));
}
// Expressions which are or might be calls:
{
let r = ex.get_callee_id();
for callee_id in r.iter() {
self.map.insert(*callee_id, node_callee_scope(ex));
let mut map = self.map.borrow_mut();
map.get().insert(*callee_id, node_callee_scope(ex));
}
}
@ -263,26 +271,40 @@ impl Ctx {
sp: codemap::Span,
id: NodeId) {
for a in decl.inputs.iter() {
self.map.insert(a.id, node_arg(a.pat));
let mut map = self.map.borrow_mut();
map.get().insert(a.id, node_arg(a.pat));
}
match *fk {
visit::fk_method(name, _, _) => { self.path.push(path_name(name)) }
visit::fk_method(name, _, _) => {
let mut path = self.path.borrow_mut();
path.get().push(path_name(name))
}
_ => {}
}
visit::walk_fn(self, fk, decl, body, sp, id, ());
match *fk {
visit::fk_method(..) => { self.path.pop(); }
visit::fk_method(..) => {
let mut path = self.path.borrow_mut();
path.get().pop();
}
_ => {}
}
}
fn map_stmt(&mut self, stmt: @Stmt) {
self.map.insert(stmt_id(stmt), node_stmt(stmt));
{
let mut map = self.map.borrow_mut();
map.get().insert(stmt_id(stmt), node_stmt(stmt));
}
visit::walk_stmt(self, stmt, ());
}
fn map_block(&mut self, b: P<Block>) {
self.map.insert(b.id, node_block(b));
{
let mut map = self.map.borrow_mut();
map.get().insert(b.id, node_block(b));
}
visit::walk_block(self, b, ());
}
@ -290,8 +312,9 @@ impl Ctx {
match pat.node {
PatIdent(_, ref path, _) => {
// Note: this is at least *potentially* a pattern...
self.map.insert(pat.id,
node_local(ast_util::path_to_ident(path)));
let mut map = self.map.borrow_mut();
map.get().insert(pat.id,
node_local(ast_util::path_to_ident(path)));
}
_ => ()
}
@ -303,8 +326,11 @@ impl Ctx {
impl Visitor<()> for Ctx {
fn visit_item(&mut self, i: @item, _: ()) {
// clone is FIXME #2543
let item_path = @self.path.clone();
self.map.insert(i.id, node_item(i, item_path));
let item_path = @self.path.get();
{
let mut map = self.map.borrow_mut();
map.get().insert(i.id, node_item(i, item_path));
}
match i.node {
item_impl(_, ref maybe_trait, ty, ref ms) => {
// Right now the ident on impls is __extensions__ which isn't
@ -318,13 +344,15 @@ impl Visitor<()> for Ctx {
self.map_method(impl_did, extended, *m, false)
}
self.path.push(elt);
let mut path = self.path.borrow_mut();
path.get().push(elt);
}
item_enum(ref enum_definition, _) => {
for &v in enum_definition.variants.iter() {
let elt = path_name(i.ident);
self.map.insert(v.node.id,
node_variant(v, i, self.extend(elt)));
let mut map = self.map.borrow_mut();
map.get().insert(v.node.id,
node_variant(v, i, self.extend(elt)));
}
}
item_foreign_mod(ref nm) => {
@ -336,16 +364,17 @@ impl Visitor<()> for Ctx {
inherited => i.vis
};
self.map.insert(nitem.id,
node_foreign_item(*nitem,
nm.abis,
visibility,
// FIXME (#2543)
let mut map = self.map.borrow_mut();
map.get().insert(nitem.id,
node_foreign_item(*nitem,
nm.abis,
visibility,
// FIXME (#2543)
// Anonymous extern
// mods go in the
// parent scope.
@self.path.clone()
));
@self.path.get()
));
}
}
item_struct(struct_def, _) => {
@ -355,7 +384,8 @@ impl Visitor<()> for Ctx {
}
item_trait(_, ref traits, ref methods) => {
for p in traits.iter() {
self.map.insert(p.ref_id, node_item(i, item_path));
let mut map = self.map.borrow_mut();
map.get().insert(p.ref_id, node_item(i, item_path));
}
for tm in methods.iter() {
let ext = { self.extend(path_name(i.ident)) };
@ -364,7 +394,8 @@ impl Visitor<()> for Ctx {
required(ref m) => {
let entry =
node_trait_method(@(*tm).clone(), d_id, ext);
self.map.insert(m.id, entry);
let mut map = self.map.borrow_mut();
map.get().insert(m.id, entry);
}
provided(m) => {
self.map_method(d_id, ext, m, true);
@ -377,13 +408,19 @@ impl Visitor<()> for Ctx {
match i.node {
item_mod(_) | item_foreign_mod(_) => {
self.path.push(path_mod(i.ident));
let mut path = self.path.borrow_mut();
path.get().push(path_mod(i.ident));
}
item_impl(..) => {} // this was guessed above.
_ => self.path.push(path_name(i.ident))
_ => {
let mut path = self.path.borrow_mut();
path.get().push(path_name(i.ident))
}
}
visit::walk_item(self, i, ());
self.path.pop();
let mut path = self.path.borrow_mut();
path.get().pop();
}
fn visit_pat(&mut self, pat: &Pat, _: ()) {
@ -418,29 +455,29 @@ impl Visitor<()> for Ctx {
}
}
pub fn map_crate(diag: @mut SpanHandler, c: &Crate) -> map {
let cx = @mut Ctx {
map: @mut HashMap::new(),
path: ~[],
pub fn map_crate(diag: @SpanHandler, c: &Crate) -> map {
let mut cx = Ctx {
map: @RefCell::new(HashMap::new()),
path: RefCell::new(~[]),
diag: diag,
};
visit::walk_crate(cx, c, ());
visit::walk_crate(&mut cx, c, ());
cx.map
}
// Used for items loaded from external crate that are being inlined into this
// crate. The `path` should be the path to the item but should not include
// the item itself.
pub fn map_decoded_item(diag: @mut SpanHandler,
pub fn map_decoded_item(diag: @SpanHandler,
map: map,
path: path,
ii: &inlined_item) {
// I believe it is ok for the local IDs of inlined items from other crates
// to overlap with the local ids from this crate, so just generate the ids
// starting from 0.
let cx = @mut Ctx {
let mut cx = Ctx {
map: map,
path: path.clone(),
path: RefCell::new(path.clone()),
diag: diag,
};
@ -450,10 +487,11 @@ pub fn map_decoded_item(diag: @mut SpanHandler,
match *ii {
ii_item(..) => {} // fallthrough
ii_foreign(i) => {
cx.map.insert(i.id, node_foreign_item(i,
AbiSet::Intrinsic(),
i.vis, // Wrong but OK
@path));
let mut map = cx.map.borrow_mut();
map.get().insert(i.id, node_foreign_item(i,
AbiSet::Intrinsic(),
i.vis, // Wrong but OK
@path));
}
ii_method(impl_did, is_provided, m) => {
cx.map_method(impl_did, @path, m, is_provided);
@ -461,11 +499,12 @@ pub fn map_decoded_item(diag: @mut SpanHandler,
}
// visit the item / method contents and add those to the map:
ii.accept((), cx);
ii.accept((), &mut cx);
}
pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
match map.find(&id) {
let map = map.borrow();
match map.get().find(&id) {
None => {
format!("unknown node (id={})", id)
}
@ -529,7 +568,8 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
pub fn node_item_query<Result>(items: map, id: NodeId, query: |@item| -> Result, error_msg: ~str)
-> Result {
match items.find(&id) {
let items = items.borrow();
match items.get().find(&id) {
Some(&node_item(it, _)) => query(it),
_ => fail!("{}", error_msg)
}
@ -538,7 +578,8 @@ pub fn node_item_query<Result>(items: map, id: NodeId, query: |@item| -> Result,
pub fn node_span(items: map,
id: ast::NodeId)
-> Span {
match items.find(&id) {
let items = items.borrow();
match items.get().find(&id) {
Some(&node_item(item, _)) => item.span,
Some(&node_foreign_item(foreign_item, _, _, _)) => foreign_item.span,
Some(&node_trait_method(@required(ref type_method), _, _)) => type_method.span,

View File

@ -17,6 +17,7 @@ use parse::token;
use visit::Visitor;
use visit;
use std::cell::{Cell, RefCell};
use std::hashmap::HashMap;
use std::u32;
use std::local_data;
@ -136,13 +137,13 @@ pub fn is_shift_binop(b: BinOp) -> bool {
}
}
pub fn unop_to_str(op: UnOp) -> ~str {
pub fn unop_to_str(op: UnOp) -> &'static str {
match op {
UnBox(mt) => if mt == MutMutable { ~"@mut " } else { ~"@" },
UnUniq => ~"~",
UnDeref => ~"*",
UnNot => ~"!",
UnNeg => ~"-"
UnBox => "@",
UnUniq => "~",
UnDeref => "*",
UnNot => "!",
UnNeg => "-",
}
}
@ -601,21 +602,23 @@ pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &inlined_item,
}
struct IdRangeComputingVisitor {
result: @mut id_range,
result: Cell<id_range>,
}
impl IdVisitingOperation for IdRangeComputingVisitor {
fn visit_id(&self, id: NodeId) {
self.result.add(id)
let mut id_range = self.result.get();
id_range.add(id);
self.result.set(id_range)
}
}
pub fn compute_id_range_for_inlined_item(item: &inlined_item) -> id_range {
let result = @mut id_range::max();
visit_ids_for_inlined_item(item, &IdRangeComputingVisitor {
result: result,
});
*result
let visitor = IdRangeComputingVisitor {
result: Cell::new(id_range::max())
};
visit_ids_for_inlined_item(item, &visitor);
visitor.result.get()
}
pub fn is_item_impl(item: @ast::item) -> bool {
@ -709,21 +712,25 @@ pub fn new_mark(m:Mrk, tail:SyntaxContext) -> SyntaxContext {
// Extend a syntax context with a given mark and table
// FIXME #8215 : currently pub to allow testing
pub fn new_mark_internal(m:Mrk, tail:SyntaxContext,table:&mut SCTable)
-> SyntaxContext {
pub fn new_mark_internal(m: Mrk, tail: SyntaxContext, table: &SCTable)
-> SyntaxContext {
let key = (tail,m);
// FIXME #5074 : can't use more natural style because we're missing
// flow-sensitivity. Results in two lookups on a hash table hit.
// also applies to new_rename_internal, below.
// let try_lookup = table.mark_memo.find(&key);
match table.mark_memo.contains_key(&key) {
let mut mark_memo = table.mark_memo.borrow_mut();
match mark_memo.get().contains_key(&key) {
false => {
let new_idx = idx_push(&mut table.table,Mark(m,tail));
table.mark_memo.insert(key,new_idx);
let new_idx = {
let mut table = table.table.borrow_mut();
idx_push(table.get(), Mark(m,tail))
};
mark_memo.get().insert(key,new_idx);
new_idx
}
true => {
match table.mark_memo.find(&key) {
match mark_memo.get().find(&key) {
None => fail!("internal error: key disappeared 2013042901"),
Some(idxptr) => {*idxptr}
}
@ -738,19 +745,26 @@ pub fn new_rename(id:Ident, to:Name, tail:SyntaxContext) -> SyntaxContext {
// Extend a syntax context with a given rename and sctable
// FIXME #8215 : currently pub to allow testing
pub fn new_rename_internal(id:Ident, to:Name, tail:SyntaxContext, table: &mut SCTable)
-> SyntaxContext {
pub fn new_rename_internal(id: Ident,
to: Name,
tail: SyntaxContext,
table: &SCTable)
-> SyntaxContext {
let key = (tail,id,to);
// FIXME #5074
//let try_lookup = table.rename_memo.find(&key);
match table.rename_memo.contains_key(&key) {
let mut rename_memo = table.rename_memo.borrow_mut();
match rename_memo.get().contains_key(&key) {
false => {
let new_idx = idx_push(&mut table.table,Rename(id,to,tail));
table.rename_memo.insert(key,new_idx);
let new_idx = {
let mut table = table.table.borrow_mut();
idx_push(table.get(), Rename(id,to,tail))
};
rename_memo.get().insert(key,new_idx);
new_idx
}
true => {
match table.rename_memo.find(&key) {
match rename_memo.get().find(&key) {
None => fail!("internal error: key disappeared 2013042902"),
Some(idxptr) => {*idxptr}
}
@ -763,18 +777,18 @@ pub fn new_rename_internal(id:Ident, to:Name, tail:SyntaxContext, table: &mut SC
// FIXME #8215 : currently pub to allow testing
pub fn new_sctable_internal() -> SCTable {
SCTable {
table: ~[EmptyCtxt,IllegalCtxt],
mark_memo: HashMap::new(),
rename_memo: HashMap::new()
table: RefCell::new(~[EmptyCtxt,IllegalCtxt]),
mark_memo: RefCell::new(HashMap::new()),
rename_memo: RefCell::new(HashMap::new()),
}
}
// fetch the SCTable from TLS, create one if it doesn't yet exist.
pub fn get_sctable() -> @mut SCTable {
local_data_key!(sctable_key: @@mut SCTable)
pub fn get_sctable() -> @SCTable {
local_data_key!(sctable_key: @@SCTable)
match local_data::get(sctable_key, |k| k.map(|k| *k)) {
None => {
let new_table = @@mut new_sctable_internal();
let new_table = @@new_sctable_internal();
local_data::set(sctable_key,new_table);
*new_table
},
@ -785,7 +799,8 @@ pub fn get_sctable() -> @mut SCTable {
/// print out an SCTable for debugging
pub fn display_sctable(table : &SCTable) {
error!("SC table:");
for (idx,val) in table.table.iter().enumerate() {
let table = table.table.borrow();
for (idx,val) in table.get().iter().enumerate() {
error!("{:4u} : {:?}",idx,val);
}
}
@ -799,7 +814,9 @@ fn idx_push<T>(vec: &mut ~[T], val: T) -> u32 {
/// Resolve a syntax object to a name, per MTWT.
pub fn mtwt_resolve(id : Ident) -> Name {
resolve_internal(id, get_sctable(), get_resolve_table())
let resolve_table = get_resolve_table();
let mut resolve_table = resolve_table.borrow_mut();
resolve_internal(id, get_sctable(), resolve_table.get())
}
// FIXME #8215: must be pub for testing
@ -807,12 +824,12 @@ pub type ResolveTable = HashMap<(Name,SyntaxContext),Name>;
// okay, I admit, putting this in TLS is not so nice:
// fetch the SCTable from TLS, create one if it doesn't yet exist.
pub fn get_resolve_table() -> @mut ResolveTable {
local_data_key!(resolve_table_key: @@mut ResolveTable)
pub fn get_resolve_table() -> @RefCell<ResolveTable> {
local_data_key!(resolve_table_key: @@RefCell<ResolveTable>)
match local_data::get(resolve_table_key, |k| k.map(|k| *k)) {
None => {
let new_table = @@mut HashMap::new();
local_data::set(resolve_table_key,new_table);
let new_table = @@RefCell::new(HashMap::new());
local_data::set(resolve_table_key, new_table);
*new_table
},
Some(intr) => *intr
@ -823,13 +840,17 @@ pub fn get_resolve_table() -> @mut ResolveTable {
// adding memoization to possibly resolve 500+ seconds in resolve for librustc (!)
// FIXME #8215 : currently pub to allow testing
pub fn resolve_internal(id : Ident,
table : &mut SCTable,
table : &SCTable,
resolve_table : &mut ResolveTable) -> Name {
let key = (id.name,id.ctxt);
match resolve_table.contains_key(&key) {
false => {
let resolved = {
match table.table[id.ctxt] {
let result = {
let table = table.table.borrow();
table.get()[id.ctxt]
};
match result {
EmptyCtxt => id.name,
// ignore marks here:
Mark(_,subctxt) =>
@ -874,7 +895,11 @@ pub fn marksof(ctxt: SyntaxContext, stopname: Name, table: &SCTable) -> ~[Mrk] {
let mut result = ~[];
let mut loopvar = ctxt;
loop {
match table.table[loopvar] {
let table_entry = {
let table = table.table.borrow();
table.get()[loopvar]
};
match table_entry {
EmptyCtxt => {return result;},
Mark(mark,tl) => {
xorPush(&mut result,mark);
@ -898,7 +923,8 @@ pub fn marksof(ctxt: SyntaxContext, stopname: Name, table: &SCTable) -> ~[Mrk] {
/// FAILS when outside is not a mark.
pub fn mtwt_outer_mark(ctxt: SyntaxContext) -> Mrk {
let sctable = get_sctable();
match sctable.table[ctxt] {
let table = sctable.table.borrow();
match table.get()[ctxt] {
ast::Mark(mrk,_) => mrk,
_ => fail!("can't retrieve outer mark when outside is not a mark")
}
@ -1003,7 +1029,7 @@ mod test {
// unfold a vector of TestSC values into a SCTable,
// returning the resulting index
fn unfold_test_sc(tscs : ~[TestSC], tail: SyntaxContext, table : &mut SCTable)
fn unfold_test_sc(tscs : ~[TestSC], tail: SyntaxContext, table: &SCTable)
-> SyntaxContext {
tscs.rev_iter().fold(tail, |tail : SyntaxContext, tsc : &TestSC|
{match *tsc {
@ -1015,7 +1041,8 @@ mod test {
fn refold_test_sc(mut sc: SyntaxContext, table : &SCTable) -> ~[TestSC] {
let mut result = ~[];
loop {
match table.table[sc] {
let table = table.table.borrow();
match table.get()[sc] {
EmptyCtxt => {return result;},
Mark(mrk,tail) => {
result.push(M(mrk));
@ -1037,15 +1064,19 @@ mod test {
let test_sc = ~[M(3),R(id(101,0),14),M(9)];
assert_eq!(unfold_test_sc(test_sc.clone(),EMPTY_CTXT,&mut t),4);
assert_eq!(t.table[2],Mark(9,0));
assert_eq!(t.table[3],Rename(id(101,0),14,2));
assert_eq!(t.table[4],Mark(3,3));
{
let table = t.table.borrow();
assert_eq!(table.get()[2],Mark(9,0));
assert_eq!(table.get()[3],Rename(id(101,0),14,2));
assert_eq!(table.get()[4],Mark(3,3));
}
assert_eq!(refold_test_sc(4,&t),test_sc);
}
// extend a syntax context with a sequence of marks given
// in a vector. v[0] will be the outermost mark.
fn unfold_marks(mrks:~[Mrk],tail:SyntaxContext,table: &mut SCTable) -> SyntaxContext {
fn unfold_marks(mrks: ~[Mrk], tail: SyntaxContext, table: &SCTable)
-> SyntaxContext {
mrks.rev_iter().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
{new_mark_internal(*mrk,tail,table)})
}
@ -1054,8 +1085,11 @@ mod test {
let mut t = new_sctable_internal();
assert_eq!(unfold_marks(~[3,7],EMPTY_CTXT,&mut t),3);
assert_eq!(t.table[2],Mark(7,0));
assert_eq!(t.table[3],Mark(3,2));
{
let table = t.table.borrow();
assert_eq!(table.get()[2],Mark(7,0));
assert_eq!(table.get()[3],Mark(3,2));
}
}
#[test] fn test_marksof () {

View File

@ -355,8 +355,7 @@ pub fn find_stability<AM: AttrMetaMethods, It: Iterator<AM>>(mut metas: It) -> O
None
}
pub fn require_unique_names(diagnostic: @mut SpanHandler,
metas: &[@MetaItem]) {
pub fn require_unique_names(diagnostic: @SpanHandler, metas: &[@MetaItem]) {
let mut set = HashSet::new();
for meta in metas.iter() {
let name = meta.name();
@ -381,7 +380,7 @@ pub fn require_unique_names(diagnostic: @mut SpanHandler,
* present (before fields, if any) with that type; reprensentation
* optimizations which would remove it will not be done.
*/
pub fn find_repr_attr(diagnostic: @mut SpanHandler, attr: @ast::MetaItem, acc: ReprAttr)
pub fn find_repr_attr(diagnostic: @SpanHandler, attr: @ast::MetaItem, acc: ReprAttr)
-> ReprAttr {
let mut acc = acc;
match attr.node {

View File

@ -21,6 +21,7 @@ source code snippets, etc.
*/
use std::cell::RefCell;
use std::cmp;
use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
@ -220,9 +221,9 @@ pub struct FileMap {
/// The start position of this source in the CodeMap
start_pos: BytePos,
/// Locations of lines beginnings in the source code
lines: @mut ~[BytePos],
lines: RefCell<~[BytePos]>,
/// Locations of multi-byte characters in the source code
multibyte_chars: @mut ~[MultiByteChar],
multibyte_chars: RefCell<~[MultiByteChar]>,
}
impl FileMap {
@ -233,14 +234,16 @@ impl FileMap {
// about what ends a line between this file and parse.rs
pub fn next_line(&self, pos: BytePos) {
// the new charpos must be > the last one (or it's the first one).
let lines = &mut *self.lines;
assert!((lines.len() == 0) || (lines[lines.len() - 1] < pos))
lines.push(pos);
let mut lines = self.lines.borrow_mut();;
let line_len = lines.get().len();
assert!(line_len == 0 || (lines.get()[line_len - 1] < pos))
lines.get().push(pos);
}
// get a line from the list of pre-computed line-beginnings
pub fn get_line(&self, line: int) -> ~str {
let begin: BytePos = self.lines[line] - self.start_pos;
let mut lines = self.lines.borrow_mut();
let begin: BytePos = lines.get()[line] - self.start_pos;
let begin = begin.to_uint();
let slice = self.src.slice_from(begin);
match slice.find('\n') {
@ -255,7 +258,8 @@ impl FileMap {
pos: pos,
bytes: bytes,
};
self.multibyte_chars.push(mbc);
let mut multibyte_chars = self.multibyte_chars.borrow_mut();
multibyte_chars.get().push(mbc);
}
pub fn is_real_file(&self) -> bool {
@ -264,13 +268,13 @@ impl FileMap {
}
pub struct CodeMap {
files: @mut ~[@FileMap]
files: RefCell<~[@FileMap]>
}
impl CodeMap {
pub fn new() -> CodeMap {
CodeMap {
files: @mut ~[],
files: RefCell::new(~[]),
}
}
@ -284,23 +288,23 @@ impl CodeMap {
substr: FileSubstr,
src: @str)
-> @FileMap {
let files = &mut *self.files;
let start_pos = if files.len() == 0 {
let mut files = self.files.borrow_mut();
let start_pos = if files.get().len() == 0 {
0
} else {
let last_start = files.last().start_pos.to_uint();
let last_len = files.last().src.len();
let last_start = files.get().last().start_pos.to_uint();
let last_len = files.get().last().src.len();
last_start + last_len
};
let filemap = @FileMap {
name: filename, substr: substr, src: src,
start_pos: Pos::from_uint(start_pos),
lines: @mut ~[],
multibyte_chars: @mut ~[],
lines: RefCell::new(~[]),
multibyte_chars: RefCell::new(~[]),
};
files.push(filemap);
files.get().push(filemap);
return filemap;
}
@ -346,9 +350,11 @@ impl CodeMap {
}
pub fn span_to_str(&self, sp: Span) -> ~str {
let files = &*self.files;
if files.len() == 0 && sp == DUMMY_SP {
return ~"no-location";
{
let files = self.files.borrow();
if files.get().len() == 0 && sp == DUMMY_SP {
return ~"no-location";
}
}
let lo = self.lookup_char_pos_adj(sp.lo);
@ -388,7 +394,12 @@ impl CodeMap {
}
pub fn get_filemap(&self, filename: &str) -> @FileMap {
for fm in self.files.iter() { if filename == fm.name { return *fm; } }
let files = self.files.borrow();
for fm in files.get().iter() {
if filename == fm.name {
return *fm
}
}
//XXjdm the following triggers a mismatched type bug
// (or expected function, found _|_)
fail!(); // ("asking for " + filename + " which we don't know about");
@ -397,13 +408,14 @@ impl CodeMap {
impl CodeMap {
fn lookup_filemap_idx(&self, pos: BytePos) -> uint {
let files = &*self.files;
let files = self.files.borrow();
let files = files.get();
let len = files.len();
let mut a = 0u;
let mut b = len;
while b - a > 1u {
let m = (a + b) / 2u;
if self.files[m].start_pos > pos {
if files[m].start_pos > pos {
b = m;
} else {
a = m;
@ -419,13 +431,15 @@ impl CodeMap {
fn lookup_line(&self, pos: BytePos) -> FileMapAndLine
{
let idx = self.lookup_filemap_idx(pos);
let f = self.files[idx];
let files = self.files.borrow();
let f = files.get()[idx];
let mut a = 0u;
let lines = &*f.lines;
let mut b = lines.len();
let mut lines = f.lines.borrow_mut();
let mut b = lines.get().len();
while b - a > 1u {
let m = (a + b) / 2u;
if lines[m] > pos { b = m; } else { a = m; }
if lines.get()[m] > pos { b = m; } else { a = m; }
}
return FileMapAndLine {fm: f, line: a};
}
@ -434,7 +448,8 @@ impl CodeMap {
let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
let line = a + 1u; // Line numbers start at 1
let chpos = self.bytepos_to_local_charpos(pos);
let linebpos = f.lines[a];
let mut lines = f.lines.borrow_mut();
let linebpos = lines.get()[a];
let linechpos = self.bytepos_to_local_charpos(linebpos);
debug!("codemap: byte pos {:?} is on the line at byte pos {:?}",
pos, linebpos);
@ -452,7 +467,8 @@ impl CodeMap {
fn lookup_byte_offset(&self, bpos: BytePos)
-> FileMapAndBytePos {
let idx = self.lookup_filemap_idx(bpos);
let fm = self.files[idx];
let files = self.files.borrow();
let fm = files.get()[idx];
let offset = bpos - fm.start_pos;
return FileMapAndBytePos {fm: fm, pos: offset};
}
@ -462,12 +478,14 @@ impl CodeMap {
fn bytepos_to_local_charpos(&self, bpos: BytePos) -> CharPos {
debug!("codemap: converting {:?} to char pos", bpos);
let idx = self.lookup_filemap_idx(bpos);
let map = self.files[idx];
let files = self.files.borrow();
let map = files.get()[idx];
// The number of extra bytes due to multibyte chars in the FileMap
let mut total_extra_bytes = 0;
for mbc in map.multibyte_chars.iter() {
let multibyte_chars = map.multibyte_chars.borrow();
for mbc in multibyte_chars.get().iter() {
debug!("codemap: {:?}-byte char at {:?}", mbc.bytes, mbc.pos);
if mbc.pos < bpos {
total_extra_bytes += mbc.bytes;

View File

@ -11,6 +11,7 @@
use codemap::{Pos, Span};
use codemap;
use std::cell::Cell;
use std::io;
use std::io::stdio::StdWriter;
use std::local_data;
@ -30,32 +31,32 @@ pub trait Emitter {
// accepts span information for source-location
// reporting.
pub struct SpanHandler {
handler: @mut Handler,
handler: @Handler,
cm: @codemap::CodeMap,
}
impl SpanHandler {
pub fn span_fatal(@mut self, sp: Span, msg: &str) -> ! {
pub fn span_fatal(@self, sp: Span, msg: &str) -> ! {
self.handler.emit(Some((&*self.cm, sp)), msg, fatal);
fail!();
}
pub fn span_err(@mut self, sp: Span, msg: &str) {
pub fn span_err(@self, sp: Span, msg: &str) {
self.handler.emit(Some((&*self.cm, sp)), msg, error);
self.handler.bump_err_count();
}
pub fn span_warn(@mut self, sp: Span, msg: &str) {
pub fn span_warn(@self, sp: Span, msg: &str) {
self.handler.emit(Some((&*self.cm, sp)), msg, warning);
}
pub fn span_note(@mut self, sp: Span, msg: &str) {
pub fn span_note(@self, sp: Span, msg: &str) {
self.handler.emit(Some((&*self.cm, sp)), msg, note);
}
pub fn span_bug(@mut self, sp: Span, msg: &str) -> ! {
pub fn span_bug(@self, sp: Span, msg: &str) -> ! {
self.span_fatal(sp, ice_msg(msg));
}
pub fn span_unimpl(@mut self, sp: Span, msg: &str) -> ! {
pub fn span_unimpl(@self, sp: Span, msg: &str) -> ! {
self.span_bug(sp, ~"unimplemented " + msg);
}
pub fn handler(@mut self) -> @mut Handler {
pub fn handler(@self) -> @Handler {
self.handler
}
}
@ -64,53 +65,53 @@ impl SpanHandler {
// (fatal, bug, unimpl) may cause immediate exit,
// others log errors for later reporting.
pub struct Handler {
err_count: uint,
err_count: Cell<uint>,
emit: @Emitter,
}
impl Handler {
pub fn fatal(@mut self, msg: &str) -> ! {
pub fn fatal(@self, msg: &str) -> ! {
self.emit.emit(None, msg, fatal);
fail!();
}
pub fn err(@mut self, msg: &str) {
pub fn err(@self, msg: &str) {
self.emit.emit(None, msg, error);
self.bump_err_count();
}
pub fn bump_err_count(@mut self) {
self.err_count += 1u;
pub fn bump_err_count(@self) {
self.err_count.set(self.err_count.get() + 1u);
}
pub fn err_count(@mut self) -> uint {
self.err_count
pub fn err_count(@self) -> uint {
self.err_count.get()
}
pub fn has_errors(@mut self) -> bool {
self.err_count > 0u
pub fn has_errors(@self) -> bool {
self.err_count.get()> 0u
}
pub fn abort_if_errors(@mut self) {
pub fn abort_if_errors(@self) {
let s;
match self.err_count {
match self.err_count.get() {
0u => return,
1u => s = ~"aborting due to previous error",
_ => {
s = format!("aborting due to {} previous errors",
self.err_count);
self.err_count.get());
}
}
self.fatal(s);
}
pub fn warn(@mut self, msg: &str) {
pub fn warn(@self, msg: &str) {
self.emit.emit(None, msg, warning);
}
pub fn note(@mut self, msg: &str) {
pub fn note(@self, msg: &str) {
self.emit.emit(None, msg, note);
}
pub fn bug(@mut self, msg: &str) -> ! {
pub fn bug(@self, msg: &str) -> ! {
self.fatal(ice_msg(msg));
}
pub fn unimpl(@mut self, msg: &str) -> ! {
pub fn unimpl(@self, msg: &str) -> ! {
self.bug(~"unimplemented " + msg);
}
pub fn emit(@mut self,
pub fn emit(@self,
cmsp: Option<(&codemap::CodeMap, Span)>,
msg: &str,
lvl: level) {
@ -123,22 +124,22 @@ pub fn ice_msg(msg: &str) -> ~str {
\nWe would appreciate a bug report: {}", msg, BUG_REPORT_URL)
}
pub fn mk_span_handler(handler: @mut Handler, cm: @codemap::CodeMap)
-> @mut SpanHandler {
@mut SpanHandler {
pub fn mk_span_handler(handler: @Handler, cm: @codemap::CodeMap)
-> @SpanHandler {
@SpanHandler {
handler: handler,
cm: cm,
}
}
pub fn mk_handler(emitter: Option<@Emitter>) -> @mut Handler {
pub fn mk_handler(emitter: Option<@Emitter>) -> @Handler {
let emit: @Emitter = match emitter {
Some(e) => e,
None => @DefaultEmitter as @Emitter
};
@mut Handler {
err_count: 0,
@Handler {
err_count: Cell::new(0),
emit: emit,
}
}
@ -327,10 +328,7 @@ fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) {
}
}
pub fn expect<T:Clone>(
diag: @mut SpanHandler,
opt: Option<T>,
msg: || -> ~str)
pub fn expect<T:Clone>(diag: @SpanHandler, opt: Option<T>, msg: || -> ~str)
-> T {
match opt {
Some(ref t) => (*t).clone(),

View File

@ -284,7 +284,7 @@ pub fn syntax_expander_table() -> SyntaxEnv {
// when a macro expansion occurs, the resulting nodes have the backtrace()
// -> expn_info of their expansion context stored into their span.
pub struct ExtCtxt {
parse_sess: @mut parse::ParseSess,
parse_sess: @parse::ParseSess,
cfg: ast::CrateConfig,
backtrace: Option<@ExpnInfo>,
@ -293,7 +293,7 @@ pub struct ExtCtxt {
}
impl ExtCtxt {
pub fn new(parse_sess: @mut parse::ParseSess, cfg: ast::CrateConfig)
pub fn new(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig)
-> ExtCtxt {
ExtCtxt {
parse_sess: parse_sess,
@ -320,7 +320,7 @@ impl ExtCtxt {
}
pub fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
pub fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
pub fn parse_sess(&self) -> @parse::ParseSess { self.parse_sess }
pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
pub fn call_site(&self) -> Span {
match self.backtrace {

View File

@ -54,7 +54,7 @@ pub trait AstBuilder {
lifetime: Option<ast::Lifetime>,
mutbl: ast::Mutability) -> P<ast::Ty>;
fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>;
fn ty_box(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty>;
fn ty_box(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>;
fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
@ -311,12 +311,13 @@ impl AstBuilder for ExtCtxt {
self.ty(span,
ast::ty_rptr(lifetime, self.ty_mt(ty, mutbl)))
}
fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> {
self.ty(span, ast::ty_uniq(ty))
}
fn ty_box(&self, span: Span,
ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty> {
self.ty(span, ast::ty_box(self.ty_mt(ty, mutbl)))
fn ty_box(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> {
self.ty(span, ast::ty_box(ty))
}
fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
@ -494,7 +495,7 @@ impl AstBuilder for ExtCtxt {
}
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
self.expr_unary(sp, ast::UnBox(ast::MutImmutable), e)
self.expr_unary(sp, ast::UnBox, e)
}
fn expr_field_access(&self, sp: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr {

View File

@ -24,7 +24,7 @@ use opt_vec::OptVec;
/// The types of pointers
pub enum PtrTy<'a> {
Send, // ~
Managed(ast::Mutability), // @[mut]
Managed, // @
Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut]
}
@ -138,8 +138,8 @@ impl<'a> Ty<'a> {
Send => {
cx.ty_uniq(span, raw_ty)
}
Managed(mutbl) => {
cx.ty_box(span, raw_ty, mutbl)
Managed => {
cx.ty_box(span, raw_ty)
}
Borrowed(ref lt, mutbl) => {
let lt = mk_lifetime(cx, span, lt);
@ -251,7 +251,7 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
span,
match *ptr {
Send => ast::sty_uniq(ast::MutImmutable),
Managed(mutbl) => ast::sty_box(mutbl),
Managed => ast::sty_box(ast::MutImmutable),
Borrowed(ref lt, mutbl) => {
let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s)));
ast::sty_region(lt, mutbl)

View File

@ -493,13 +493,14 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
let mut name_finder = new_name_finder(~[]);
name_finder.visit_pat(expanded_pat,());
// generate fresh names, push them to a new pending list
let new_pending_renames = @mut ~[];
let mut new_pending_renames = ~[];
for ident in name_finder.ident_accumulator.iter() {
let new_name = fresh_name(ident);
new_pending_renames.push((*ident,new_name));
}
let rewritten_pat = {
let mut rename_fld = renames_to_fold(new_pending_renames);
let mut rename_fld =
renames_to_fold(&mut new_pending_renames);
// rewrite the pattern using the new names (the old ones
// have already been applied):
rename_fld.fold_pat(expanded_pat)
@ -889,7 +890,7 @@ impl ast_fold for Injector {
// add a bunch of macros as though they were placed at the head of the
// program (ick). This should run before cfg stripping.
pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
pub fn inject_std_macros(parse_sess: @parse::ParseSess,
cfg: ast::CrateConfig,
c: Crate)
-> Crate {
@ -939,7 +940,7 @@ impl<'a> ast_fold for MacroExpander<'a> {
}
}
pub fn expand_crate(parse_sess: @mut parse::ParseSess,
pub fn expand_crate(parse_sess: @parse::ParseSess,
cfg: ast::CrateConfig,
c: Crate) -> Crate {
let mut cx = ExtCtxt::new(parse_sess, cfg.clone());
@ -981,21 +982,6 @@ impl CtxtFn for Renamer {
}
}
// a renamer that performs a whole bunch of renames
pub struct MultiRenamer {
renames : @mut ~[(ast::Ident,ast::Name)]
}
impl CtxtFn for MultiRenamer {
fn f(&self, starting_ctxt : ast::SyntaxContext) -> ast::SyntaxContext {
// the individual elements are memoized... it would
// also be possible to memoize on the whole list at once.
self.renames.iter().fold(starting_ctxt,|ctxt,&(from,to)| {
new_rename(from,to,ctxt)
})
}
}
// a marker adds the given mark to the syntax context
pub struct Marker { mark : Mrk }
@ -1306,9 +1292,11 @@ mod test {
let a3_name = gensym("a3");
// a context that renames from ("a",empty) to "a2" :
let ctxt2 = new_rename(ast::Ident::new(a_name),a2_name,EMPTY_CTXT);
let pending_renames = @mut ~[(ast::Ident::new(a_name),a2_name),
(ast::Ident{name:a_name,ctxt:ctxt2},a3_name)];
let double_renamed = renames_to_fold(pending_renames).fold_crate(item_ast);
let mut pending_renames = ~[
(ast::Ident::new(a_name),a2_name),
(ast::Ident{name:a_name,ctxt:ctxt2},a3_name)
];
let double_renamed = renames_to_fold(&mut pending_renames).fold_crate(item_ast);
let mut path_finder = new_path_finder(~[]);
visit::walk_crate(&mut path_finder, &double_renamed, ());
match path_finder.path_accumulator {
@ -1318,11 +1306,11 @@ mod test {
}
}
fn fake_print_crate(crate: &ast::Crate) {
let out = @mut std::io::stderr() as @mut std::io::Writer;
let s = pprust::rust_printer(out, get_ident_interner());
pprust::print_crate_(s, crate);
}
//fn fake_print_crate(crate: &ast::Crate) {
// let mut out = ~std::io::stderr() as ~std::io::Writer;
// let mut s = pprust::rust_printer(out, get_ident_interner());
// pprust::print_crate_(&mut s, crate);
//}
fn expand_crate_str(crate_str: @str) -> ast::Crate {
let (crate_ast,ps) = string_to_crate_and_sess(crate_str);
@ -1516,8 +1504,12 @@ foo_module!()
mtwt_resolve(v.segments[0].identifier));
let table = get_sctable();
println("SC table:");
for (idx,val) in table.table.iter().enumerate() {
println!("{:4u} : {:?}",idx,val);
{
let table = table.table.borrow();
for (idx,val) in table.get().iter().enumerate() {
println!("{:4u} : {:?}",idx,val);
}
}
}
assert_eq!(mtwt_resolve(v.segments[0].identifier),resolved_binding);

View File

@ -19,6 +19,7 @@ use parse;
use parse::token::{get_ident_interner};
use print::pprust;
use std::cell::RefCell;
use std::io;
use std::io::File;
use std::str;
@ -108,13 +109,14 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::token_tree])
let s = s.to_managed();
// Add this input file to the code map to make it available as
// dependency information
cx.parse_sess.cm.files.push(@codemap::FileMap {
let mut files = cx.parse_sess.cm.files.borrow_mut();
files.get().push(@codemap::FileMap {
name: file.display().to_str().to_managed(),
substr: codemap::FssNone,
src: s,
start_pos: codemap::BytePos(0),
lines: @mut ~[],
multibyte_chars: @mut ~[],
lines: RefCell::new(~[]),
multibyte_chars: RefCell::new(~[]),
});
base::MRExpr(cx.expr_str(sp, s))
}

View File

@ -25,7 +25,7 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
None,
tt.to_owned());
let rdr = tt_rdr as @mut reader;
let rdr = tt_rdr as @reader;
let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup());
if rust_parser.is_keyword(keywords::True) {

View File

@ -188,9 +188,9 @@ pub enum named_match {
pub type earley_item = ~MatcherPos;
pub fn nameize(p_s: @mut ParseSess, ms: &[matcher], res: &[@named_match])
pub fn nameize(p_s: @ParseSess, ms: &[matcher], res: &[@named_match])
-> HashMap<Ident,@named_match> {
fn n_rec(p_s: @mut ParseSess, m: &matcher, res: &[@named_match],
fn n_rec(p_s: @ParseSess, m: &matcher, res: &[@named_match],
ret_val: &mut HashMap<Ident, @named_match>) {
match *m {
codemap::Spanned {node: match_tok(_), .. } => (),
@ -221,12 +221,11 @@ pub enum parse_result {
error(codemap::Span, ~str)
}
pub fn parse_or_else(
sess: @mut ParseSess,
cfg: ast::CrateConfig,
rdr: @mut reader,
ms: ~[matcher]
) -> HashMap<Ident, @named_match> {
pub fn parse_or_else(sess: @ParseSess,
cfg: ast::CrateConfig,
rdr: @reader,
ms: ~[matcher])
-> HashMap<Ident, @named_match> {
match parse(sess, cfg, rdr, ms) {
success(m) => m,
failure(sp, str) => sess.span_diagnostic.span_fatal(sp, str),
@ -243,12 +242,11 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
}
}
pub fn parse(
sess: @mut ParseSess,
cfg: ast::CrateConfig,
rdr: @mut reader,
ms: &[matcher]
) -> parse_result {
pub fn parse(sess: @ParseSess,
cfg: ast::CrateConfig,
rdr: @reader,
ms: &[matcher])
-> parse_result {
let mut cur_eis = ~[];
cur_eis.push(initial_matcher_pos(ms.to_owned(), None, rdr.peek().sp.lo));

View File

@ -130,11 +130,7 @@ fn generic_extension(cx: &ExtCtxt,
match *lhs {
@matched_nonterminal(nt_matchers(ref mtcs)) => {
// `none` is because we're not interpolating
let arg_rdr = new_tt_reader(
s_d,
None,
arg.to_owned()
) as @mut reader;
let arg_rdr = new_tt_reader(s_d, None, arg.to_owned()) as @reader;
match parse(cx.parse_sess(), cx.cfg(), arg_rdr, *mtcs) {
success(named_matches) => {
let rhs = match rhses[i] {
@ -154,10 +150,7 @@ fn generic_extension(cx: &ExtCtxt,
// rhs has holes ( `$id` and `$(...)` that need filled)
let trncbr = new_tt_reader(s_d, Some(named_matches),
rhs);
let p = Parser(cx.parse_sess(),
cx.cfg(),
trncbr as @mut reader);
let p = Parser(cx.parse_sess(), cx.cfg(), trncbr as @reader);
// Let the context choose how to interpret the result.
// Weird, but useful for X-macros.
return MRAny(@ParserAnyMacro {
@ -218,7 +211,7 @@ pub fn add_new_extension(cx: &mut ExtCtxt,
arg.clone());
let argument_map = parse_or_else(cx.parse_sess(),
cx.cfg(),
arg_reader as @mut reader,
arg_reader as @reader,
argument_gram);
// Extract the arguments:

View File

@ -17,65 +17,66 @@ use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident};
use parse::token::{ident_to_str};
use parse::lexer::TokenAndSpan;
use std::cell::{Cell, RefCell};
use std::hashmap::HashMap;
use std::option;
///an unzipping of `token_tree`s
struct TtFrame {
forest: @~[ast::token_tree],
idx: uint,
idx: Cell<uint>,
dotdotdoted: bool,
sep: Option<Token>,
up: Option<@mut TtFrame>,
up: Option<@TtFrame>,
}
pub struct TtReader {
sp_diag: @mut SpanHandler,
sp_diag: @SpanHandler,
// the unzipped tree:
stack: @mut TtFrame,
priv stack: RefCell<@TtFrame>,
/* for MBE-style macro transcription */
interpolations: HashMap<Ident, @named_match>,
repeat_idx: ~[uint],
repeat_len: ~[uint],
priv interpolations: RefCell<HashMap<Ident, @named_match>>,
priv repeat_idx: RefCell<~[uint]>,
priv repeat_len: RefCell<~[uint]>,
/* cached: */
cur_tok: Token,
cur_span: Span
cur_tok: RefCell<Token>,
cur_span: RefCell<Span>,
}
/** This can do Macro-By-Example transcription. On the other hand, if
* `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
* should) be none. */
pub fn new_tt_reader(sp_diag: @mut SpanHandler,
pub fn new_tt_reader(sp_diag: @SpanHandler,
interp: Option<HashMap<Ident,@named_match>>,
src: ~[ast::token_tree])
-> @mut TtReader {
let r = @mut TtReader {
-> @TtReader {
let r = @TtReader {
sp_diag: sp_diag,
stack: @mut TtFrame {
stack: RefCell::new(@TtFrame {
forest: @src,
idx: 0u,
idx: Cell::new(0u),
dotdotdoted: false,
sep: None,
up: option::None
},
}),
interpolations: match interp { /* just a convienience */
None => HashMap::new(),
Some(x) => x
None => RefCell::new(HashMap::new()),
Some(x) => RefCell::new(x),
},
repeat_idx: ~[],
repeat_len: ~[],
repeat_idx: RefCell::new(~[]),
repeat_len: RefCell::new(~[]),
/* dummy values, never read: */
cur_tok: EOF,
cur_span: DUMMY_SP
cur_tok: RefCell::new(EOF),
cur_span: RefCell::new(DUMMY_SP),
};
tt_next_token(r); /* get cur_tok and cur_span set up */
return r;
}
fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame {
@mut TtFrame {
fn dup_tt_frame(f: @TtFrame) -> @TtFrame {
@TtFrame {
forest: @(*f.forest).clone(),
idx: f.idx,
idx: f.idx.clone(),
dotdotdoted: f.dotdotdoted,
sep: f.sep.clone(),
up: match f.up {
@ -85,22 +86,21 @@ fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame {
}
}
pub fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader {
@mut TtReader {
pub fn dup_tt_reader(r: @TtReader) -> @TtReader {
@TtReader {
sp_diag: r.sp_diag,
stack: dup_tt_frame(r.stack),
stack: RefCell::new(dup_tt_frame(r.stack.get())),
repeat_idx: r.repeat_idx.clone(),
repeat_len: r.repeat_len.clone(),
cur_tok: r.cur_tok.clone(),
cur_span: r.cur_span,
cur_span: r.cur_span.clone(),
interpolations: r.interpolations.clone(),
}
}
fn lookup_cur_matched_by_matched(r: &mut TtReader,
start: @named_match)
-> @named_match {
fn lookup_cur_matched_by_matched(r: &TtReader, start: @named_match)
-> @named_match {
fn red(ad: @named_match, idx: &uint) -> @named_match {
match *ad {
matched_nonterminal(_) => {
@ -110,15 +110,21 @@ fn lookup_cur_matched_by_matched(r: &mut TtReader,
matched_seq(ref ads, _) => ads[*idx]
}
}
r.repeat_idx.iter().fold(start, red)
let repeat_idx = r.repeat_idx.borrow();
repeat_idx.get().iter().fold(start, red)
}
fn lookup_cur_matched(r: &mut TtReader, name: Ident) -> @named_match {
match r.interpolations.find_copy(&name) {
fn lookup_cur_matched(r: &TtReader, name: Ident) -> @named_match {
let matched_opt = {
let interpolations = r.interpolations.borrow();
interpolations.get().find_copy(&name)
};
match matched_opt {
Some(s) => lookup_cur_matched_by_matched(r, s),
None => {
r.sp_diag.span_fatal(r.cur_span, format!("unknown macro variable `{}`",
ident_to_str(&name)));
r.sp_diag.span_fatal(r.cur_span.get(),
format!("unknown macro variable `{}`",
ident_to_str(&name)));
}
}
}
@ -130,7 +136,7 @@ enum lis {
lis_contradiction(~str),
}
fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis {
fn lockstep_iter_size(t: &token_tree, r: &TtReader) -> lis {
fn lis_merge(lhs: lis, rhs: lis) -> lis {
match lhs {
lis_unconstrained => rhs.clone(),
@ -166,46 +172,56 @@ fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis {
// return the next token from the TtReader.
// EFFECT: advances the reader's token field
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
pub fn tt_next_token(r: &TtReader) -> TokenAndSpan {
// XXX(pcwalton): Bad copy?
let ret_val = TokenAndSpan {
tok: r.cur_tok.clone(),
sp: r.cur_span,
tok: r.cur_tok.get(),
sp: r.cur_span.get(),
};
loop {
{
let stack = &mut *r.stack;
if stack.idx < stack.forest.len() {
let mut stack = r.stack.borrow_mut();
if stack.get().idx.get() < stack.get().forest.len() {
break;
}
}
/* done with this set; pop or repeat? */
if ! r.stack.dotdotdoted
|| { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } {
if !r.stack.get().dotdotdoted || {
let repeat_idx = r.repeat_idx.borrow();
let repeat_len = r.repeat_len.borrow();
*repeat_idx.get().last() == *repeat_len.get().last() - 1
} {
match r.stack.up {
match r.stack.get().up {
None => {
r.cur_tok = EOF;
r.cur_tok.set(EOF);
return ret_val;
}
Some(tt_f) => {
if r.stack.dotdotdoted {
r.repeat_idx.pop();
r.repeat_len.pop();
if r.stack.get().dotdotdoted {
{
let mut repeat_idx = r.repeat_idx.borrow_mut();
let mut repeat_len = r.repeat_len.borrow_mut();
repeat_idx.get().pop();
repeat_len.get().pop();
}
}
r.stack = tt_f;
r.stack.idx += 1u;
r.stack.set(tt_f);
r.stack.get().idx.set(r.stack.get().idx.get() + 1u);
}
}
} else { /* repeat */
r.stack.idx = 0u;
r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
match r.stack.sep.clone() {
r.stack.get().idx.set(0u);
{
let mut repeat_idx = r.repeat_idx.borrow_mut();
repeat_idx.get()[repeat_idx.get().len() - 1u] += 1u;
}
match r.stack.get().sep.clone() {
Some(tk) => {
r.cur_tok = tk; /* repeat same span, I guess */
r.cur_tok.set(tk); /* repeat same span, I guess */
return ret_val;
}
None => ()
@ -215,21 +231,21 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
loop { /* because it's easiest, this handles `tt_delim` not starting
with a `tt_tok`, even though it won't happen */
// XXX(pcwalton): Bad copy.
match r.stack.forest[r.stack.idx].clone() {
match r.stack.get().forest[r.stack.get().idx.get()].clone() {
tt_delim(tts) => {
r.stack = @mut TtFrame {
r.stack.set(@TtFrame {
forest: tts,
idx: 0u,
idx: Cell::new(0u),
dotdotdoted: false,
sep: None,
up: option::Some(r.stack)
};
up: option::Some(r.stack.get())
});
// if this could be 0-length, we'd need to potentially recur here
}
tt_tok(sp, tok) => {
r.cur_span = sp;
r.cur_tok = tok;
r.stack.idx += 1u;
r.cur_span.set(sp);
r.cur_tok.set(tok);
r.stack.get().idx.set(r.stack.get().idx.get() + 1u);
return ret_val;
}
tt_seq(sp, tts, sep, zerok) => {
@ -256,18 +272,22 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
once");
}
r.stack.idx += 1u;
r.stack.get().idx.set(r.stack.get().idx.get() + 1u);
return tt_next_token(r);
} else {
r.repeat_len.push(len);
r.repeat_idx.push(0u);
r.stack = @mut TtFrame {
forest: tts,
idx: 0u,
dotdotdoted: true,
sep: sep,
up: Some(r.stack)
};
{
let mut repeat_idx = r.repeat_idx.borrow_mut();
let mut repeat_len = r.repeat_len.borrow_mut();
repeat_len.get().push(len);
repeat_idx.get().push(0u);
r.stack.set(@TtFrame {
forest: tts,
idx: Cell::new(0u),
dotdotdoted: true,
sep: sep,
up: Some(r.stack.get())
});
}
}
}
}
@ -279,20 +299,21 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
(a) idents can be in lots of places, so it'd be a pain
(b) we actually can, since it's a token. */
matched_nonterminal(nt_ident(~sn,b)) => {
r.cur_span = sp; r.cur_tok = IDENT(sn,b);
r.stack.idx += 1u;
r.cur_span.set(sp);
r.cur_tok.set(IDENT(sn,b));
r.stack.get().idx.set(r.stack.get().idx.get() + 1u);
return ret_val;
}
matched_nonterminal(ref other_whole_nt) => {
// XXX(pcwalton): Bad copy.
r.cur_span = sp;
r.cur_tok = INTERPOLATED((*other_whole_nt).clone());
r.stack.idx += 1u;
r.cur_span.set(sp);
r.cur_tok.set(INTERPOLATED((*other_whole_nt).clone()));
r.stack.get().idx.set(r.stack.get().idx.get() + 1u);
return ret_val;
}
matched_seq(..) => {
r.sp_diag.span_fatal(
r.cur_span, /* blame the macro writer */
r.cur_span.get(), /* blame the macro writer */
format!("variable '{}' is still repeating at this depth",
ident_to_str(&ident)));
}

View File

@ -238,7 +238,7 @@ pub trait ast_fold {
fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
let node = match t.node {
ty_nil | ty_bot | ty_infer => t.node.clone(),
ty_box(ref mt) => ty_box(fold_mt(mt, self)),
ty_box(ty) => ty_box(self.fold_ty(ty)),
ty_uniq(ty) => ty_uniq(self.fold_ty(ty)),
ty_vec(ty) => ty_vec(self.fold_ty(ty)),
ty_ptr(ref mt) => ty_ptr(fold_mt(mt, self)),
@ -866,7 +866,7 @@ mod test {
use super::*;
// this version doesn't care about getting comments or docstrings in.
fn fake_print_crate(s: @pprust::ps, crate: &ast::Crate) {
fn fake_print_crate(s: &mut pprust::ps, crate: &ast::Crate) {
pprust::print_mod(s, &crate.module, crate.attrs);
}

View File

@ -135,39 +135,44 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
fail!("not a doc-comment: {}", comment);
}
fn read_to_eol(rdr: @mut StringReader) -> ~str {
fn read_to_eol(rdr: @StringReader) -> ~str {
let mut val = ~"";
while rdr.curr != '\n' && !is_eof(rdr) {
val.push_char(rdr.curr);
while rdr.curr.get() != '\n' && !is_eof(rdr) {
val.push_char(rdr.curr.get());
bump(rdr);
}
if rdr.curr == '\n' { bump(rdr); }
if rdr.curr.get() == '\n' { bump(rdr); }
return val;
}
fn read_one_line_comment(rdr: @mut StringReader) -> ~str {
fn read_one_line_comment(rdr: @StringReader) -> ~str {
let val = read_to_eol(rdr);
assert!((val[0] == '/' as u8 && val[1] == '/' as u8) ||
(val[0] == '#' as u8 && val[1] == '!' as u8));
return val;
}
fn consume_non_eol_whitespace(rdr: @mut StringReader) {
while is_whitespace(rdr.curr) && rdr.curr != '\n' && !is_eof(rdr) {
fn consume_non_eol_whitespace(rdr: @StringReader) {
while is_whitespace(rdr.curr.get()) && rdr.curr.get() != '\n' &&
!is_eof(rdr) {
bump(rdr);
}
}
fn push_blank_line_comment(rdr: @mut StringReader, comments: &mut ~[cmnt]) {
fn push_blank_line_comment(rdr: @StringReader, comments: &mut ~[cmnt]) {
debug!(">>> blank-line comment");
let v: ~[~str] = ~[];
comments.push(cmnt {style: blank_line, lines: v, pos: rdr.last_pos});
comments.push(cmnt {
style: blank_line,
lines: v,
pos: rdr.last_pos.get(),
});
}
fn consume_whitespace_counting_blank_lines(rdr: @mut StringReader,
fn consume_whitespace_counting_blank_lines(rdr: @StringReader,
comments: &mut ~[cmnt]) {
while is_whitespace(rdr.curr) && !is_eof(rdr) {
if rdr.col == CharPos(0u) && rdr.curr == '\n' {
while is_whitespace(rdr.curr.get()) && !is_eof(rdr) {
if rdr.col.get() == CharPos(0u) && rdr.curr.get() == '\n' {
push_blank_line_comment(rdr, &mut *comments);
}
bump(rdr);
@ -175,10 +180,10 @@ fn consume_whitespace_counting_blank_lines(rdr: @mut StringReader,
}
fn read_shebang_comment(rdr: @mut StringReader, code_to_the_left: bool,
fn read_shebang_comment(rdr: @StringReader, code_to_the_left: bool,
comments: &mut ~[cmnt]) {
debug!(">>> shebang comment");
let p = rdr.last_pos;
let p = rdr.last_pos.get();
debug!("<<< shebang comment");
comments.push(cmnt {
style: if code_to_the_left { trailing } else { isolated },
@ -187,12 +192,12 @@ fn read_shebang_comment(rdr: @mut StringReader, code_to_the_left: bool,
});
}
fn read_line_comments(rdr: @mut StringReader, code_to_the_left: bool,
fn read_line_comments(rdr: @StringReader, code_to_the_left: bool,
comments: &mut ~[cmnt]) {
debug!(">>> line comments");
let p = rdr.last_pos;
let p = rdr.last_pos.get();
let mut lines: ~[~str] = ~[];
while rdr.curr == '/' && nextch(rdr) == '/' {
while rdr.curr.get() == '/' && nextch(rdr) == '/' {
let line = read_one_line_comment(rdr);
debug!("{}", line);
if is_doc_comment(line) { // doc-comments are not put in comments
@ -244,22 +249,22 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
lines.push(s1);
}
fn read_block_comment(rdr: @mut StringReader,
fn read_block_comment(rdr: @StringReader,
code_to_the_left: bool,
comments: &mut ~[cmnt]) {
debug!(">>> block comment");
let p = rdr.last_pos;
let p = rdr.last_pos.get();
let mut lines: ~[~str] = ~[];
let col: CharPos = rdr.col;
let col: CharPos = rdr.col.get();
bump(rdr);
bump(rdr);
let mut curr_line = ~"/*";
// doc-comments are not really comments, they are attributes
if rdr.curr == '*' || rdr.curr == '!' {
while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) {
curr_line.push_char(rdr.curr);
if rdr.curr.get() == '*' || rdr.curr.get() == '!' {
while !(rdr.curr.get() == '*' && nextch(rdr) == '/') && !is_eof(rdr) {
curr_line.push_char(rdr.curr.get());
bump(rdr);
}
if !is_eof(rdr) {
@ -275,22 +280,22 @@ fn read_block_comment(rdr: @mut StringReader,
while level > 0 {
debug!("=== block comment level {}", level);
if is_eof(rdr) {
(rdr as @mut reader).fatal(~"unterminated block comment");
(rdr as @reader).fatal(~"unterminated block comment");
}
if rdr.curr == '\n' {
if rdr.curr.get() == '\n' {
trim_whitespace_prefix_and_push_line(&mut lines, curr_line,
col);
curr_line = ~"";
bump(rdr);
} else {
curr_line.push_char(rdr.curr);
if rdr.curr == '/' && nextch(rdr) == '*' {
curr_line.push_char(rdr.curr.get());
if rdr.curr.get() == '/' && nextch(rdr) == '*' {
bump(rdr);
bump(rdr);
curr_line.push_char('*');
level += 1;
} else {
if rdr.curr == '*' && nextch(rdr) == '/' {
if rdr.curr.get() == '*' && nextch(rdr) == '/' {
bump(rdr);
bump(rdr);
curr_line.push_char('/');
@ -306,28 +311,28 @@ fn read_block_comment(rdr: @mut StringReader,
let mut style = if code_to_the_left { trailing } else { isolated };
consume_non_eol_whitespace(rdr);
if !is_eof(rdr) && rdr.curr != '\n' && lines.len() == 1u {
if !is_eof(rdr) && rdr.curr.get() != '\n' && lines.len() == 1u {
style = mixed;
}
debug!("<<< block comment");
comments.push(cmnt {style: style, lines: lines, pos: p});
}
fn peeking_at_comment(rdr: @mut StringReader) -> bool {
return ((rdr.curr == '/' && nextch(rdr) == '/') ||
(rdr.curr == '/' && nextch(rdr) == '*')) ||
(rdr.curr == '#' && nextch(rdr) == '!');
fn peeking_at_comment(rdr: @StringReader) -> bool {
return ((rdr.curr.get() == '/' && nextch(rdr) == '/') ||
(rdr.curr.get() == '/' && nextch(rdr) == '*')) ||
(rdr.curr.get() == '#' && nextch(rdr) == '!');
}
fn consume_comment(rdr: @mut StringReader,
fn consume_comment(rdr: @StringReader,
code_to_the_left: bool,
comments: &mut ~[cmnt]) {
debug!(">>> consume comment");
if rdr.curr == '/' && nextch(rdr) == '/' {
if rdr.curr.get() == '/' && nextch(rdr) == '/' {
read_line_comments(rdr, code_to_the_left, comments);
} else if rdr.curr == '/' && nextch(rdr) == '*' {
} else if rdr.curr.get() == '/' && nextch(rdr) == '*' {
read_block_comment(rdr, code_to_the_left, comments);
} else if rdr.curr == '#' && nextch(rdr) == '!' {
} else if rdr.curr.get() == '#' && nextch(rdr) == '!' {
read_shebang_comment(rdr, code_to_the_left, comments);
} else { fail!(); }
debug!("<<< consume comment");
@ -342,7 +347,7 @@ pub struct lit {
// it appears this function is called only from pprust... that's
// probably not a good thing.
pub fn gather_comments_and_literals(span_diagnostic:
@mut diagnostic::SpanHandler,
@diagnostic::SpanHandler,
path: @str,
srdr: &mut io::Reader)
-> (~[cmnt], ~[lit]) {
@ -358,7 +363,7 @@ pub fn gather_comments_and_literals(span_diagnostic:
loop {
let mut code_to_the_left = !first_read;
consume_non_eol_whitespace(rdr);
if rdr.curr == '\n' {
if rdr.curr.get() == '\n' {
code_to_the_left = false;
consume_whitespace_counting_blank_lines(rdr, &mut comments);
}
@ -370,7 +375,7 @@ pub fn gather_comments_and_literals(span_diagnostic:
}
let bstart = rdr.last_pos;
let bstart = rdr.last_pos.get();
rdr.next_token();
//discard, and look ahead; we're working with internal state
let TokenAndSpan {tok: tok, sp: sp} = rdr.peek();

View File

@ -18,6 +18,7 @@ use parse::token;
use parse::token::{str_to_ident};
use std::cast::transmute;
use std::cell::{Cell, RefCell};
use std::char;
use std::num::from_str_radix;
use std::util;
@ -25,12 +26,12 @@ use std::util;
pub use ext::tt::transcribe::{TtReader, new_tt_reader};
pub trait reader {
fn is_eof(@mut self) -> bool;
fn next_token(@mut self) -> TokenAndSpan;
fn fatal(@mut self, ~str) -> !;
fn span_diag(@mut self) -> @mut SpanHandler;
fn peek(@mut self) -> TokenAndSpan;
fn dup(@mut self) -> @mut reader;
fn is_eof(@self) -> bool;
fn next_token(@self) -> TokenAndSpan;
fn fatal(@self, ~str) -> !;
fn span_diag(@self) -> @SpanHandler;
fn peek(@self) -> TokenAndSpan;
fn dup(@self) -> @reader;
}
#[deriving(Clone, Eq)]
@ -40,47 +41,47 @@ pub struct TokenAndSpan {
}
pub struct StringReader {
span_diagnostic: @mut SpanHandler,
span_diagnostic: @SpanHandler,
src: @str,
// The absolute offset within the codemap of the next character to read
pos: BytePos,
pos: Cell<BytePos>,
// The absolute offset within the codemap of the last character read(curr)
last_pos: BytePos,
last_pos: Cell<BytePos>,
// The column of the next character to read
col: CharPos,
col: Cell<CharPos>,
// The last character to be read
curr: char,
curr: Cell<char>,
filemap: @codemap::FileMap,
/* cached: */
peek_tok: token::Token,
peek_span: Span
peek_tok: RefCell<token::Token>,
peek_span: RefCell<Span>,
}
pub fn new_string_reader(span_diagnostic: @mut SpanHandler,
pub fn new_string_reader(span_diagnostic: @SpanHandler,
filemap: @codemap::FileMap)
-> @mut StringReader {
-> @StringReader {
let r = new_low_level_string_reader(span_diagnostic, filemap);
string_advance_token(r); /* fill in peek_* */
return r;
}
/* For comments.rs, which hackily pokes into 'pos' and 'curr' */
pub fn new_low_level_string_reader(span_diagnostic: @mut SpanHandler,
pub fn new_low_level_string_reader(span_diagnostic: @SpanHandler,
filemap: @codemap::FileMap)
-> @mut StringReader {
-> @StringReader {
// Force the initial reader bump to start on a fresh line
let initial_char = '\n';
let r = @mut StringReader {
let r = @StringReader {
span_diagnostic: span_diagnostic,
src: filemap.src,
pos: filemap.start_pos,
last_pos: filemap.start_pos,
col: CharPos(0),
curr: initial_char,
pos: Cell::new(filemap.start_pos),
last_pos: Cell::new(filemap.start_pos),
col: Cell::new(CharPos(0)),
curr: Cell::new(initial_char),
filemap: filemap,
/* dummy values; not read */
peek_tok: token::EOF,
peek_span: codemap::DUMMY_SP
peek_tok: RefCell::new(token::EOF),
peek_span: RefCell::new(codemap::DUMMY_SP),
};
bump(r);
return r;
@ -89,78 +90,84 @@ pub fn new_low_level_string_reader(span_diagnostic: @mut SpanHandler,
// duplicating the string reader is probably a bad idea, in
// that using them will cause interleaved pushes of line
// offsets to the underlying filemap...
fn dup_string_reader(r: @mut StringReader) -> @mut StringReader {
@mut StringReader {
fn dup_string_reader(r: @StringReader) -> @StringReader {
@StringReader {
span_diagnostic: r.span_diagnostic,
src: r.src,
pos: r.pos,
last_pos: r.last_pos,
col: r.col,
curr: r.curr,
pos: Cell::new(r.pos.get()),
last_pos: Cell::new(r.last_pos.get()),
col: Cell::new(r.col.get()),
curr: Cell::new(r.curr.get()),
filemap: r.filemap,
peek_tok: r.peek_tok.clone(),
peek_span: r.peek_span
peek_span: r.peek_span.clone(),
}
}
impl reader for StringReader {
fn is_eof(@mut self) -> bool { is_eof(self) }
fn is_eof(@self) -> bool { is_eof(self) }
// return the next token. EFFECT: advances the string_reader.
fn next_token(@mut self) -> TokenAndSpan {
let ret_val = TokenAndSpan {
tok: util::replace(&mut self.peek_tok, token::UNDERSCORE),
sp: self.peek_span,
fn next_token(@self) -> TokenAndSpan {
let ret_val = {
let mut peek_tok = self.peek_tok.borrow_mut();
TokenAndSpan {
tok: util::replace(peek_tok.get(), token::UNDERSCORE),
sp: self.peek_span.get(),
}
};
string_advance_token(self);
ret_val
}
fn fatal(@mut self, m: ~str) -> ! {
self.span_diagnostic.span_fatal(self.peek_span, m)
fn fatal(@self, m: ~str) -> ! {
self.span_diagnostic.span_fatal(self.peek_span.get(), m)
}
fn span_diag(@mut self) -> @mut SpanHandler { self.span_diagnostic }
fn peek(@mut self) -> TokenAndSpan {
fn span_diag(@self) -> @SpanHandler { self.span_diagnostic }
fn peek(@self) -> TokenAndSpan {
// XXX(pcwalton): Bad copy!
TokenAndSpan {
tok: self.peek_tok.clone(),
sp: self.peek_span,
tok: self.peek_tok.get(),
sp: self.peek_span.get(),
}
}
fn dup(@mut self) -> @mut reader { dup_string_reader(self) as @mut reader }
fn dup(@self) -> @reader { dup_string_reader(self) as @reader }
}
impl reader for TtReader {
fn is_eof(@mut self) -> bool { self.cur_tok == token::EOF }
fn next_token(@mut self) -> TokenAndSpan {
fn is_eof(@self) -> bool {
let cur_tok = self.cur_tok.borrow();
*cur_tok.get() == token::EOF
}
fn next_token(@self) -> TokenAndSpan {
let r = tt_next_token(self);
debug!("TtReader: r={:?}", r);
return r;
}
fn fatal(@mut self, m: ~str) -> ! {
self.sp_diag.span_fatal(self.cur_span, m);
fn fatal(@self, m: ~str) -> ! {
self.sp_diag.span_fatal(self.cur_span.get(), m);
}
fn span_diag(@mut self) -> @mut SpanHandler { self.sp_diag }
fn peek(@mut self) -> TokenAndSpan {
fn span_diag(@self) -> @SpanHandler { self.sp_diag }
fn peek(@self) -> TokenAndSpan {
TokenAndSpan {
tok: self.cur_tok.clone(),
sp: self.cur_span,
tok: self.cur_tok.get(),
sp: self.cur_span.get(),
}
}
fn dup(@mut self) -> @mut reader { dup_tt_reader(self) as @mut reader }
fn dup(@self) -> @reader { dup_tt_reader(self) as @reader }
}
// report a lexical error spanning [`from_pos`, `to_pos`)
fn fatal_span(rdr: @mut StringReader,
fn fatal_span(rdr: @StringReader,
from_pos: BytePos,
to_pos: BytePos,
m: ~str)
-> ! {
rdr.peek_span = codemap::mk_sp(from_pos, to_pos);
rdr.peek_span.set(codemap::mk_sp(from_pos, to_pos));
rdr.fatal(m);
}
// report a lexical error spanning [`from_pos`, `to_pos`), appending an
// escaped character to the error message
fn fatal_span_char(rdr: @mut StringReader,
fn fatal_span_char(rdr: @StringReader,
from_pos: BytePos,
to_pos: BytePos,
m: ~str,
@ -174,7 +181,7 @@ fn fatal_span_char(rdr: @mut StringReader,
// report a lexical error spanning [`from_pos`, `to_pos`), appending the
// offending string to the error message
fn fatal_span_verbose(rdr: @mut StringReader,
fn fatal_span_verbose(rdr: @StringReader,
from_pos: BytePos,
to_pos: BytePos,
m: ~str)
@ -190,19 +197,20 @@ fn fatal_span_verbose(rdr: @mut StringReader,
// EFFECT: advance peek_tok and peek_span to refer to the next token.
// EFFECT: update the interner, maybe.
fn string_advance_token(r: @mut StringReader) {
fn string_advance_token(r: @StringReader) {
match (consume_whitespace_and_comments(r)) {
Some(comment) => {
r.peek_span = comment.sp;
r.peek_tok = comment.tok;
r.peek_span.set(comment.sp);
r.peek_tok.set(comment.tok);
},
None => {
if is_eof(r) {
r.peek_tok = token::EOF;
r.peek_tok.set(token::EOF);
} else {
let start_bytepos = r.last_pos;
r.peek_tok = next_token_inner(r);
r.peek_span = codemap::mk_sp(start_bytepos, r.last_pos);
let start_bytepos = r.last_pos.get();
r.peek_tok.set(next_token_inner(r));
r.peek_span.set(codemap::mk_sp(start_bytepos,
r.last_pos.get()));
};
}
}
@ -216,17 +224,17 @@ fn byte_offset(rdr: &StringReader, pos: BytePos) -> BytePos {
/// up to but excluding `rdr.last_pos`, meaning the slice does not include
/// the character `rdr.curr`.
pub fn with_str_from<T>(
rdr: @mut StringReader,
rdr: @StringReader,
start: BytePos,
f: |s: &str| -> T)
-> T {
with_str_from_to(rdr, start, rdr.last_pos, f)
with_str_from_to(rdr, start, rdr.last_pos.get(), f)
}
/// Calls `f` with astring slice of the source text spanning from `start`
/// up to but excluding `end`.
fn with_str_from_to<T>(
rdr: @mut StringReader,
rdr: @StringReader,
start: BytePos,
end: BytePos,
f: |s: &str| -> T)
@ -238,20 +246,22 @@ fn with_str_from_to<T>(
// EFFECT: advance the StringReader by one character. If a newline is
// discovered, add it to the FileMap's list of line start offsets.
pub fn bump(rdr: &mut StringReader) {
rdr.last_pos = rdr.pos;
let current_byte_offset = byte_offset(rdr, rdr.pos).to_uint();
pub fn bump(rdr: &StringReader) {
rdr.last_pos.set(rdr.pos.get());
let current_byte_offset = byte_offset(rdr, rdr.pos.get()).to_uint();
if current_byte_offset < (rdr.src).len() {
assert!(rdr.curr != unsafe { transmute(-1u32) }); // FIXME: #8971: unsound
let last_char = rdr.curr;
assert!(rdr.curr.get() != unsafe {
transmute(-1u32)
}); // FIXME: #8971: unsound
let last_char = rdr.curr.get();
let next = rdr.src.char_range_at(current_byte_offset);
let byte_offset_diff = next.next - current_byte_offset;
rdr.pos = rdr.pos + Pos::from_uint(byte_offset_diff);
rdr.curr = next.ch;
rdr.col = rdr.col + CharPos(1u);
rdr.pos.set(rdr.pos.get() + Pos::from_uint(byte_offset_diff));
rdr.curr.set(next.ch);
rdr.col.set(rdr.col.get() + CharPos(1u));
if last_char == '\n' {
rdr.filemap.next_line(rdr.last_pos);
rdr.col = CharPos(0u);
rdr.filemap.next_line(rdr.last_pos.get());
rdr.col.set(CharPos(0u));
}
if byte_offset_diff > 1 {
@ -259,14 +269,14 @@ pub fn bump(rdr: &mut StringReader) {
Pos::from_uint(current_byte_offset), byte_offset_diff);
}
} else {
rdr.curr = unsafe { transmute(-1u32) }; // FIXME: #8971: unsound
rdr.curr.set(unsafe { transmute(-1u32) }); // FIXME: #8971: unsound
}
}
pub fn is_eof(rdr: @mut StringReader) -> bool {
rdr.curr == unsafe { transmute(-1u32) } // FIXME: #8971: unsound
pub fn is_eof(rdr: @StringReader) -> bool {
rdr.curr.get() == unsafe { transmute(-1u32) } // FIXME: #8971: unsound
}
pub fn nextch(rdr: @mut StringReader) -> char {
let offset = byte_offset(rdr, rdr.pos).to_uint();
pub fn nextch(rdr: @StringReader) -> char {
let offset = byte_offset(rdr, rdr.pos.get()).to_uint();
if offset < (rdr.src).len() {
return rdr.src.char_at(offset);
} else { return unsafe { transmute(-1u32) }; } // FIXME: #8971: unsound
@ -296,9 +306,9 @@ fn is_hex_digit(c: char) -> bool {
// EFFECT: eats whitespace and comments.
// returns a Some(sugared-doc-attr) if one exists, None otherwise.
fn consume_whitespace_and_comments(rdr: @mut StringReader)
fn consume_whitespace_and_comments(rdr: @StringReader)
-> Option<TokenAndSpan> {
while is_whitespace(rdr.curr) { bump(rdr); }
while is_whitespace(rdr.curr.get()) { bump(rdr); }
return consume_any_line_comment(rdr);
}
@ -309,17 +319,17 @@ pub fn is_line_non_doc_comment(s: &str) -> bool {
// PRECONDITION: rdr.curr is not whitespace
// EFFECT: eats any kind of comment.
// returns a Some(sugared-doc-attr) if one exists, None otherwise
fn consume_any_line_comment(rdr: @mut StringReader)
fn consume_any_line_comment(rdr: @StringReader)
-> Option<TokenAndSpan> {
if rdr.curr == '/' {
if rdr.curr.get() == '/' {
match nextch(rdr) {
'/' => {
bump(rdr);
bump(rdr);
// line comments starting with "///" or "//!" are doc-comments
if rdr.curr == '/' || rdr.curr == '!' {
let start_bpos = rdr.pos - BytePos(3);
while rdr.curr != '\n' && !is_eof(rdr) {
if rdr.curr.get() == '/' || rdr.curr.get() == '!' {
let start_bpos = rdr.pos.get() - BytePos(3);
while rdr.curr.get() != '\n' && !is_eof(rdr) {
bump(rdr);
}
let ret = with_str_from(rdr, start_bpos, |string| {
@ -327,7 +337,7 @@ fn consume_any_line_comment(rdr: @mut StringReader)
if !is_line_non_doc_comment(string) {
Some(TokenAndSpan{
tok: token::DOC_COMMENT(str_to_ident(string)),
sp: codemap::mk_sp(start_bpos, rdr.pos)
sp: codemap::mk_sp(start_bpos, rdr.pos.get())
})
} else {
None
@ -338,7 +348,7 @@ fn consume_any_line_comment(rdr: @mut StringReader)
return ret;
}
} else {
while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); }
while rdr.curr.get() != '\n' && !is_eof(rdr) { bump(rdr); }
}
// Restart whitespace munch.
return consume_whitespace_and_comments(rdr);
@ -346,15 +356,18 @@ fn consume_any_line_comment(rdr: @mut StringReader)
'*' => { bump(rdr); bump(rdr); return consume_block_comment(rdr); }
_ => ()
}
} else if rdr.curr == '#' {
} else if rdr.curr.get() == '#' {
if nextch(rdr) == '!' {
// I guess this is the only way to figure out if
// we're at the beginning of the file...
let cmap = @CodeMap::new();
(*cmap).files.push(rdr.filemap);
let loc = cmap.lookup_char_pos_adj(rdr.last_pos);
{
let mut files = cmap.files.borrow_mut();
files.get().push(rdr.filemap);
}
let loc = cmap.lookup_char_pos_adj(rdr.last_pos.get());
if loc.line == 1u && loc.col == CharPos(0u) {
while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); }
while rdr.curr.get() != '\n' && !is_eof(rdr) { bump(rdr); }
return consume_whitespace_and_comments(rdr);
}
}
@ -367,11 +380,10 @@ pub fn is_block_non_doc_comment(s: &str) -> bool {
}
// might return a sugared-doc-attr
fn consume_block_comment(rdr: @mut StringReader)
-> Option<TokenAndSpan> {
fn consume_block_comment(rdr: @StringReader) -> Option<TokenAndSpan> {
// block comments starting with "/**" or "/*!" are doc-comments
let is_doc_comment = rdr.curr == '*' || rdr.curr == '!';
let start_bpos = rdr.pos - BytePos(if is_doc_comment {3} else {2});
let is_doc_comment = rdr.curr.get() == '*' || rdr.curr.get() == '!';
let start_bpos = rdr.pos.get() - BytePos(if is_doc_comment {3} else {2});
let mut level: int = 1;
while level > 0 {
@ -381,12 +393,12 @@ fn consume_block_comment(rdr: @mut StringReader)
} else {
~"unterminated block comment"
};
fatal_span(rdr, start_bpos, rdr.last_pos, msg);
} else if rdr.curr == '/' && nextch(rdr) == '*' {
fatal_span(rdr, start_bpos, rdr.last_pos.get(), msg);
} else if rdr.curr.get() == '/' && nextch(rdr) == '*' {
level += 1;
bump(rdr);
bump(rdr);
} else if rdr.curr == '*' && nextch(rdr) == '/' {
} else if rdr.curr.get() == '*' && nextch(rdr) == '/' {
level -= 1;
bump(rdr);
bump(rdr);
@ -401,7 +413,7 @@ fn consume_block_comment(rdr: @mut StringReader)
if !is_block_non_doc_comment(string) {
Some(TokenAndSpan{
tok: token::DOC_COMMENT(str_to_ident(string)),
sp: codemap::mk_sp(start_bpos, rdr.pos)
sp: codemap::mk_sp(start_bpos, rdr.pos.get())
})
} else {
None
@ -415,13 +427,13 @@ fn consume_block_comment(rdr: @mut StringReader)
if res.is_some() { res } else { consume_whitespace_and_comments(rdr) }
}
fn scan_exponent(rdr: @mut StringReader, start_bpos: BytePos) -> Option<~str> {
let mut c = rdr.curr;
fn scan_exponent(rdr: @StringReader, start_bpos: BytePos) -> Option<~str> {
let mut c = rdr.curr.get();
let mut rslt = ~"";
if c == 'e' || c == 'E' {
rslt.push_char(c);
bump(rdr);
c = rdr.curr;
c = rdr.curr.get();
if c == '-' || c == '+' {
rslt.push_char(c);
bump(rdr);
@ -430,16 +442,16 @@ fn scan_exponent(rdr: @mut StringReader, start_bpos: BytePos) -> Option<~str> {
if exponent.len() > 0u {
return Some(rslt + exponent);
} else {
fatal_span(rdr, start_bpos, rdr.last_pos,
fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"scan_exponent: bad fp literal");
}
} else { return None::<~str>; }
}
fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str {
fn scan_digits(rdr: @StringReader, radix: uint) -> ~str {
let mut rslt = ~"";
loop {
let c = rdr.curr;
let c = rdr.curr.get();
if c == '_' { bump(rdr); continue; }
match char::to_digit(c, radix) {
Some(_) => {
@ -451,12 +463,12 @@ fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str {
};
}
fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
fn scan_number(c: char, rdr: @StringReader) -> token::Token {
let mut num_str;
let mut base = 10u;
let mut c = c;
let mut n = nextch(rdr);
let start_bpos = rdr.last_pos;
let start_bpos = rdr.last_pos.get();
if c == '0' && n == 'x' {
bump(rdr);
bump(rdr);
@ -471,7 +483,7 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
base = 2u;
}
num_str = scan_digits(rdr, base);
c = rdr.curr;
c = rdr.curr.get();
nextch(rdr);
if c == 'u' || c == 'i' {
enum Result { Signed(ast::int_ty), Unsigned(ast::uint_ty) }
@ -481,7 +493,7 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
else { Unsigned(ast::ty_u) }
};
bump(rdr);
c = rdr.curr;
c = rdr.curr.get();
if c == '8' {
bump(rdr);
tp = if signed { Signed(ast::ty_i8) }
@ -505,12 +517,12 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
else { Unsigned(ast::ty_u64) };
}
if num_str.len() == 0u {
fatal_span(rdr, start_bpos, rdr.last_pos,
fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"no valid digits found for number");
}
let parsed = match from_str_radix::<u64>(num_str, base as uint) {
Some(p) => p,
None => fatal_span(rdr, start_bpos, rdr.last_pos,
None => fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"int literal is too large")
};
@ -520,7 +532,8 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
}
}
let mut is_float = false;
if rdr.curr == '.' && !(ident_start(nextch(rdr)) || nextch(rdr) == '.') {
if rdr.curr.get() == '.' && !(ident_start(nextch(rdr)) || nextch(rdr) ==
'.') {
is_float = true;
bump(rdr);
let dec_part = scan_digits(rdr, 10u);
@ -529,11 +542,11 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
}
if is_float {
match base {
16u => fatal_span(rdr, start_bpos, rdr.last_pos,
16u => fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"hexadecimal float literal is not supported"),
8u => fatal_span(rdr, start_bpos, rdr.last_pos,
8u => fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"octal float literal is not supported"),
2u => fatal_span(rdr, start_bpos, rdr.last_pos,
2u => fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"binary float literal is not supported"),
_ => ()
}
@ -546,9 +559,9 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
None => ()
}
if rdr.curr == 'f' {
if rdr.curr.get() == 'f' {
bump(rdr);
c = rdr.curr;
c = rdr.curr.get();
n = nextch(rdr);
if c == '3' && n == '2' {
bump(rdr);
@ -564,19 +577,20 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
32-bit or 64-bit float, it won't be noticed till the
back-end. */
} else {
fatal_span(rdr, start_bpos, rdr.last_pos, ~"expected `f32` or `f64` suffix");
fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"expected `f32` or `f64` suffix");
}
}
if is_float {
return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(num_str));
} else {
if num_str.len() == 0u {
fatal_span(rdr, start_bpos, rdr.last_pos,
fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"no valid digits found for number");
}
let parsed = match from_str_radix::<u64>(num_str, base as uint) {
Some(p) => p,
None => fatal_span(rdr, start_bpos, rdr.last_pos,
None => fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"int literal is too large")
};
@ -585,14 +599,14 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
}
}
fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char {
fn scan_numeric_escape(rdr: @StringReader, n_hex_digits: uint) -> char {
let mut accum_int = 0;
let mut i = n_hex_digits;
let start_bpos = rdr.last_pos;
let start_bpos = rdr.last_pos.get();
while i != 0u {
let n = rdr.curr;
let n = rdr.curr.get();
if !is_hex_digit(n) {
fatal_span_char(rdr, rdr.last_pos, rdr.pos,
fatal_span_char(rdr, rdr.last_pos.get(), rdr.pos.get(),
~"illegal character in numeric character escape",
n);
}
@ -603,7 +617,7 @@ fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char {
}
match char::from_u32(accum_int as u32) {
Some(x) => x,
None => fatal_span(rdr, start_bpos, rdr.last_pos,
None => fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"illegal numeric character escape")
}
}
@ -626,14 +640,14 @@ fn ident_continue(c: char) -> bool {
// return the next token from the string
// EFFECT: advances the input past that token
// EFFECT: updates the interner
fn next_token_inner(rdr: @mut StringReader) -> token::Token {
let c = rdr.curr;
fn next_token_inner(rdr: @StringReader) -> token::Token {
let c = rdr.curr.get();
if ident_start(c) && nextch(rdr) != '"' && nextch(rdr) != '#' {
// Note: r as in r" or r#" is part of a raw string literal,
// not an identifier, and is handled further down.
let start = rdr.last_pos;
while ident_continue(rdr.curr) {
let start = rdr.last_pos.get();
while ident_continue(rdr.curr.get()) {
bump(rdr);
}
@ -641,7 +655,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
if string == "_" {
token::UNDERSCORE
} else {
let is_mod_name = rdr.curr == ':' && nextch(rdr) == ':';
let is_mod_name = rdr.curr.get() == ':' && nextch(rdr) == ':';
// FIXME: perform NFKC normalization here. (Issue #2253)
token::IDENT(str_to_ident(string), is_mod_name)
@ -651,9 +665,9 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
if is_dec_digit(c) {
return scan_number(c, rdr);
}
fn binop(rdr: @mut StringReader, op: token::binop) -> token::Token {
fn binop(rdr: @StringReader, op: token::binop) -> token::Token {
bump(rdr);
if rdr.curr == '=' {
if rdr.curr.get() == '=' {
bump(rdr);
return token::BINOPEQ(op);
} else { return token::BINOP(op); }
@ -669,9 +683,9 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
',' => { bump(rdr); return token::COMMA; }
'.' => {
bump(rdr);
return if rdr.curr == '.' {
return if rdr.curr.get() == '.' {
bump(rdr);
if rdr.curr == '.' {
if rdr.curr.get() == '.' {
bump(rdr);
token::DOTDOTDOT
} else {
@ -692,7 +706,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
'~' => { bump(rdr); return token::TILDE; }
':' => {
bump(rdr);
if rdr.curr == ':' {
if rdr.curr.get() == ':' {
bump(rdr);
return token::MOD_SEP;
} else { return token::COLON; }
@ -707,10 +721,10 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
// Multi-byte tokens.
'=' => {
bump(rdr);
if rdr.curr == '=' {
if rdr.curr.get() == '=' {
bump(rdr);
return token::EQEQ;
} else if rdr.curr == '>' {
} else if rdr.curr.get() == '>' {
bump(rdr);
return token::FAT_ARROW;
} else {
@ -719,19 +733,19 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
}
'!' => {
bump(rdr);
if rdr.curr == '=' {
if rdr.curr.get() == '=' {
bump(rdr);
return token::NE;
} else { return token::NOT; }
}
'<' => {
bump(rdr);
match rdr.curr {
match rdr.curr.get() {
'=' => { bump(rdr); return token::LE; }
'<' => { return binop(rdr, token::SHL); }
'-' => {
bump(rdr);
match rdr.curr {
match rdr.curr.get() {
'>' => { bump(rdr); return token::DARROW; }
_ => { return token::LARROW; }
}
@ -741,7 +755,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
}
'>' => {
bump(rdr);
match rdr.curr {
match rdr.curr.get() {
'=' => { bump(rdr); return token::GE; }
'>' => { return binop(rdr, token::SHR); }
_ => { return token::GT; }
@ -750,14 +764,14 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
'\'' => {
// Either a character constant 'a' OR a lifetime name 'abc
bump(rdr);
let start = rdr.last_pos;
let mut c2 = rdr.curr;
let start = rdr.last_pos.get();
let mut c2 = rdr.curr.get();
bump(rdr);
// If the character is an ident start not followed by another single
// quote, then this is a lifetime name:
if ident_start(c2) && rdr.curr != '\'' {
while ident_continue(rdr.curr) {
if ident_start(c2) && rdr.curr.get() != '\'' {
while ident_continue(rdr.curr.get()) {
bump(rdr);
}
return with_str_from(rdr, start, |lifetime_name| {
@ -765,11 +779,12 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
let tok = &token::IDENT(ident, false);
if token::is_keyword(token::keywords::Self, tok) {
fatal_span(rdr, start, rdr.last_pos,
fatal_span(rdr, start, rdr.last_pos.get(),
~"invalid lifetime name: 'self is no longer a special lifetime");
} else if token::is_any_keyword(tok) &&
!token::is_keyword(token::keywords::Static, tok) {
fatal_span(rdr, start, rdr.last_pos, ~"invalid lifetime name");
fatal_span(rdr, start, rdr.last_pos.get(),
~"invalid lifetime name");
} else {
token::LIFETIME(ident)
}
@ -780,8 +795,8 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
match c2 {
'\\' => {
// '\X' for some X must be a character constant:
let escaped = rdr.curr;
let escaped_pos = rdr.last_pos;
let escaped = rdr.curr.get();
let escaped_pos = rdr.last_pos.get();
bump(rdr);
match escaped {
'n' => { c2 = '\n'; }
@ -795,24 +810,24 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
'u' => { c2 = scan_numeric_escape(rdr, 4u); }
'U' => { c2 = scan_numeric_escape(rdr, 8u); }
c2 => {
fatal_span_char(rdr, escaped_pos, rdr.last_pos,
fatal_span_char(rdr, escaped_pos, rdr.last_pos.get(),
~"unknown character escape", c2);
}
}
}
'\t' | '\n' | '\r' | '\'' => {
fatal_span_char(rdr, start, rdr.last_pos,
fatal_span_char(rdr, start, rdr.last_pos.get(),
~"character constant must be escaped", c2);
}
_ => {}
}
if rdr.curr != '\'' {
if rdr.curr.get() != '\'' {
fatal_span_verbose(rdr,
// Byte offsetting here is okay because the
// character before position `start` is an
// ascii single quote.
start - BytePos(1),
rdr.last_pos,
rdr.last_pos.get(),
~"unterminated character constant");
}
bump(rdr); // advance curr past token
@ -820,20 +835,20 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
}
'"' => {
let mut accum_str = ~"";
let start_bpos = rdr.last_pos;
let start_bpos = rdr.last_pos.get();
bump(rdr);
while rdr.curr != '"' {
while rdr.curr.get() != '"' {
if is_eof(rdr) {
fatal_span(rdr, start_bpos, rdr.last_pos,
fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"unterminated double quote string");
}
let ch = rdr.curr;
let ch = rdr.curr.get();
bump(rdr);
match ch {
'\\' => {
let escaped = rdr.curr;
let escaped_pos = rdr.last_pos;
let escaped = rdr.curr.get();
let escaped_pos = rdr.last_pos.get();
bump(rdr);
match escaped {
'n' => accum_str.push_char('\n'),
@ -854,7 +869,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
accum_str.push_char(scan_numeric_escape(rdr, 8u));
}
c2 => {
fatal_span_char(rdr, escaped_pos, rdr.last_pos,
fatal_span_char(rdr, escaped_pos, rdr.last_pos.get(),
~"unknown string escape", c2);
}
}
@ -866,32 +881,32 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
return token::LIT_STR(str_to_ident(accum_str));
}
'r' => {
let start_bpos = rdr.last_pos;
let start_bpos = rdr.last_pos.get();
bump(rdr);
let mut hash_count = 0u;
while rdr.curr == '#' {
while rdr.curr.get() == '#' {
bump(rdr);
hash_count += 1;
}
if rdr.curr != '"' {
fatal_span_char(rdr, start_bpos, rdr.last_pos,
if rdr.curr.get() != '"' {
fatal_span_char(rdr, start_bpos, rdr.last_pos.get(),
~"only `#` is allowed in raw string delimitation; \
found illegal character",
rdr.curr);
rdr.curr.get());
}
bump(rdr);
let content_start_bpos = rdr.last_pos;
let content_start_bpos = rdr.last_pos.get();
let mut content_end_bpos;
'outer: loop {
if is_eof(rdr) {
fatal_span(rdr, start_bpos, rdr.last_pos,
fatal_span(rdr, start_bpos, rdr.last_pos.get(),
~"unterminated raw string");
}
if rdr.curr == '"' {
content_end_bpos = rdr.last_pos;
if rdr.curr.get() == '"' {
content_end_bpos = rdr.last_pos.get();
for _ in range(0, hash_count) {
bump(rdr);
if rdr.curr != '#' {
if rdr.curr.get() != '#' {
continue 'outer;
}
}
@ -932,14 +947,14 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
'^' => { return binop(rdr, token::CARET); }
'%' => { return binop(rdr, token::PERCENT); }
c => {
fatal_span_char(rdr, rdr.last_pos, rdr.pos,
fatal_span_char(rdr, rdr.last_pos.get(), rdr.pos.get(),
~"unknown start of token", c);
}
}
}
fn consume_whitespace(rdr: @mut StringReader) {
while is_whitespace(rdr.curr) && !is_eof(rdr) { bump(rdr); }
fn consume_whitespace(rdr: @StringReader) {
while is_whitespace(rdr.curr.get()) && !is_eof(rdr) { bump(rdr); }
}
#[cfg(test)]
@ -953,7 +968,7 @@ mod test {
// represents a testing reader (incl. both reader and interner)
struct Env {
string_reader: @mut StringReader
string_reader: @StringReader
}
// open a string reader for the given string
@ -978,7 +993,7 @@ mod test {
sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}};
assert_eq!(tok1,tok2);
// the 'main' id is already read:
assert_eq!(string_reader.last_pos.clone(), BytePos(28));
assert_eq!(string_reader.last_pos.get().clone(), BytePos(28));
// read another token:
let tok3 = string_reader.next_token();
let tok4 = TokenAndSpan{
@ -986,7 +1001,7 @@ mod test {
sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}};
assert_eq!(tok3,tok4);
// the lparen is already read:
assert_eq!(string_reader.last_pos.clone(), BytePos(29))
assert_eq!(string_reader.last_pos.get().clone(), BytePos(29))
}
// check that the given reader produces the desired stream

View File

@ -19,6 +19,7 @@ use parse::attr::parser_attr;
use parse::lexer::reader;
use parse::parser::Parser;
use std::cell::RefCell;
use std::io;
use std::io::File;
use std::str;
@ -41,27 +42,27 @@ pub mod obsolete;
// info about a parsing session.
pub struct ParseSess {
cm: @codemap::CodeMap, // better be the same as the one in the reader!
span_diagnostic: @mut SpanHandler, // better be the same as the one in the reader!
span_diagnostic: @SpanHandler, // better be the same as the one in the reader!
/// Used to determine and report recursive mod inclusions
included_mod_stack: ~[Path],
included_mod_stack: RefCell<~[Path]>,
}
pub fn new_parse_sess(demitter: Option<@Emitter>) -> @mut ParseSess {
pub fn new_parse_sess(demitter: Option<@Emitter>) -> @ParseSess {
let cm = @CodeMap::new();
@mut ParseSess {
@ParseSess {
cm: cm,
span_diagnostic: mk_span_handler(mk_handler(demitter), cm),
included_mod_stack: ~[],
included_mod_stack: RefCell::new(~[]),
}
}
pub fn new_parse_sess_special_handler(sh: @mut SpanHandler,
pub fn new_parse_sess_special_handler(sh: @SpanHandler,
cm: @codemap::CodeMap)
-> @mut ParseSess {
@mut ParseSess {
-> @ParseSess {
@ParseSess {
cm: cm,
span_diagnostic: sh,
included_mod_stack: ~[],
included_mod_stack: RefCell::new(~[]),
}
}
@ -73,7 +74,7 @@ pub fn new_parse_sess_special_handler(sh: @mut SpanHandler,
pub fn parse_crate_from_file(
input: &Path,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> ast::Crate {
new_parser_from_file(sess, /*bad*/ cfg.clone(), input).parse_crate_mod()
// why is there no p.abort_if_errors here?
@ -82,7 +83,7 @@ pub fn parse_crate_from_file(
pub fn parse_crate_attrs_from_file(
input: &Path,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> ~[ast::Attribute] {
let mut parser = new_parser_from_file(sess, cfg, input);
let (inner, _) = parser.parse_inner_attrs_and_next();
@ -93,7 +94,7 @@ pub fn parse_crate_from_source_str(
name: @str,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> ast::Crate {
let mut p = new_parser_from_source_str(sess,
/*bad*/ cfg.clone(),
@ -106,7 +107,7 @@ pub fn parse_crate_attrs_from_source_str(
name: @str,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> ~[ast::Attribute] {
let mut p = new_parser_from_source_str(sess,
/*bad*/ cfg.clone(),
@ -120,7 +121,7 @@ pub fn parse_expr_from_source_str(
name: @str,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> @ast::Expr {
let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_expr(), p)
@ -131,7 +132,7 @@ pub fn parse_item_from_source_str(
source: @str,
cfg: ast::CrateConfig,
attrs: ~[ast::Attribute],
sess: @mut ParseSess
sess: @ParseSess
) -> Option<@ast::item> {
let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_item(attrs),p)
@ -141,7 +142,7 @@ pub fn parse_meta_from_source_str(
name: @str,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> @ast::MetaItem {
let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_meta_item(),p)
@ -152,7 +153,7 @@ pub fn parse_stmt_from_source_str(
source: @str,
cfg: ast::CrateConfig,
attrs: ~[ast::Attribute],
sess: @mut ParseSess
sess: @ParseSess
) -> @ast::Stmt {
let mut p = new_parser_from_source_str(
sess,
@ -167,7 +168,7 @@ pub fn parse_tts_from_source_str(
name: @str,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess
sess: @ParseSess
) -> ~[ast::token_tree] {
let mut p = new_parser_from_source_str(
sess,
@ -191,7 +192,7 @@ pub fn parse_from_source_str<T>(
ss: codemap::FileSubstr,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess)
sess: @ParseSess)
-> T {
let mut p = new_parser_from_source_substr(sess, cfg, name, ss, source);
let r = f(&mut p);
@ -202,7 +203,7 @@ pub fn parse_from_source_str<T>(
}
// Create a new parser from a source string
pub fn new_parser_from_source_str(sess: @mut ParseSess,
pub fn new_parser_from_source_str(sess: @ParseSess,
cfg: ast::CrateConfig,
name: @str,
source: @str)
@ -212,7 +213,7 @@ pub fn new_parser_from_source_str(sess: @mut ParseSess,
// Create a new parser from a source string where the origin
// is specified as a substring of another file.
pub fn new_parser_from_source_substr(sess: @mut ParseSess,
pub fn new_parser_from_source_substr(sess: @ParseSess,
cfg: ast::CrateConfig,
name: @str,
ss: codemap::FileSubstr,
@ -224,7 +225,7 @@ pub fn new_parser_from_source_substr(sess: @mut ParseSess,
/// Create a new parser, handling errors as appropriate
/// if the file doesn't exist
pub fn new_parser_from_file(
sess: @mut ParseSess,
sess: @ParseSess,
cfg: ast::CrateConfig,
path: &Path
) -> Parser {
@ -235,7 +236,7 @@ pub fn new_parser_from_file(
/// the file at the given path to the codemap, and return a parser.
/// On an error, use the given span as the source of the problem.
pub fn new_sub_parser_from_file(
sess: @mut ParseSess,
sess: @ParseSess,
cfg: ast::CrateConfig,
path: &Path,
sp: Span
@ -244,7 +245,7 @@ pub fn new_sub_parser_from_file(
}
/// Given a filemap and config, return a parser
pub fn filemap_to_parser(sess: @mut ParseSess,
pub fn filemap_to_parser(sess: @ParseSess,
filemap: @FileMap,
cfg: ast::CrateConfig) -> Parser {
tts_to_parser(sess,filemap_to_tts(sess,filemap),cfg)
@ -252,7 +253,7 @@ pub fn filemap_to_parser(sess: @mut ParseSess,
// must preserve old name for now, because quote! from the *existing*
// compiler expands into it
pub fn new_parser_from_tts(sess: @mut ParseSess,
pub fn new_parser_from_tts(sess: @ParseSess,
cfg: ast::CrateConfig,
tts: ~[ast::token_tree]) -> Parser {
tts_to_parser(sess,tts,cfg)
@ -263,7 +264,7 @@ pub fn new_parser_from_tts(sess: @mut ParseSess,
/// Given a session and a path and an optional span (for error reporting),
/// add the path to the session's codemap and return the new filemap.
pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option<Span>)
pub fn file_to_filemap(sess: @ParseSess, path: &Path, spanopt: Option<Span>)
-> @FileMap {
let err = |msg: &str| {
match spanopt {
@ -292,35 +293,35 @@ pub fn file_to_filemap(sess: @mut ParseSess, path: &Path, spanopt: Option<Span>)
// given a session and a string, add the string to
// the session's codemap and return the new filemap
pub fn string_to_filemap(sess: @mut ParseSess, source: @str, path: @str)
pub fn string_to_filemap(sess: @ParseSess, source: @str, path: @str)
-> @FileMap {
sess.cm.new_filemap(path, source)
}
// given a session and a string and a path and a FileSubStr, add
// the string to the CodeMap and return the new FileMap
pub fn substring_to_filemap(sess: @mut ParseSess, source: @str, path: @str,
pub fn substring_to_filemap(sess: @ParseSess, source: @str, path: @str,
filesubstr: FileSubstr) -> @FileMap {
sess.cm.new_filemap_w_substr(path,filesubstr,source)
}
// given a filemap, produce a sequence of token-trees
pub fn filemap_to_tts(sess: @mut ParseSess, filemap: @FileMap)
pub fn filemap_to_tts(sess: @ParseSess, filemap: @FileMap)
-> ~[ast::token_tree] {
// it appears to me that the cfg doesn't matter here... indeed,
// parsing tt's probably shouldn't require a parser at all.
let cfg = ~[];
let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap);
let mut p1 = Parser(sess, cfg, srdr as @mut reader);
let mut p1 = Parser(sess, cfg, srdr as @reader);
p1.parse_all_token_trees()
}
// given tts and cfg, produce a parser
pub fn tts_to_parser(sess: @mut ParseSess,
pub fn tts_to_parser(sess: @ParseSess,
tts: ~[ast::token_tree],
cfg: ast::CrateConfig) -> Parser {
let trdr = lexer::new_tt_reader(sess.span_diagnostic, None, tts);
Parser(sess, cfg, trdr as @mut reader)
Parser(sess, cfg, trdr as @reader)
}
// abort if necessary

View File

@ -29,8 +29,7 @@ use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac};
use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc, ExprRepeat};
use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary};
use ast::{ExprVec, ExprVstore, ExprVstoreMutBox};
use ast::{ExprVstoreSlice, ExprVstoreBox};
use ast::{ExprVec, ExprVstore, ExprVstoreSlice, ExprVstoreBox};
use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, extern_fn, Field, fn_decl};
use ast::{ExprVstoreUniq, Onceness, Once, Many};
use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod};
@ -81,6 +80,7 @@ use parse::{new_sub_parser_from_file, ParseSess};
use opt_vec;
use opt_vec::OptVec;
use std::cell::Cell;
use std::hashmap::HashSet;
use std::util;
use std::vec;
@ -286,8 +286,8 @@ struct ParsedItemsAndViewItems {
/* ident is handled by common.rs */
pub fn Parser(sess: @mut ParseSess, cfg: ast::CrateConfig, rdr: @mut reader)
-> Parser {
pub fn Parser(sess: @ParseSess, cfg: ast::CrateConfig, rdr: @reader)
-> Parser {
let tok0 = rdr.next_token();
let interner = get_ident_interner();
let span = tok0.sp;
@ -324,7 +324,7 @@ pub fn Parser(sess: @mut ParseSess, cfg: ast::CrateConfig, rdr: @mut reader)
}
pub struct Parser {
sess: @mut ParseSess,
sess: @ParseSess,
cfg: CrateConfig,
// the current token:
token: token::Token,
@ -340,7 +340,7 @@ pub struct Parser {
tokens_consumed: uint,
restriction: restriction,
quote_depth: uint, // not (yet) related to the quasiquoter
reader: @mut reader,
reader: @reader,
interner: @token::ident_interner,
/// The set of seen errors about obsolete syntax. Used to suppress
/// extra detail when the same error is seen twice
@ -1299,7 +1299,7 @@ impl Parser {
if sigil == OwnedSigil {
ty_uniq(self.parse_ty(false))
} else {
ty_box(self.parse_mt())
ty_box(self.parse_ty(false))
}
}
@ -2185,7 +2185,7 @@ impl Parser {
// unification of matchers and token_trees would vastly improve
// the interpolation of matchers
maybe_whole!(self, nt_matchers);
let name_idx = @mut 0u;
let name_idx = @Cell::new(0u);
match self.token {
token::LBRACE | token::LPAREN | token::LBRACKET => {
let other_delimiter = token::flip_delimiter(&self.token);
@ -2200,7 +2200,7 @@ impl Parser {
// Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
// invalid. It's similar to common::parse_seq.
pub fn parse_matcher_subseq_upto(&mut self,
name_idx: @mut uint,
name_idx: @Cell<uint>,
ket: &token::Token)
-> ~[matcher] {
let mut ret_val = ~[];
@ -2217,13 +2217,13 @@ impl Parser {
return ret_val;
}
pub fn parse_matcher(&mut self, name_idx: @mut uint) -> matcher {
pub fn parse_matcher(&mut self, name_idx: @Cell<uint>) -> matcher {
let lo = self.span.lo;
let m = if self.token == token::DOLLAR {
self.bump();
if self.token == token::LPAREN {
let name_idx_lo = *name_idx;
let name_idx_lo = name_idx.get();
self.bump();
let ms = self.parse_matcher_subseq_upto(name_idx,
&token::RPAREN);
@ -2231,13 +2231,13 @@ impl Parser {
self.fatal("repetition body must be nonempty");
}
let (sep, zerok) = self.parse_sep_and_zerok();
match_seq(ms, sep, zerok, name_idx_lo, *name_idx)
match_seq(ms, sep, zerok, name_idx_lo, name_idx.get())
} else {
let bound_to = self.parse_ident();
self.expect(&token::COLON);
let nt_name = self.parse_ident();
let m = match_nonterminal(bound_to, nt_name, *name_idx);
*name_idx += 1u;
let m = match_nonterminal(bound_to, nt_name, name_idx.get());
name_idx.set(name_idx.get() + 1u);
m
}
} else {
@ -2299,17 +2299,14 @@ impl Parser {
}
token::AT => {
self.bump();
let m = self.parse_mutability();
let e = self.parse_prefix_expr();
hi = e.span.hi;
// HACK: turn @[...] into a @-evec
ex = match e.node {
ExprVec(..) | ExprRepeat(..) if m == MutMutable =>
ExprVstore(e, ExprVstoreMutBox),
ExprVec(..) |
ExprLit(@codemap::Spanned { node: lit_str(..), span: _}) |
ExprRepeat(..) if m == MutImmutable => ExprVstore(e, ExprVstoreBox),
_ => self.mk_unary(UnBox(m), e)
ExprRepeat(..) => ExprVstore(e, ExprVstoreBox),
_ => self.mk_unary(UnBox, e)
};
}
token::TILDE => {
@ -4264,21 +4261,28 @@ impl Parser {
path: Path,
outer_attrs: ~[ast::Attribute],
id_sp: Span) -> (ast::item_, ~[ast::Attribute]) {
let maybe_i = self.sess.included_mod_stack.iter().position(|p| *p == path);
match maybe_i {
Some(i) => {
let stack = &self.sess.included_mod_stack;
let mut err = ~"circular modules: ";
for p in stack.slice(i, stack.len()).iter() {
p.display().with_str(|s| err.push_str(s));
err.push_str(" -> ");
{
let mut included_mod_stack = self.sess
.included_mod_stack
.borrow_mut();
let maybe_i = included_mod_stack.get()
.iter()
.position(|p| *p == path);
match maybe_i {
Some(i) => {
let mut err = ~"circular modules: ";
let len = included_mod_stack.get().len();
for p in included_mod_stack.get().slice(i, len).iter() {
p.display().with_str(|s| err.push_str(s));
err.push_str(" -> ");
}
path.display().with_str(|s| err.push_str(s));
self.span_fatal(id_sp, err);
}
path.display().with_str(|s| err.push_str(s));
self.span_fatal(id_sp, err);
None => ()
}
None => ()
included_mod_stack.get().push(path.clone());
}
self.sess.included_mod_stack.push(path.clone());
let mut p0 =
new_sub_parser_from_file(self.sess,
@ -4289,7 +4293,12 @@ impl Parser {
let mod_attrs = vec::append(outer_attrs, inner);
let first_item_outer_attrs = next;
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
self.sess.included_mod_stack.pop();
{
let mut included_mod_stack = self.sess
.included_mod_stack
.borrow_mut();
included_mod_stack.get().pop();
}
return (ast::item_mod(m0), mod_attrs);
}

View File

@ -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})

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More