mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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:
commit
3dd7c49faf
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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::*;
|
||||
|
@ -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| {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -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();
|
||||
|
@ -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(
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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))),
|
||||
'&' => {
|
||||
|
@ -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) => {
|
||||
|
@ -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),
|
||||
|
@ -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() {
|
||||
|
@ -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, .. }) => {
|
||||
|
@ -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, _) => {
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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")
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
},
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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| {
|
||||
|
@ -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(_) => ~"*"
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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 => {}
|
||||
|
@ -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) => {
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 => {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 => {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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) => {
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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))
|
||||
|
@ -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(),
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
¶m_bounds,
|
||||
mt.ty,
|
||||
typ,
|
||||
is_early);
|
||||
|
||||
if !is_early {
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
_ => {
|
||||
|
@ -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)) => {
|
||||
|
@ -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,_)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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() }
|
||||
|
@ -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 ())");
|
||||
|
@ -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]
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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 () {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user