auto merge of #14250 : alexcrichton/rust/gc, r=brson

This commit removes `@T` from the compiler by moving the AST to using `Gc<T>`. This also starts treating `Gc<T>` as `@T` in the same way that `Box<T>` is the same as `~T` in the compiler.

After this hits a snapshot, the `@T` syntax should be able to be removed completely.
This commit is contained in:
bors 2014-06-11 10:02:04 -07:00
commit f0f9095f1d
119 changed files with 2809 additions and 2659 deletions

View File

@ -1710,14 +1710,14 @@ having ownership of the box. It allows the creation of cycles, and the individua
not have a destructor. not have a destructor.
~~~ ~~~
use std::gc::Gc; use std::gc::GC;
// A fixed-size array allocated in a garbage-collected box // A fixed-size array allocated in a garbage-collected box
let x = Gc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); let x = box(GC) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let y = x; // does not perform a move, unlike with `Rc` let y = x; // does not perform a move, unlike with `Rc`
let z = x; let z = x;
assert!(*z.borrow() == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); assert!(*z == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
~~~ ~~~
With shared ownership, mutability cannot be inherited so the boxes are always immutable. However, With shared ownership, mutability cannot be inherited so the boxes are always immutable. However,

View File

@ -320,8 +320,8 @@ mod tests {
#[test] #[test]
fn gc_inside() { fn gc_inside() {
// see issue #11532 // see issue #11532
use std::gc::Gc; use std::gc::GC;
let a = Rc::new(RefCell::new(Gc::new(1))); let a = Rc::new(RefCell::new(box(GC) 1));
assert!(a.try_borrow_mut().is_some()); assert!(a.try_borrow_mut().is_some());
} }

View File

@ -248,13 +248,6 @@ impl<S: Writer, T: Hash<S>> Hash<S> for Box<T> {
} }
} }
impl<S: Writer, T: Hash<S>> Hash<S> for @T {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}
impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> { impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> {
#[inline] #[inline]
fn hash(&self, state: &mut S) { fn hash(&self, state: &mut S) {

View File

@ -39,12 +39,6 @@ pub trait Clone {
} }
} }
impl<T> Clone for @T {
/// Return a shallow copy of the managed box.
#[inline]
fn clone(&self) -> @T { *self }
}
impl<'a, T> Clone for &'a T { impl<'a, T> Clone for &'a T {
/// Return a shallow copy of the reference. /// Return a shallow copy of the reference.
#[inline] #[inline]
@ -116,6 +110,7 @@ extern_fn_clone!(A, B, C, D, E, F, G, H)
mod test { mod test {
use prelude::*; use prelude::*;
use realstd::owned::Box; use realstd::owned::Box;
use realstd::gc::{Gc, GC};
fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T { fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
use realstd::clone::Clone; use realstd::clone::Clone;
@ -136,9 +131,9 @@ mod test {
#[test] #[test]
fn test_managed_clone() { fn test_managed_clone() {
let a = @5i; let a = box(GC) 5i;
let b: @int = a.clone(); let b: Gc<int> = realclone(&a);
assert_eq!(a, b); assert!(a == b);
} }
#[test] #[test]

View File

@ -326,29 +326,6 @@ mod impls {
fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) } fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
} }
impl<'a, T: Eq> Eq for &'a mut T {} impl<'a, T: Eq> Eq for &'a mut T {}
// @ pointers
impl<T:PartialEq> PartialEq for @T {
#[inline]
fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
#[inline]
fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
}
impl<T:PartialOrd> PartialOrd for @T {
#[inline]
fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
#[inline]
fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
#[inline]
fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
#[inline]
fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
}
impl<T: Ord> Ord for @T {
#[inline]
fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
}
impl<T: Eq> Eq for @T {}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -43,7 +43,3 @@ default_impl!(i64, 0i64)
default_impl!(f32, 0.0f32) default_impl!(f32, 0.0f32)
default_impl!(f64, 0.0f64) default_impl!(f64, 0.0f64)
impl<T: Default + 'static> Default for @T {
fn default() -> @T { @Default::default() }
}

View File

@ -628,9 +628,6 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
// Implementations of the core formatting traits // Implementations of the core formatting traits
impl<T: Show> Show for @T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
}
impl<'a, T: Show> Show for &'a T { impl<'a, T: Show> Show for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) } fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
} }

View File

@ -79,7 +79,6 @@ pub trait Repr<T> {
impl<'a, T> Repr<Slice<T>> for &'a [T] {} impl<'a, T> Repr<Slice<T>> for &'a [T] {}
impl<'a> Repr<Slice<u8>> for &'a str {} impl<'a> Repr<Slice<u8>> for &'a str {}
impl<T> Repr<*Box<T>> for @T {}
impl<T> Repr<*Vec<T>> for ~[T] {} impl<T> Repr<*Vec<T>> for ~[T] {}
#[cfg(test)] #[cfg(test)]

View File

@ -705,7 +705,7 @@ fn print_flowgraph<W:io::Writer>(analysis: CrateAnalysis,
block: ast::P<ast::Block>, block: ast::P<ast::Block>,
mut out: W) -> io::IoResult<()> { mut out: W) -> io::IoResult<()> {
let ty_cx = &analysis.ty_cx; let ty_cx = &analysis.ty_cx;
let cfg = cfg::CFG::new(ty_cx, block); let cfg = cfg::CFG::new(ty_cx, &*block);
let lcfg = LabelledCFG { ast_map: &ty_cx.map, let lcfg = LabelledCFG { ast_map: &ty_cx.map,
cfg: &cfg, cfg: &cfg,
name: format!("block{}", block.id).to_string(), }; name: format!("block{}", block.id).to_string(), };

View File

@ -12,6 +12,8 @@ use syntax::fold::Folder;
use syntax::{ast, fold, attr}; use syntax::{ast, fold, attr};
use syntax::codemap; use syntax::codemap;
use std::gc::Gc;
struct Context<'a> { struct Context<'a> {
in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool, in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
} }
@ -36,7 +38,7 @@ impl<'a> fold::Folder for Context<'a> {
fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ { fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
fold_item_underscore(self, item) fold_item_underscore(self, item)
} }
fn fold_expr(&mut self, expr: @ast::Expr) -> @ast::Expr { fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
fold_expr(self, expr) fold_expr(self, expr)
} }
} }
@ -60,8 +62,8 @@ fn filter_view_item<'r>(cx: &mut Context, view_item: &'r ast::ViewItem)
} }
fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod { fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
let filtered_items: Vec<&@ast::Item> = m.items.iter() let filtered_items: Vec<&Gc<ast::Item>> = m.items.iter()
.filter(|&a| item_in_cfg(cx, *a)) .filter(|a| item_in_cfg(cx, &***a))
.collect(); .collect();
let flattened_items = filtered_items.move_iter() let flattened_items = filtered_items.move_iter()
.flat_map(|&x| cx.fold_item(x).move_iter()) .flat_map(|&x| cx.fold_item(x).move_iter())
@ -76,9 +78,9 @@ fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
} }
} }
fn filter_foreign_item(cx: &mut Context, item: @ast::ForeignItem) fn filter_foreign_item(cx: &mut Context, item: Gc<ast::ForeignItem>)
-> Option<@ast::ForeignItem> { -> Option<Gc<ast::ForeignItem>> {
if foreign_item_in_cfg(cx, item) { if foreign_item_in_cfg(cx, &*item) {
Some(item) Some(item)
} else { } else {
None None
@ -103,7 +105,7 @@ fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ { fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
let item = match *item { let item = match *item {
ast::ItemImpl(ref a, ref b, c, ref methods) => { ast::ItemImpl(ref a, ref b, c, ref methods) => {
let methods = methods.iter().filter(|m| method_in_cfg(cx, **m)) let methods = methods.iter().filter(|m| method_in_cfg(cx, &***m))
.map(|x| *x).collect(); .map(|x| *x).collect();
ast::ItemImpl((*a).clone(), (*b).clone(), c, methods) ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
} }
@ -114,8 +116,8 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
.collect(); .collect();
ast::ItemTrait((*a).clone(), b, (*c).clone(), methods) ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
} }
ast::ItemStruct(def, ref generics) => { ast::ItemStruct(ref def, ref generics) => {
ast::ItemStruct(fold_struct(cx, def), generics.clone()) ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
} }
ast::ItemEnum(ref def, ref generics) => { ast::ItemEnum(ref def, ref generics) => {
let mut variants = def.variants.iter().map(|c| c.clone()). let mut variants = def.variants.iter().map(|c| c.clone()).
@ -125,11 +127,11 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
} else { } else {
Some(match v.node.kind { Some(match v.node.kind {
ast::TupleVariantKind(..) => v, ast::TupleVariantKind(..) => v,
ast::StructVariantKind(def) => { ast::StructVariantKind(ref def) => {
let def = fold_struct(cx, def); let def = fold_struct(cx, &**def);
@codemap::Spanned { box(GC) codemap::Spanned {
node: ast::Variant_ { node: ast::Variant_ {
kind: ast::StructVariantKind(def), kind: ast::StructVariantKind(def.clone()),
..v.node.clone() ..v.node.clone()
}, },
..*v ..*v
@ -148,11 +150,11 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
fold::noop_fold_item_underscore(&item, cx) fold::noop_fold_item_underscore(&item, cx)
} }
fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> @ast::StructDef { fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> Gc<ast::StructDef> {
let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| { let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
(cx.in_cfg)(m.node.attrs.as_slice()) (cx.in_cfg)(m.node.attrs.as_slice())
}); });
@ast::StructDef { box(GC) ast::StructDef {
fields: fields.collect(), fields: fields.collect(),
ctor_id: def.ctor_id, ctor_id: def.ctor_id,
super_struct: def.super_struct.clone(), super_struct: def.super_struct.clone(),
@ -160,12 +162,12 @@ fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> @ast::StructDef {
} }
} }
fn retain_stmt(cx: &mut Context, stmt: @ast::Stmt) -> bool { fn retain_stmt(cx: &mut Context, stmt: Gc<ast::Stmt>) -> bool {
match stmt.node { match stmt.node {
ast::StmtDecl(decl, _) => { ast::StmtDecl(decl, _) => {
match decl.node { match decl.node {
ast::DeclItem(item) => { ast::DeclItem(ref item) => {
item_in_cfg(cx, item) item_in_cfg(cx, &**item)
} }
_ => true _ => true
} }
@ -175,10 +177,10 @@ fn retain_stmt(cx: &mut Context, stmt: @ast::Stmt) -> bool {
} }
fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> { fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
let resulting_stmts: Vec<&@ast::Stmt> = let resulting_stmts: Vec<&Gc<ast::Stmt>> =
b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect(); b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
let resulting_stmts = resulting_stmts.move_iter() let resulting_stmts = resulting_stmts.move_iter()
.flat_map(|&stmt| cx.fold_stmt(stmt).move_iter()) .flat_map(|stmt| cx.fold_stmt(&**stmt).move_iter())
.collect(); .collect();
let filtered_view_items = b.view_items.iter().filter_map(|a| { let filtered_view_items = b.view_items.iter().filter_map(|a| {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x)) filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
@ -193,14 +195,14 @@ fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
}) })
} }
fn fold_expr(cx: &mut Context, expr: @ast::Expr) -> @ast::Expr { fn fold_expr(cx: &mut Context, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let expr = match expr.node { let expr = match expr.node {
ast::ExprMatch(ref m, ref arms) => { ast::ExprMatch(ref m, ref arms) => {
let arms = arms.iter() let arms = arms.iter()
.filter(|a| (cx.in_cfg)(a.attrs.as_slice())) .filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
.map(|a| a.clone()) .map(|a| a.clone())
.collect(); .collect();
@ast::Expr { box(GC) ast::Expr {
id: expr.id, id: expr.id,
span: expr.span.clone(), span: expr.span.clone(),
node: ast::ExprMatch(m.clone(), arms), node: ast::ExprMatch(m.clone(), arms),
@ -236,7 +238,7 @@ fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
// Determine if an item should be translated in the current crate // Determine if an item should be translated in the current crate
// configuration based on the item's attributes // configuration based on the item's attributes
fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool { fn in_cfg(cfg: &[Gc<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
attr::test_cfg(cfg, attrs.iter().map(|x| *x)) attr::test_cfg(cfg, attrs.iter().map(|x| *x))
} }

View File

@ -23,6 +23,7 @@ use syntax::parse::token;
use syntax::util::small_vector::SmallVector; use syntax::util::small_vector::SmallVector;
use std::mem; use std::mem;
use std::gc::Gc;
pub static VERSION: &'static str = "0.11.0-pre"; pub static VERSION: &'static str = "0.11.0-pre";
@ -165,12 +166,12 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
krate krate
} }
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> { fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
if !no_prelude(item.attrs.as_slice()) { if !no_prelude(item.attrs.as_slice()) {
// only recur if there wasn't `#![no_implicit_prelude]` // only recur if there wasn't `#![no_implicit_prelude]`
// on this item, i.e. this means that the prelude is not // on this item, i.e. this means that the prelude is not
// implicitly imported though the whole subtree // implicitly imported though the whole subtree
fold::noop_fold_item(item, self) fold::noop_fold_item(&*item, self)
} else { } else {
SmallVector::one(item) SmallVector::one(item)
} }
@ -193,7 +194,8 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
}), }),
}; };
let vp = @codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID)); let vp = box(GC) codemap::dummy_spanned(ast::ViewPathGlob(prelude_path,
ast::DUMMY_NODE_ID));
let vi2 = ast::ViewItem { let vi2 = ast::ViewItem {
node: ast::ViewItemUse(vp), node: ast::ViewItemUse(vp),
attrs: Vec::new(), attrs: Vec::new(),

View File

@ -18,8 +18,8 @@ use front::config;
use front::std_inject::with_version; use front::std_inject::with_version;
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use std::slice; use std::slice;
use std::vec::Vec;
use std::vec; use std::vec;
use syntax::ast_util::*; use syntax::ast_util::*;
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
@ -86,7 +86,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
} }
} }
fn fold_item(&mut self, i: @ast::Item) -> SmallVector<@ast::Item> { fn fold_item(&mut self, i: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
self.cx.path.borrow_mut().push(i.ident); self.cx.path.borrow_mut().push(i.ident);
debug!("current path: {}", debug!("current path: {}",
ast_util::path_name_i(self.cx.path.borrow().as_slice())); ast_util::path_name_i(self.cx.path.borrow().as_slice()));
@ -115,7 +115,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
} }
} }
let res = fold::noop_fold_item(i, self); let res = fold::noop_fold_item(&*i, self);
self.cx.path.borrow_mut().pop(); self.cx.path.borrow_mut().pop();
res res
} }
@ -124,8 +124,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
// Remove any #[main] from the AST so it doesn't clash with // Remove any #[main] from the AST so it doesn't clash with
// the one we're going to add. Only if compiling an executable. // the one we're going to add. Only if compiling an executable.
fn nomain(item: @ast::Item) -> @ast::Item { fn nomain(item: Gc<ast::Item>) -> Gc<ast::Item> {
@ast::Item { box(GC) ast::Item {
attrs: item.attrs.iter().filter_map(|attr| { attrs: item.attrs.iter().filter_map(|attr| {
if !attr.name().equiv(&("main")) { if !attr.name().equiv(&("main")) {
Some(*attr) Some(*attr)
@ -188,10 +188,10 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
}) })
} }
fn is_test_fn(cx: &TestCtxt, i: @ast::Item) -> bool { fn is_test_fn(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
let has_test_attr = attr::contains_name(i.attrs.as_slice(), "test"); let has_test_attr = attr::contains_name(i.attrs.as_slice(), "test");
fn has_test_signature(i: @ast::Item) -> bool { fn has_test_signature(i: Gc<ast::Item>) -> bool {
match &i.node { match &i.node {
&ast::ItemFn(ref decl, _, _, ref generics, _) => { &ast::ItemFn(ref decl, _, _, ref generics, _) => {
let no_output = match decl.output.node { let no_output = match decl.output.node {
@ -217,10 +217,10 @@ fn is_test_fn(cx: &TestCtxt, i: @ast::Item) -> bool {
return has_test_attr && has_test_signature(i); return has_test_attr && has_test_signature(i);
} }
fn is_bench_fn(cx: &TestCtxt, i: @ast::Item) -> bool { fn is_bench_fn(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
let has_bench_attr = attr::contains_name(i.attrs.as_slice(), "bench"); let has_bench_attr = attr::contains_name(i.attrs.as_slice(), "bench");
fn has_test_signature(i: @ast::Item) -> bool { fn has_test_signature(i: Gc<ast::Item>) -> bool {
match i.node { match i.node {
ast::ItemFn(ref decl, _, _, ref generics, _) => { ast::ItemFn(ref decl, _, _, ref generics, _) => {
let input_cnt = decl.inputs.len(); let input_cnt = decl.inputs.len();
@ -247,7 +247,7 @@ fn is_bench_fn(cx: &TestCtxt, i: @ast::Item) -> bool {
return has_bench_attr && has_test_signature(i); return has_bench_attr && has_test_signature(i);
} }
fn is_ignored(cx: &TestCtxt, i: @ast::Item) -> bool { fn is_ignored(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
i.attrs.iter().any(|attr| { i.attrs.iter().any(|attr| {
// check ignore(cfg(foo, bar)) // check ignore(cfg(foo, bar))
attr.check_name("ignore") && match attr.meta_item_list() { attr.check_name("ignore") && match attr.meta_item_list() {
@ -259,7 +259,7 @@ fn is_ignored(cx: &TestCtxt, i: @ast::Item) -> bool {
}) })
} }
fn should_fail(i: @ast::Item) -> bool { fn should_fail(i: Gc<ast::Item>) -> bool {
attr::contains_name(i.attrs.as_slice(), "should_fail") attr::contains_name(i.attrs.as_slice(), "should_fail")
} }
@ -293,7 +293,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
let id_test = token::str_to_ident("test"); let id_test = token::str_to_ident("test");
let (vi, vis) = if cx.is_test_crate { let (vi, vis) = if cx.is_test_crate {
(ast::ViewItemUse( (ast::ViewItemUse(
@nospan(ast::ViewPathSimple(id_test, box(GC) nospan(ast::ViewPathSimple(id_test,
path_node(vec!(id_test)), path_node(vec!(id_test)),
ast::DUMMY_NODE_ID))), ast::DUMMY_NODE_ID))),
ast::Public) ast::Public)
@ -311,7 +311,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
} }
} }
fn mk_test_module(cx: &TestCtxt) -> @ast::Item { fn mk_test_module(cx: &TestCtxt) -> Gc<ast::Item> {
// Link to test crate // Link to test crate
let view_items = vec!(mk_std(cx)); let view_items = vec!(mk_std(cx));
@ -352,7 +352,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::Item {
debug!("Synthetic test module:\n{}\n", pprust::item_to_str(&item)); debug!("Synthetic test module:\n{}\n", pprust::item_to_str(&item));
return @item; box(GC) item
} }
fn nospan<T>(t: T) -> codemap::Spanned<T> { fn nospan<T>(t: T) -> codemap::Spanned<T> {
@ -383,7 +383,7 @@ fn path_node_global(ids: Vec<ast::Ident> ) -> ast::Path {
} }
} }
fn mk_tests(cx: &TestCtxt) -> @ast::Item { fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
// The vector of test_descs for this crate // The vector of test_descs for this crate
let test_descs = mk_test_descs(cx); let test_descs = mk_test_descs(cx);
@ -401,12 +401,12 @@ fn is_test_crate(krate: &ast::Crate) -> bool {
} }
} }
fn mk_test_descs(cx: &TestCtxt) -> @ast::Expr { fn mk_test_descs(cx: &TestCtxt) -> Gc<ast::Expr> {
debug!("building test vector from {} tests", cx.testfns.borrow().len()); debug!("building test vector from {} tests", cx.testfns.borrow().len());
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprVstore(@ast::Expr { node: ast::ExprVstore(box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprVec(cx.testfns.borrow().iter().map(|test| { node: ast::ExprVec(cx.testfns.borrow().iter().map(|test| {
mk_test_desc_and_fn_rec(cx, test) mk_test_desc_and_fn_rec(cx, test)
@ -417,7 +417,7 @@ fn mk_test_descs(cx: &TestCtxt) -> @ast::Expr {
} }
} }
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr { fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> Gc<ast::Expr> {
let span = test.span; let span = test.span;
let path = test.path.clone(); let path = test.path.clone();
@ -428,15 +428,15 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::Expr {
ast_util::path_name_i(path.as_slice()).as_slice()), ast_util::path_name_i(path.as_slice()).as_slice()),
ast::CookedStr)); ast::CookedStr));
let name_expr = @ast::Expr { let name_expr = box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprLit(@name_lit), node: ast::ExprLit(box(GC) name_lit),
span: span span: span
}; };
let fn_path = path_node_global(path); let fn_path = path_node_global(path);
let fn_expr = @ast::Expr { let fn_expr = box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(fn_path), node: ast::ExprPath(fn_path),
span: span, span: span,

View File

@ -177,7 +177,7 @@ pub fn get_static_methods_if_impl(cstore: &cstore::CStore,
pub fn get_item_attrs(cstore: &cstore::CStore, pub fn get_item_attrs(cstore: &cstore::CStore,
def_id: ast::DefId, def_id: ast::DefId,
f: |Vec<ast::Attribute> |) { f: |Vec<ast::Attribute>|) {
let cdata = cstore.get_crate_data(def_id.krate); let cdata = cstore.get_crate_data(def_id.krate);
decoder::get_item_attrs(&*cdata, def_id.node, f) decoder::get_item_attrs(&*cdata, def_id.node, f)
} }

View File

@ -28,13 +28,13 @@ use middle::ty;
use middle::typeck; use middle::typeck;
use middle::astencode::vtable_decoder_helpers; use middle::astencode::vtable_decoder_helpers;
use std::u64; use std::gc::Gc;
use std::hash;
use std::hash::Hash; use std::hash::Hash;
use std::io; use std::hash;
use std::io::extensions::u64_from_be_bytes; use std::io::extensions::u64_from_be_bytes;
use std::option; use std::io;
use std::rc::Rc; use std::rc::Rc;
use std::u64;
use serialize::ebml::reader; use serialize::ebml::reader;
use serialize::ebml; use serialize::ebml;
use serialize::Decodable; use serialize::Decodable;
@ -1010,8 +1010,8 @@ pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId)
result result
} }
fn get_meta_items(md: ebml::Doc) -> Vec<@ast::MetaItem> { fn get_meta_items(md: ebml::Doc) -> Vec<Gc<ast::MetaItem>> {
let mut items: Vec<@ast::MetaItem> = Vec::new(); let mut items: Vec<Gc<ast::MetaItem>> = Vec::new();
reader::tagged_docs(md, tag_meta_item_word, |meta_item_doc| { reader::tagged_docs(md, tag_meta_item_word, |meta_item_doc| {
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
let n = token::intern_and_get_ident(nd.as_str_slice()); let n = token::intern_and_get_ident(nd.as_str_slice());
@ -1041,7 +1041,7 @@ fn get_meta_items(md: ebml::Doc) -> Vec<@ast::MetaItem> {
fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> { fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
let mut attrs: Vec<ast::Attribute> = Vec::new(); let mut attrs: Vec<ast::Attribute> = Vec::new();
match reader::maybe_get_doc(md, tag_attributes) { match reader::maybe_get_doc(md, tag_attributes) {
option::Some(attrs_d) => { Some(attrs_d) => {
reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| { reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| {
let meta_items = get_meta_items(attr_doc); let meta_items = get_meta_items(attr_doc);
// Currently it's only possible to have a single meta item on // Currently it's only possible to have a single meta item on
@ -1061,7 +1061,7 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
true true
}); });
} }
option::None => () None => ()
} }
return attrs; return attrs;
} }

View File

@ -27,11 +27,12 @@ use middle;
use util::nodemap::{NodeMap, NodeSet}; use util::nodemap::{NodeMap, NodeSet};
use serialize::Encodable; use serialize::Encodable;
use std::mem;
use std::cell::RefCell; use std::cell::RefCell;
use std::hash; use std::gc::Gc;
use std::hash::Hash; use std::hash::Hash;
use std::hash;
use std::io::MemWriter; use std::io::MemWriter;
use std::mem;
use std::str; use std::str;
use std::collections::HashMap; use std::collections::HashMap;
use syntax::abi; use syntax::abi;
@ -475,7 +476,7 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
/// * For enums, iterates through the node IDs of the variants. /// * For enums, iterates through the node IDs of the variants.
/// ///
/// * For newtype structs, iterates through the node ID of the constructor. /// * For newtype structs, iterates through the node ID of the constructor.
fn each_auxiliary_node_id(item: @Item, callback: |NodeId| -> bool) -> bool { fn each_auxiliary_node_id(item: Gc<Item>, callback: |NodeId| -> bool) -> bool {
let mut continue_ = true; let mut continue_ = true;
match item.node { match item.node {
ItemEnum(ref enum_def, _) => { ItemEnum(ref enum_def, _) => {
@ -746,7 +747,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
impl_path: PathElems, impl_path: PathElems,
is_default_impl: bool, is_default_impl: bool,
parent_id: NodeId, parent_id: NodeId,
ast_method_opt: Option<@Method>) { ast_method_opt: Option<Gc<Method>>) {
debug!("encode_info_for_method: {:?} {}", m.def_id, debug!("encode_info_for_method: {:?} {}", m.def_id,
token::get_ident(m.ident)); token::get_ident(m.ident));
@ -774,7 +775,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
is_default_impl || is_default_impl ||
should_inline(ast_method.attrs.as_slice()) { should_inline(ast_method.attrs.as_slice()) {
encode_inlined_item(ecx, ebml_w, encode_inlined_item(ecx, ebml_w,
IIMethodRef(local_def(parent_id), false, ast_method)); IIMethodRef(local_def(parent_id), false,
&*ast_method));
} else { } else {
encode_symbol(ecx, ebml_w, m.def_id.node); encode_symbol(ecx, ebml_w, m.def_id.node);
} }
@ -1212,7 +1214,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
} }
encode_method_sort(ebml_w, 'p'); encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w, encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, m)); IIMethodRef(def_id, true, &*m));
encode_method_argument_names(ebml_w, &*m.decl); encode_method_argument_names(ebml_w, &*m.decl);
} }
} }
@ -1408,7 +1410,7 @@ fn write_i64(writer: &mut MemWriter, &n: &i64) {
wr.write_be_u32(n as u32); wr.write_be_u32(n as u32);
} }
fn encode_meta_item(ebml_w: &mut Encoder, mi: @MetaItem) { fn encode_meta_item(ebml_w: &mut Encoder, mi: Gc<MetaItem>) {
match mi.node { match mi.node {
MetaWord(ref name) => { MetaWord(ref name) => {
ebml_w.start_tag(tag_meta_item_word); ebml_w.start_tag(tag_meta_item_word);

View File

@ -40,7 +40,6 @@ use std::io::Seek;
use std::io::MemWriter; use std::io::MemWriter;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
use std::string::String;
use serialize::ebml::reader; use serialize::ebml::reader;
use serialize::ebml; use serialize::ebml;
@ -51,6 +50,7 @@ use writer = serialize::ebml::writer;
#[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::parse;
#[cfg(test)] use syntax::print::pprust; #[cfg(test)] use syntax::print::pprust;
#[cfg(test)] use std::gc::Gc;
struct DecodeContext<'a> { struct DecodeContext<'a> {
cdata: &'a cstore::crate_metadata, cdata: &'a cstore::crate_metadata,
@ -146,7 +146,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
match ii { match ii {
ast::IIItem(i) => { ast::IIItem(i) => {
debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<", debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
syntax::print::pprust::item_to_str(i)); syntax::print::pprust::item_to_str(&*i));
} }
_ => { } _ => { }
} }
@ -438,7 +438,7 @@ impl tr for def::Def {
def::DefUse(did) => def::DefUse(did.tr(xcx)), def::DefUse(did) => def::DefUse(did.tr(xcx)),
def::DefUpvar(nid1, def, nid2, nid3) => { def::DefUpvar(nid1, def, nid2, nid3) => {
def::DefUpvar(xcx.tr_id(nid1), def::DefUpvar(xcx.tr_id(nid1),
@(*def).tr(xcx), box(GC) (*def).tr(xcx),
xcx.tr_id(nid2), xcx.tr_id(nid2),
xcx.tr_id(nid3)) xcx.tr_id(nid3))
} }
@ -1395,17 +1395,17 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
// Testing of astencode_gen // Testing of astencode_gen
#[cfg(test)] #[cfg(test)]
fn encode_item_ast(ebml_w: &mut Encoder, item: @ast::Item) { fn encode_item_ast(ebml_w: &mut Encoder, item: Gc<ast::Item>) {
ebml_w.start_tag(c::tag_tree as uint); ebml_w.start_tag(c::tag_tree as uint);
(*item).encode(ebml_w); (*item).encode(ebml_w);
ebml_w.end_tag(); ebml_w.end_tag();
} }
#[cfg(test)] #[cfg(test)]
fn decode_item_ast(par_doc: ebml::Doc) -> @ast::Item { fn decode_item_ast(par_doc: ebml::Doc) -> Gc<ast::Item> {
let chi_doc = par_doc.get(c::tag_tree as uint); let chi_doc = par_doc.get(c::tag_tree as uint);
let mut d = reader::Decoder::new(chi_doc); let mut d = reader::Decoder::new(chi_doc);
@Decodable::decode(&mut d).unwrap() box(GC) Decodable::decode(&mut d).unwrap()
} }
#[cfg(test)] #[cfg(test)]
@ -1440,7 +1440,7 @@ fn mk_ctxt() -> parse::ParseSess {
} }
#[cfg(test)] #[cfg(test)]
fn roundtrip(in_item: Option<@ast::Item>) { fn roundtrip(in_item: Option<Gc<ast::Item>>) {
use std::io::MemWriter; use std::io::MemWriter;
let in_item = in_item.unwrap(); let in_item = in_item.unwrap();

View File

@ -894,4 +894,3 @@ impl<'a> CheckLoanCtxt<'a> {
} }
} }
} }

View File

@ -486,8 +486,8 @@ struct StaticInitializerCtxt<'a> {
impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> { impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> {
fn visit_expr(&mut self, ex: &Expr, _: ()) { fn visit_expr(&mut self, ex: &Expr, _: ()) {
match ex.node { match ex.node {
ast::ExprAddrOf(mutbl, base) => { ast::ExprAddrOf(mutbl, ref base) => {
let base_cmt = self.bccx.cat_expr(base); let base_cmt = self.bccx.cat_expr(&**base);
let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl);
// Check that we don't allow borrows of unsafe static items. // Check that we don't allow borrows of unsafe static items.
if check_aliasability(self.bccx, ex.span, euv::AddrOf, if check_aliasability(self.bccx, ex.span, euv::AddrOf,

View File

@ -106,7 +106,7 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
// flow dependent conditions. // flow dependent conditions.
match item.node { match item.node {
ast::ItemStatic(_, _, ex) => { ast::ItemStatic(_, _, ex) => {
gather_loans::gather_loans_in_static_initializer(this, ex); gather_loans::gather_loans_in_static_initializer(this, &*ex);
} }
_ => { _ => {
visit::walk_item(this, item, ()); visit::walk_item(this, item, ());
@ -480,7 +480,7 @@ impl<'a> BorrowckCtxt<'a> {
move_data::MoveExpr => { move_data::MoveExpr => {
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) { let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
Some(ast_map::NodeExpr(expr)) => { Some(ast_map::NodeExpr(expr)) => {
(ty::expr_ty_adjusted(self.tcx, expr), expr.span) (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
} }
r => { r => {
self.tcx.sess.bug(format!("MoveExpr({:?}) maps to \ self.tcx.sess.bug(format!("MoveExpr({:?}) maps to \
@ -512,7 +512,7 @@ impl<'a> BorrowckCtxt<'a> {
move_data::Captured => { move_data::Captured => {
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) { let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
Some(ast_map::NodeExpr(expr)) => { Some(ast_map::NodeExpr(expr)) => {
(ty::expr_ty_adjusted(self.tcx, expr), expr.span) (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
} }
r => { r => {
self.tcx.sess.bug(format!("Captured({:?}) maps to \ self.tcx.sess.bug(format!("Captured({:?}) maps to \

View File

@ -17,6 +17,8 @@ use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
use util::nodemap::NodeMap; use util::nodemap::NodeMap;
use std::gc::Gc;
struct CFGBuilder<'a> { struct CFGBuilder<'a> {
tcx: &'a ty::ctxt, tcx: &'a ty::ctxt,
exit_map: NodeMap<CFGIndex>, exit_map: NodeMap<CFGIndex>,
@ -66,23 +68,23 @@ fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
impl<'a> CFGBuilder<'a> { impl<'a> CFGBuilder<'a> {
fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex { fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
let mut stmts_exit = pred; let mut stmts_exit = pred;
for &stmt in blk.stmts.iter() { for stmt in blk.stmts.iter() {
stmts_exit = self.stmt(stmt, stmts_exit); stmts_exit = self.stmt(stmt.clone(), stmts_exit);
} }
let expr_exit = self.opt_expr(blk.expr, stmts_exit); let expr_exit = self.opt_expr(blk.expr.clone(), stmts_exit);
self.add_node(blk.id, [expr_exit]) self.add_node(blk.id, [expr_exit])
} }
fn stmt(&mut self, stmt: @ast::Stmt, pred: CFGIndex) -> CFGIndex { fn stmt(&mut self, stmt: Gc<ast::Stmt>, pred: CFGIndex) -> CFGIndex {
match stmt.node { match stmt.node {
ast::StmtDecl(decl, _) => { ast::StmtDecl(ref decl, _) => {
self.decl(decl, pred) self.decl(&**decl, pred)
} }
ast::StmtExpr(expr, _) | ast::StmtSemi(expr, _) => { ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
self.expr(expr, pred) self.expr(expr.clone(), pred)
} }
ast::StmtMac(..) => { ast::StmtMac(..) => {
@ -91,11 +93,11 @@ impl<'a> CFGBuilder<'a> {
} }
} }
fn decl(&mut self, decl: @ast::Decl, pred: CFGIndex) -> CFGIndex { fn decl(&mut self, decl: &ast::Decl, pred: CFGIndex) -> CFGIndex {
match decl.node { match decl.node {
ast::DeclLocal(local) => { ast::DeclLocal(ref local) => {
let init_exit = self.opt_expr(local.init, pred); let init_exit = self.opt_expr(local.init.clone(), pred);
self.pat(local.pat, init_exit) self.pat(&*local.pat, init_exit)
} }
ast::DeclItem(_) => { ast::DeclItem(_) => {
@ -104,7 +106,7 @@ impl<'a> CFGBuilder<'a> {
} }
} }
fn pat(&mut self, pat: @ast::Pat, pred: CFGIndex) -> CFGIndex { fn pat(&mut self, pat: &ast::Pat, pred: CFGIndex) -> CFGIndex {
match pat.node { match pat.node {
ast::PatIdent(_, _, None) | ast::PatIdent(_, _, None) |
ast::PatEnum(_, None) | ast::PatEnum(_, None) |
@ -114,23 +116,23 @@ impl<'a> CFGBuilder<'a> {
self.add_node(pat.id, [pred]) self.add_node(pat.id, [pred])
} }
ast::PatBox(subpat) | ast::PatBox(ref subpat) |
ast::PatRegion(subpat) | ast::PatRegion(ref subpat) |
ast::PatIdent(_, _, Some(subpat)) => { ast::PatIdent(_, _, Some(ref subpat)) => {
let subpat_exit = self.pat(subpat, pred); let subpat_exit = self.pat(&**subpat, pred);
self.add_node(pat.id, [subpat_exit]) self.add_node(pat.id, [subpat_exit])
} }
ast::PatEnum(_, Some(ref subpats)) | ast::PatEnum(_, Some(ref subpats)) |
ast::PatTup(ref subpats) => { ast::PatTup(ref subpats) => {
let pats_exit = let pats_exit =
self.pats_all(subpats.iter().map(|p| *p), pred); self.pats_all(subpats.iter().map(|p| p.clone()), pred);
self.add_node(pat.id, [pats_exit]) self.add_node(pat.id, [pats_exit])
} }
ast::PatStruct(_, ref subpats, _) => { ast::PatStruct(_, ref subpats, _) => {
let pats_exit = let pats_exit =
self.pats_all(subpats.iter().map(|f| f.pat), pred); self.pats_all(subpats.iter().map(|f| f.pat.clone()), pred);
self.add_node(pat.id, [pats_exit]) self.add_node(pat.id, [pats_exit])
} }
@ -150,39 +152,39 @@ impl<'a> CFGBuilder<'a> {
} }
} }
fn pats_all<I: Iterator<@ast::Pat>>(&mut self, fn pats_all<I: Iterator<Gc<ast::Pat>>>(&mut self,
pats: I, pats: I,
pred: CFGIndex) -> CFGIndex { pred: CFGIndex) -> CFGIndex {
//! Handles case where all of the patterns must match. //! Handles case where all of the patterns must match.
let mut pats = pats; let mut pats = pats;
pats.fold(pred, |pred, pat| self.pat(pat, pred)) pats.fold(pred, |pred, pat| self.pat(&*pat, pred))
} }
fn pats_any(&mut self, fn pats_any(&mut self,
pats: &[@ast::Pat], pats: &[Gc<ast::Pat>],
pred: CFGIndex) -> CFGIndex { pred: CFGIndex) -> CFGIndex {
//! Handles case where just one of the patterns must match. //! Handles case where just one of the patterns must match.
if pats.len() == 1 { if pats.len() == 1 {
self.pat(pats[0], pred) self.pat(&*pats[0], pred)
} else { } else {
let collect = self.add_dummy_node([]); let collect = self.add_dummy_node([]);
for &pat in pats.iter() { for &pat in pats.iter() {
let pat_exit = self.pat(pat, pred); let pat_exit = self.pat(&*pat, pred);
self.add_contained_edge(pat_exit, collect); self.add_contained_edge(pat_exit, collect);
} }
collect collect
} }
} }
fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex { fn expr(&mut self, expr: Gc<ast::Expr>, pred: CFGIndex) -> CFGIndex {
match expr.node { match expr.node {
ast::ExprBlock(blk) => { ast::ExprBlock(ref blk) => {
let blk_exit = self.block(blk, pred); let blk_exit = self.block(&**blk, pred);
self.add_node(expr.id, [blk_exit]) self.add_node(expr.id, [blk_exit])
} }
ast::ExprIf(cond, then, None) => { ast::ExprIf(ref cond, ref then, None) => {
// //
// [pred] // [pred]
// | // |
@ -197,12 +199,12 @@ impl<'a> CFGBuilder<'a> {
// v 3 v 4 // v 3 v 4
// [..expr..] // [..expr..]
// //
let cond_exit = self.expr(cond, pred); // 1 let cond_exit = self.expr(cond.clone(), pred); // 1
let then_exit = self.block(then, cond_exit); // 2 let then_exit = self.block(&**then, cond_exit); // 2
self.add_node(expr.id, [cond_exit, then_exit]) // 3,4 self.add_node(expr.id, [cond_exit, then_exit]) // 3,4
} }
ast::ExprIf(cond, then, Some(otherwise)) => { ast::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
// //
// [pred] // [pred]
// | // |
@ -217,13 +219,13 @@ impl<'a> CFGBuilder<'a> {
// v 4 v 5 // v 4 v 5
// [..expr..] // [..expr..]
// //
let cond_exit = self.expr(cond, pred); // 1 let cond_exit = self.expr(cond.clone(), pred); // 1
let then_exit = self.block(then, cond_exit); // 2 let then_exit = self.block(&**then, cond_exit); // 2
let else_exit = self.expr(otherwise, cond_exit); // 3 let else_exit = self.expr(otherwise.clone(), cond_exit); // 3
self.add_node(expr.id, [then_exit, else_exit]) // 4, 5 self.add_node(expr.id, [then_exit, else_exit]) // 4, 5
} }
ast::ExprWhile(cond, body) => { ast::ExprWhile(ref cond, ref body) => {
// //
// [pred] // [pred]
// | // |
@ -242,22 +244,22 @@ impl<'a> CFGBuilder<'a> {
// may cause additional edges. // may cause additional edges.
// Is the condition considered part of the loop? // Is the condition considered part of the loop?
let loopback = self.add_dummy_node([pred]); // 1 let loopback = self.add_dummy_node([pred]); // 1
let cond_exit = self.expr(cond, loopback); // 2 let cond_exit = self.expr(cond.clone(), loopback); // 2
let expr_exit = self.add_node(expr.id, [cond_exit]); // 3 let expr_exit = self.add_node(expr.id, [cond_exit]); // 3
self.loop_scopes.push(LoopScope { self.loop_scopes.push(LoopScope {
loop_id: expr.id, loop_id: expr.id,
continue_index: loopback, continue_index: loopback,
break_index: expr_exit break_index: expr_exit
}); });
let body_exit = self.block(body, cond_exit); // 4 let body_exit = self.block(&**body, cond_exit); // 4
self.add_contained_edge(body_exit, loopback); // 5 self.add_contained_edge(body_exit, loopback); // 5
expr_exit expr_exit
} }
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
ast::ExprLoop(body, _) => { ast::ExprLoop(ref body, _) => {
// //
// [pred] // [pred]
// | // |
@ -272,20 +274,20 @@ impl<'a> CFGBuilder<'a> {
// Note that `break` and `loop` statements // Note that `break` and `loop` statements
// may cause additional edges. // may cause additional edges.
let loopback = self.add_dummy_node([pred]); // 1 let loopback = self.add_dummy_node([pred]); // 1
let expr_exit = self.add_node(expr.id, []); // 2 let expr_exit = self.add_node(expr.id, []); // 2
self.loop_scopes.push(LoopScope { self.loop_scopes.push(LoopScope {
loop_id: expr.id, loop_id: expr.id,
continue_index: loopback, continue_index: loopback,
break_index: expr_exit, break_index: expr_exit,
}); });
let body_exit = self.block(body, loopback); // 3 let body_exit = self.block(&**body, loopback); // 3
self.add_contained_edge(body_exit, loopback); // 4 self.add_contained_edge(body_exit, loopback); // 4
self.loop_scopes.pop(); self.loop_scopes.pop();
expr_exit expr_exit
} }
ast::ExprMatch(discr, ref arms) => { ast::ExprMatch(ref discr, ref arms) => {
// //
// [pred] // [pred]
// | // |
@ -309,21 +311,21 @@ impl<'a> CFGBuilder<'a> {
// v 5 v v // v 5 v v
// [....expr....] // [....expr....]
// //
let discr_exit = self.expr(discr, pred); // 1 let discr_exit = self.expr(discr.clone(), pred); // 1
let expr_exit = self.add_node(expr.id, []); let expr_exit = self.add_node(expr.id, []);
let mut guard_exit = discr_exit; let mut guard_exit = discr_exit;
for arm in arms.iter() { for arm in arms.iter() {
guard_exit = self.opt_expr(arm.guard, guard_exit); // 2 guard_exit = self.opt_expr(arm.guard, guard_exit); // 2
let pats_exit = self.pats_any(arm.pats.as_slice(), let pats_exit = self.pats_any(arm.pats.as_slice(),
guard_exit); // 3 guard_exit); // 3
let body_exit = self.expr(arm.body, pats_exit); // 4 let body_exit = self.expr(arm.body.clone(), pats_exit); // 4
self.add_contained_edge(body_exit, expr_exit); // 5 self.add_contained_edge(body_exit, expr_exit); // 5
} }
expr_exit expr_exit
} }
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => { ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
// //
// [pred] // [pred]
// | // |
@ -338,13 +340,13 @@ impl<'a> CFGBuilder<'a> {
// v 3 v 4 // v 3 v 4
// [..exit..] // [..exit..]
// //
let l_exit = self.expr(l, pred); // 1 let l_exit = self.expr(l.clone(), pred); // 1
let r_exit = self.expr(r, l_exit); // 2 let r_exit = self.expr(r.clone(), l_exit); // 2
self.add_node(expr.id, [l_exit, r_exit]) // 3,4 self.add_node(expr.id, [l_exit, r_exit]) // 3,4
} }
ast::ExprRet(v) => { ast::ExprRet(ref v) => {
let v_exit = self.opt_expr(v, pred); let v_exit = self.opt_expr(v.clone(), pred);
let b = self.add_node(expr.id, [v_exit]); let b = self.add_node(expr.id, [v_exit]);
self.add_returning_edge(expr, b); self.add_returning_edge(expr, b);
self.add_node(ast::DUMMY_NODE_ID, []) self.add_node(ast::DUMMY_NODE_ID, [])
@ -370,21 +372,21 @@ impl<'a> CFGBuilder<'a> {
self.straightline(expr, pred, elems.as_slice()) self.straightline(expr, pred, elems.as_slice())
} }
ast::ExprCall(func, ref args) => { ast::ExprCall(ref func, ref args) => {
self.call(expr, pred, func, args.as_slice()) self.call(expr, pred, func.clone(), args.as_slice())
} }
ast::ExprMethodCall(_, _, ref args) => { ast::ExprMethodCall(_, _, ref args) => {
self.call(expr, pred, *args.get(0), args.slice_from(1)) self.call(expr, pred, *args.get(0), args.slice_from(1))
} }
ast::ExprIndex(l, r) | ast::ExprIndex(ref l, ref r) |
ast::ExprBinary(_, l, r) if self.is_method_call(expr) => { ast::ExprBinary(_, ref l, ref r) if self.is_method_call(&*expr) => {
self.call(expr, pred, l, [r]) self.call(expr, pred, l.clone(), [r.clone()])
} }
ast::ExprUnary(_, e) if self.is_method_call(expr) => { ast::ExprUnary(_, ref e) if self.is_method_call(&*expr) => {
self.call(expr, pred, e, []) self.call(expr, pred, e.clone(), [])
} }
ast::ExprTup(ref exprs) => { ast::ExprTup(ref exprs) => {
@ -393,7 +395,7 @@ impl<'a> CFGBuilder<'a> {
ast::ExprStruct(_, ref fields, base) => { ast::ExprStruct(_, ref fields, base) => {
let base_exit = self.opt_expr(base, pred); let base_exit = self.opt_expr(base, pred);
let field_exprs: Vec<@ast::Expr> = let field_exprs: Vec<Gc<ast::Expr>> =
fields.iter().map(|f| f.expr).collect(); fields.iter().map(|f| f.expr).collect();
self.straightline(expr, base_exit, field_exprs.as_slice()) self.straightline(expr, base_exit, field_exprs.as_slice())
} }
@ -437,16 +439,16 @@ impl<'a> CFGBuilder<'a> {
} }
fn call(&mut self, fn call(&mut self,
call_expr: @ast::Expr, call_expr: Gc<ast::Expr>,
pred: CFGIndex, pred: CFGIndex,
func_or_rcvr: @ast::Expr, func_or_rcvr: Gc<ast::Expr>,
args: &[@ast::Expr]) -> CFGIndex { args: &[Gc<ast::Expr>]) -> CFGIndex {
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
self.straightline(call_expr, func_or_rcvr_exit, args) self.straightline(call_expr, func_or_rcvr_exit, args)
} }
fn exprs(&mut self, fn exprs(&mut self,
exprs: &[@ast::Expr], exprs: &[Gc<ast::Expr>],
pred: CFGIndex) -> CFGIndex { pred: CFGIndex) -> CFGIndex {
//! Constructs graph for `exprs` evaluated in order //! Constructs graph for `exprs` evaluated in order
@ -454,7 +456,7 @@ impl<'a> CFGBuilder<'a> {
} }
fn opt_expr(&mut self, fn opt_expr(&mut self,
opt_expr: Option<@ast::Expr>, opt_expr: Option<Gc<ast::Expr>>,
pred: CFGIndex) -> CFGIndex { pred: CFGIndex) -> CFGIndex {
//! Constructs graph for `opt_expr` evaluated, if Some //! Constructs graph for `opt_expr` evaluated, if Some
@ -462,9 +464,9 @@ impl<'a> CFGBuilder<'a> {
} }
fn straightline(&mut self, fn straightline(&mut self,
expr: @ast::Expr, expr: Gc<ast::Expr>,
pred: CFGIndex, pred: CFGIndex,
subexprs: &[@ast::Expr]) -> CFGIndex { subexprs: &[Gc<ast::Expr>]) -> CFGIndex {
//! Handles case of an expression that evaluates `subexprs` in order //! Handles case of an expression that evaluates `subexprs` in order
let subexprs_exit = self.exprs(subexprs, pred); let subexprs_exit = self.exprs(subexprs, pred);
@ -496,7 +498,7 @@ impl<'a> CFGBuilder<'a> {
} }
fn add_exiting_edge(&mut self, fn add_exiting_edge(&mut self,
from_expr: @ast::Expr, from_expr: Gc<ast::Expr>,
from_index: CFGIndex, from_index: CFGIndex,
to_loop: LoopScope, to_loop: LoopScope,
to_index: CFGIndex) { to_index: CFGIndex) {
@ -511,7 +513,7 @@ impl<'a> CFGBuilder<'a> {
} }
fn add_returning_edge(&mut self, fn add_returning_edge(&mut self,
_from_expr: @ast::Expr, _from_expr: Gc<ast::Expr>,
from_index: CFGIndex) { from_index: CFGIndex) {
let mut data = CFGEdgeData { let mut data = CFGEdgeData {
exiting_scopes: vec!(), exiting_scopes: vec!(),
@ -523,7 +525,7 @@ impl<'a> CFGBuilder<'a> {
} }
fn find_scope(&self, fn find_scope(&self,
expr: @ast::Expr, expr: Gc<ast::Expr>,
label: Option<ast::Ident>) -> LoopScope { label: Option<ast::Ident>) -> LoopScope {
match label { match label {
None => { None => {

View File

@ -45,13 +45,13 @@ pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) {
fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) { fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) {
match it.node { match it.node {
ItemStatic(_, _, ex) => { ItemStatic(_, _, ex) => {
v.visit_expr(ex, true); v.visit_expr(&*ex, true);
check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it); check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it);
} }
ItemEnum(ref enum_definition, _) => { ItemEnum(ref enum_definition, _) => {
for var in (*enum_definition).variants.iter() { for var in (*enum_definition).variants.iter() {
for ex in var.node.disr_expr.iter() { for ex in var.node.disr_expr.iter() {
v.visit_expr(*ex, true); v.visit_expr(&**ex, true);
} }
} }
} }
@ -73,10 +73,10 @@ fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) {
} }
match p.node { match p.node {
// Let through plain ~-string literals here // Let through plain ~-string literals here
PatLit(a) => if !is_str(a) { v.visit_expr(a, true); }, PatLit(ref a) => if !is_str(&**a) { v.visit_expr(&**a, true); },
PatRange(a, b) => { PatRange(ref a, ref b) => {
if !is_str(a) { v.visit_expr(a, true); } if !is_str(&**a) { v.visit_expr(&**a, true); }
if !is_str(b) { v.visit_expr(b, true); } if !is_str(&**b) { v.visit_expr(&**b, true); }
} }
_ => visit::walk_pat(v, p, false) _ => visit::walk_pat(v, p, false)
} }
@ -245,7 +245,7 @@ impl<'a> Visitor<()> for CheckItemRecursionVisitor<'a> {
match self.def_map.borrow().find(&e.id) { match self.def_map.borrow().find(&e.id) {
Some(&DefStatic(def_id, _)) if Some(&DefStatic(def_id, _)) if
ast_util::is_local(def_id) => { ast_util::is_local(def_id) => {
self.visit_item(self.ast_map.expect_item(def_id.node), ()); self.visit_item(&*self.ast_map.expect_item(def_id.node), ());
} }
_ => () _ => ()
} }

View File

@ -35,15 +35,15 @@ impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, cx:Context) { fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
match e.node { match e.node {
ast::ExprWhile(e, b) => { ast::ExprWhile(ref e, ref b) => {
self.visit_expr(e, cx); self.visit_expr(&**e, cx);
self.visit_block(b, Loop); self.visit_block(&**b, Loop);
} }
ast::ExprLoop(b, _) => { ast::ExprLoop(ref b, _) => {
self.visit_block(b, Loop); self.visit_block(&**b, Loop);
} }
ast::ExprFnBlock(_, b) | ast::ExprProc(_, b) => { ast::ExprFnBlock(_, ref b) | ast::ExprProc(_, ref b) => {
self.visit_block(b, Closure); self.visit_block(&**b, Closure);
} }
ast::ExprBreak(_) => self.require_loop("break", cx, e.span), ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
ast::ExprAgain(_) => self.require_loop("continue", cx, e.span), ast::ExprAgain(_) => self.require_loop("continue", cx, e.span),

View File

@ -19,6 +19,7 @@ use middle::ty;
use util::ppaux::ty_to_str; use util::ppaux::ty_to_str;
use std::cmp; use std::cmp;
use std::gc::Gc;
use std::iter; use std::iter;
use syntax::ast::*; use syntax::ast::*;
use syntax::ast_util::{is_unguarded, walk_pat}; use syntax::ast_util::{is_unguarded, walk_pat};
@ -104,7 +105,7 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
match opt_def { match opt_def {
Some(DefStatic(did, false)) => { Some(DefStatic(did, false)) => {
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap(); let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
match eval_const_expr(cx.tcx, const_expr) { match eval_const_expr(cx.tcx, &*const_expr) {
const_float(f) if f.is_nan() => true, const_float(f) if f.is_nan() => true,
_ => false _ => false
} }
@ -113,7 +114,7 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
} }
}; };
walk_pat(*pat, |p| { walk_pat(&**pat, |p| {
if pat_matches_nan(p) { if pat_matches_nan(p) {
cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \ cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \
use the is_nan method in a guard instead"); use the is_nan method in a guard instead");
@ -133,7 +134,7 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
} }
} }
fn raw_pat(p: @Pat) -> @Pat { fn raw_pat(p: Gc<Pat>) -> Gc<Pat> {
match p.node { match p.node {
PatIdent(_, _, Some(s)) => { raw_pat(s) } PatIdent(_, _, Some(s)) => { raw_pat(s) }
_ => { p } _ => { p }
@ -193,7 +194,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &matrix) {
cx.tcx.sess.span_err(sp, msg.as_slice()); cx.tcx.sess.span_err(sp, msg.as_slice());
} }
type matrix = Vec<Vec<@Pat> > ; type matrix = Vec<Vec<Gc<Pat>>>;
#[deriving(Clone)] #[deriving(Clone)]
enum useful { enum useful {
@ -224,7 +225,7 @@ enum ctor {
// Note: is_useful doesn't work on empty types, as the paper notes. // Note: is_useful doesn't work on empty types, as the paper notes.
// So it assumes that v is non-empty. // So it assumes that v is non-empty.
fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful { fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[Gc<Pat>]) -> useful {
if m.len() == 0u { if m.len() == 0u {
return useful_; return useful_;
} }
@ -327,7 +328,7 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
fn is_useful_specialized(cx: &MatchCheckCtxt, fn is_useful_specialized(cx: &MatchCheckCtxt,
m: &matrix, m: &matrix,
v: &[@Pat], v: &[Gc<Pat>],
ctor: ctor, ctor: ctor,
arity: uint, arity: uint,
lty: ty::t) lty: ty::t)
@ -345,7 +346,7 @@ fn is_useful_specialized(cx: &MatchCheckCtxt,
} }
} }
fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> { fn pat_ctor_id(cx: &MatchCheckCtxt, p: Gc<Pat>) -> Option<ctor> {
let pat = raw_pat(p); let pat = raw_pat(p);
match pat.node { match pat.node {
PatWild | PatWildMulti => { None } PatWild | PatWildMulti => { None }
@ -355,14 +356,14 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
Some(DefVariant(_, id, _)) => Some(variant(id)), Some(DefVariant(_, id, _)) => Some(variant(id)),
Some(DefStatic(did, false)) => { Some(DefStatic(did, false)) => {
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap(); let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
Some(val(eval_const_expr(cx.tcx, const_expr))) Some(val(eval_const_expr(cx.tcx, &*const_expr)))
} }
_ => None _ => None
} }
} }
PatLit(expr) => { Some(val(eval_const_expr(cx.tcx, expr))) } PatLit(ref expr) => { Some(val(eval_const_expr(cx.tcx, &**expr))) }
PatRange(lo, hi) => { PatRange(ref lo, ref hi) => {
Some(range(eval_const_expr(cx.tcx, lo), eval_const_expr(cx.tcx, hi))) Some(range(eval_const_expr(cx.tcx, &**lo), eval_const_expr(cx.tcx, &**hi)))
} }
PatStruct(..) => { PatStruct(..) => {
match cx.tcx.def_map.borrow().find(&pat.id) { match cx.tcx.def_map.borrow().find(&pat.id) {
@ -383,7 +384,7 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
} }
} }
fn is_wild(cx: &MatchCheckCtxt, p: @Pat) -> bool { fn is_wild(cx: &MatchCheckCtxt, p: Gc<Pat>) -> bool {
let pat = raw_pat(p); let pat = raw_pat(p);
match pat.node { match pat.node {
PatWild | PatWildMulti => { true } PatWild | PatWildMulti => { true }
@ -548,12 +549,12 @@ fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
} }
} }
fn wild() -> @Pat { fn wild() -> Gc<Pat> {
@Pat {id: 0, node: PatWild, span: DUMMY_SP} box(GC) Pat {id: 0, node: PatWild, span: DUMMY_SP}
} }
fn wild_multi() -> @Pat { fn wild_multi() -> Gc<Pat> {
@Pat {id: 0, node: PatWildMulti, span: DUMMY_SP} box(GC) Pat {id: 0, node: PatWildMulti, span: DUMMY_SP}
} }
fn range_covered_by_constructor(ctor_id: &ctor, from: &const_val, to: &const_val) -> Option<bool> { fn range_covered_by_constructor(ctor_id: &ctor, from: &const_val, to: &const_val) -> Option<bool> {
@ -572,13 +573,13 @@ fn range_covered_by_constructor(ctor_id: &ctor, from: &const_val, to: &const_val
} }
fn specialize(cx: &MatchCheckCtxt, fn specialize(cx: &MatchCheckCtxt,
r: &[@Pat], r: &[Gc<Pat>],
ctor_id: &ctor, ctor_id: &ctor,
arity: uint, arity: uint,
left_ty: ty::t) left_ty: ty::t)
-> Option<Vec<@Pat> > { -> Option<Vec<Gc<Pat>>> {
let &Pat{id: ref pat_id, node: ref n, span: ref pat_span} = &(*raw_pat(r[0])); let &Pat{id: ref pat_id, node: ref n, span: ref pat_span} = &(*raw_pat(r[0]));
let head: Option<Vec<@Pat>> = match n { let head: Option<Vec<Gc<Pat>>> = match n {
&PatWild => { &PatWild => {
Some(Vec::from_elem(arity, wild())) Some(Vec::from_elem(arity, wild()))
} }
@ -597,7 +598,7 @@ fn specialize(cx: &MatchCheckCtxt,
} }
Some(DefStatic(did, _)) => { Some(DefStatic(did, _)) => {
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap(); let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
let e_v = eval_const_expr(cx.tcx, const_expr); let e_v = eval_const_expr(cx.tcx, &*const_expr);
match range_covered_by_constructor(ctor_id, &e_v, &e_v) { match range_covered_by_constructor(ctor_id, &e_v, &e_v) {
Some(true) => Some(vec!()), Some(true) => Some(vec!()),
Some(false) => None, Some(false) => None,
@ -617,7 +618,7 @@ fn specialize(cx: &MatchCheckCtxt,
match def { match def {
DefStatic(did, _) => { DefStatic(did, _) => {
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap(); let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
let e_v = eval_const_expr(cx.tcx, const_expr); let e_v = eval_const_expr(cx.tcx, &*const_expr);
match range_covered_by_constructor(ctor_id, &e_v, &e_v) { match range_covered_by_constructor(ctor_id, &e_v, &e_v) {
Some(true) => Some(vec!()), Some(true) => Some(vec!()),
Some(false) => None, Some(false) => None,
@ -681,7 +682,7 @@ fn specialize(cx: &MatchCheckCtxt,
Some(vec!(inner.clone())) Some(vec!(inner.clone()))
} }
&PatLit(ref expr) => { &PatLit(ref expr) => {
let expr_value = eval_const_expr(cx.tcx, *expr); let expr_value = eval_const_expr(cx.tcx, &**expr);
match range_covered_by_constructor(ctor_id, &expr_value, &expr_value) { match range_covered_by_constructor(ctor_id, &expr_value, &expr_value) {
Some(true) => Some(vec!()), Some(true) => Some(vec!()),
Some(false) => None, Some(false) => None,
@ -692,8 +693,8 @@ fn specialize(cx: &MatchCheckCtxt,
} }
} }
&PatRange(ref from, ref to) => { &PatRange(ref from, ref to) => {
let from_value = eval_const_expr(cx.tcx, *from); let from_value = eval_const_expr(cx.tcx, &**from);
let to_value = eval_const_expr(cx.tcx, *to); let to_value = eval_const_expr(cx.tcx, &**to);
match range_covered_by_constructor(ctor_id, &from_value, &to_value) { match range_covered_by_constructor(ctor_id, &from_value, &to_value) {
Some(true) => Some(vec!()), Some(true) => Some(vec!()),
Some(false) => None, Some(false) => None,
@ -733,7 +734,7 @@ fn specialize(cx: &MatchCheckCtxt,
head.map(|head| head.append(r.tail())) head.map(|head| head.append(r.tail()))
} }
fn default(cx: &MatchCheckCtxt, r: &[@Pat]) -> Option<Vec<@Pat> > { fn default(cx: &MatchCheckCtxt, r: &[Gc<Pat>]) -> Option<Vec<Gc<Pat>>> {
if is_wild(cx, r[0]) { if is_wild(cx, r[0]) {
Some(Vec::from_slice(r.tail())) Some(Vec::from_slice(r.tail()))
} else { } else {
@ -750,7 +751,7 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
}; };
let mut spans = vec![]; let mut spans = vec![];
find_refutable(cx, loc.pat, &mut spans); find_refutable(cx, &*loc.pat, &mut spans);
for span in spans.iter() { for span in spans.iter() {
cx.tcx.sess.span_err(*span, cx.tcx.sess.span_err(*span,
@ -769,7 +770,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
visit::walk_fn(cx, kind, decl, body, sp, ()); visit::walk_fn(cx, kind, decl, body, sp, ());
for input in decl.inputs.iter() { for input in decl.inputs.iter() {
let mut spans = vec![]; let mut spans = vec![];
find_refutable(cx, input.pat, &mut spans); find_refutable(cx, &*input.pat, &mut spans);
for span in spans.iter() { for span in spans.iter() {
cx.tcx.sess.span_err(*span, cx.tcx.sess.span_err(*span,
@ -799,8 +800,8 @@ fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) {
} }
match pat.node { match pat.node {
PatBox(sub) | PatRegion(sub) | PatIdent(_, _, Some(sub)) => { PatBox(ref sub) | PatRegion(ref sub) | PatIdent(_, _, Some(ref sub)) => {
find_refutable(cx, sub, spans) find_refutable(cx, &**sub, spans)
} }
PatWild | PatWildMulti | PatIdent(_, _, None) => {} PatWild | PatWildMulti | PatIdent(_, _, None) => {}
PatLit(lit) => { PatLit(lit) => {
@ -817,12 +818,12 @@ fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) {
PatRange(_, _) => { this_pattern!() } PatRange(_, _) => { this_pattern!() }
PatStruct(_, ref fields, _) => { PatStruct(_, ref fields, _) => {
for f in fields.iter() { for f in fields.iter() {
find_refutable(cx, f.pat, spans); find_refutable(cx, &*f.pat, spans);
} }
} }
PatTup(ref elts) | PatEnum(_, Some(ref elts))=> { PatTup(ref elts) | PatEnum(_, Some(ref elts))=> {
for elt in elts.iter() { for elt in elts.iter() {
find_refutable(cx, *elt, spans) find_refutable(cx, &**elt, spans)
} }
} }
PatEnum(_,_) => {} PatEnum(_,_) => {}
@ -835,12 +836,12 @@ fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) {
fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
has_guard: bool, has_guard: bool,
pats: &[@Pat]) { pats: &[Gc<Pat>]) {
let tcx = cx.tcx; let tcx = cx.tcx;
let def_map = &tcx.def_map; let def_map = &tcx.def_map;
let mut by_ref_span = None; let mut by_ref_span = None;
for pat in pats.iter() { for pat in pats.iter() {
pat_bindings(def_map, *pat, |bm, _, span, _path| { pat_bindings(def_map, &**pat, |bm, _, span, _path| {
match bm { match bm {
BindByRef(_) => { BindByRef(_) => {
by_ref_span = Some(span); by_ref_span = Some(span);
@ -851,11 +852,11 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
}) })
} }
let check_move: |&Pat, Option<@Pat>| = |p, sub| { let check_move: |&Pat, Option<Gc<Pat>>| = |p, sub| {
// check legality of moving out of the enum // check legality of moving out of the enum
// x @ Foo(..) is legal, but x @ Foo(y) isn't. // x @ Foo(..) is legal, but x @ Foo(y) isn't.
if sub.map_or(false, |p| pat_contains_bindings(def_map, p)) { if sub.map_or(false, |p| pat_contains_bindings(def_map, &*p)) {
tcx.sess.span_err( tcx.sess.span_err(
p.span, p.span,
"cannot bind by-move with sub-bindings"); "cannot bind by-move with sub-bindings");
@ -875,8 +876,8 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
}; };
for pat in pats.iter() { for pat in pats.iter() {
walk_pat(*pat, |p| { walk_pat(&**pat, |p| {
if pat_is_binding(def_map, p) { if pat_is_binding(def_map, &*p) {
match p.node { match p.node {
PatIdent(BindByValue(_), _, sub) => { PatIdent(BindByValue(_), _, sub) => {
let pat_ty = ty::node_id_to_type(tcx, p.id); let pat_ty = ty::node_id_to_type(tcx, p.id);

View File

@ -77,13 +77,14 @@ impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
fn visit_item(&mut self, i: &ast::Item, _is_const: bool) { fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
debug!("visit_item(item={})", pprust::item_to_str(i)); debug!("visit_item(item={})", pprust::item_to_str(i));
match i.node { match i.node {
ast::ItemStatic(_, mutability, expr) => { ast::ItemStatic(_, mutability, ref expr) => {
match mutability { match mutability {
ast::MutImmutable => { ast::MutImmutable => {
self.visit_expr(expr, true); self.visit_expr(&**expr, true);
} }
ast::MutMutable => { ast::MutMutable => {
self.report_error(expr.span, safe_type_for_static_mut(self.tcx, expr)); let safe = safe_type_for_static_mut(self.tcx, &**expr);
self.report_error(expr.span, safe);
} }
} }
} }

View File

@ -26,6 +26,7 @@ use syntax::visit;
use syntax::{ast, ast_map, ast_util}; use syntax::{ast, ast_map, ast_util};
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
// //
// This pass classifies expressions by their constant-ness. // This pass classifies expressions by their constant-ness.
@ -81,7 +82,7 @@ pub fn join_all<It: Iterator<constness>>(mut cs: It) -> constness {
cs.fold(integral_const, |a, b| join(a, b)) cs.fold(integral_const, |a, b| join(a, b))
} }
pub fn lookup_const(tcx: &ty::ctxt, e: &Expr) -> Option<@Expr> { pub fn lookup_const(tcx: &ty::ctxt, e: &Expr) -> Option<Gc<Expr>> {
let opt_def = tcx.def_map.borrow().find_copy(&e.id); let opt_def = tcx.def_map.borrow().find_copy(&e.id);
match opt_def { match opt_def {
Some(def::DefStatic(def_id, false)) => { Some(def::DefStatic(def_id, false)) => {
@ -97,8 +98,9 @@ pub fn lookup_const(tcx: &ty::ctxt, e: &Expr) -> Option<@Expr> {
pub fn lookup_variant_by_id(tcx: &ty::ctxt, pub fn lookup_variant_by_id(tcx: &ty::ctxt,
enum_def: ast::DefId, enum_def: ast::DefId,
variant_def: ast::DefId) variant_def: ast::DefId)
-> Option<@Expr> { -> Option<Gc<Expr>> {
fn variant_expr(variants: &[ast::P<ast::Variant>], id: ast::NodeId) -> Option<@Expr> { fn variant_expr(variants: &[ast::P<ast::Variant>],
id: ast::NodeId) -> Option<Gc<Expr>> {
for variant in variants.iter() { for variant in variants.iter() {
if variant.node.id == id { if variant.node.id == id {
return variant.node.disr_expr; return variant.node.disr_expr;
@ -141,7 +143,7 @@ pub fn lookup_variant_by_id(tcx: &ty::ctxt,
} }
pub fn lookup_const_by_id(tcx: &ty::ctxt, def_id: ast::DefId) pub fn lookup_const_by_id(tcx: &ty::ctxt, def_id: ast::DefId)
-> Option<@Expr> { -> Option<Gc<Expr>> {
if ast_util::is_local(def_id) { if ast_util::is_local(def_id) {
{ {
match tcx.map.find(def_id.node) { match tcx.map.find(def_id.node) {
@ -186,39 +188,39 @@ impl<'a> ConstEvalVisitor<'a> {
None => {} None => {}
} }
let cn = match e.node { let cn = match e.node {
ast::ExprLit(lit) => { ast::ExprLit(ref lit) => {
match lit.node { match lit.node {
ast::LitStr(..) | ast::LitFloat(..) => general_const, ast::LitStr(..) | ast::LitFloat(..) => general_const,
_ => integral_const _ => integral_const
} }
} }
ast::ExprUnary(_, inner) | ast::ExprParen(inner) => ast::ExprUnary(_, ref inner) | ast::ExprParen(ref inner) =>
self.classify(inner), self.classify(&**inner),
ast::ExprBinary(_, a, b) => ast::ExprBinary(_, ref a, ref b) =>
join(self.classify(a), self.classify(b)), join(self.classify(&**a), self.classify(&**b)),
ast::ExprTup(ref es) | ast::ExprTup(ref es) |
ast::ExprVec(ref es) => ast::ExprVec(ref es) =>
join_all(es.iter().map(|e| self.classify(*e))), join_all(es.iter().map(|e| self.classify(&**e))),
ast::ExprVstore(e, vstore) => { ast::ExprVstore(ref e, vstore) => {
match vstore { match vstore {
ast::ExprVstoreSlice => self.classify(e), ast::ExprVstoreSlice => self.classify(&**e),
ast::ExprVstoreUniq | ast::ExprVstoreUniq |
ast::ExprVstoreMutSlice => non_const ast::ExprVstoreMutSlice => non_const
} }
} }
ast::ExprStruct(_, ref fs, None) => { ast::ExprStruct(_, ref fs, None) => {
let cs = fs.iter().map(|f| self.classify(f.expr)); let cs = fs.iter().map(|f| self.classify(&*f.expr));
join_all(cs) join_all(cs)
} }
ast::ExprCast(base, _) => { ast::ExprCast(ref base, _) => {
let ty = ty::expr_ty(self.tcx, e); let ty = ty::expr_ty(self.tcx, e);
let base = self.classify(base); let base = self.classify(&**base);
if ty::type_is_integral(ty) { if ty::type_is_integral(ty) {
join(integral_const, base) join(integral_const, base)
} else if ty::type_is_fp(ty) { } else if ty::type_is_fp(ty) {
@ -228,12 +230,13 @@ impl<'a> ConstEvalVisitor<'a> {
} }
} }
ast::ExprField(base, _, _) => self.classify(base), ast::ExprField(ref base, _, _) => self.classify(&**base),
ast::ExprIndex(base, idx) => ast::ExprIndex(ref base, ref idx) =>
join(self.classify(base), self.classify(idx)), join(self.classify(&**base), self.classify(&**idx)),
ast::ExprAddrOf(ast::MutImmutable, base) => self.classify(base), ast::ExprAddrOf(ast::MutImmutable, ref base) =>
self.classify(&**base),
// FIXME: (#3728) we can probably do something CCI-ish // FIXME: (#3728) we can probably do something CCI-ish
// surrounding nonlocal constants. But we don't yet. // surrounding nonlocal constants. But we don't yet.
@ -257,7 +260,7 @@ impl<'a> ConstEvalVisitor<'a> {
fn lookup_constness(&self, e: &Expr) -> constness { fn lookup_constness(&self, e: &Expr) -> constness {
match lookup_const(self.tcx, e) { match lookup_const(self.tcx, e) {
Some(rhs) => { Some(rhs) => {
let ty = ty::expr_ty(self.tcx, rhs); let ty = ty::expr_ty(self.tcx, &*rhs);
if ty::type_is_integral(ty) { if ty::type_is_integral(ty) {
integral_const integral_const
} else { } else {
@ -310,8 +313,8 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
-> Result<const_val, String> { -> Result<const_val, String> {
fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) } fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
match e.node { match e.node {
ExprUnary(UnNeg, inner) => { ExprUnary(UnNeg, ref inner) => {
match eval_const_expr_partial(tcx, inner) { match eval_const_expr_partial(tcx, &**inner) {
Ok(const_float(f)) => Ok(const_float(-f)), Ok(const_float(f)) => Ok(const_float(-f)),
Ok(const_int(i)) => Ok(const_int(-i)), Ok(const_int(i)) => Ok(const_int(-i)),
Ok(const_uint(i)) => Ok(const_uint(-i)), Ok(const_uint(i)) => Ok(const_uint(-i)),
@ -320,17 +323,17 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
ref err => ((*err).clone()) ref err => ((*err).clone())
} }
} }
ExprUnary(UnNot, inner) => { ExprUnary(UnNot, ref inner) => {
match eval_const_expr_partial(tcx, inner) { match eval_const_expr_partial(tcx, &**inner) {
Ok(const_int(i)) => Ok(const_int(!i)), Ok(const_int(i)) => Ok(const_int(!i)),
Ok(const_uint(i)) => Ok(const_uint(!i)), Ok(const_uint(i)) => Ok(const_uint(!i)),
Ok(const_bool(b)) => Ok(const_bool(!b)), Ok(const_bool(b)) => Ok(const_bool(!b)),
_ => Err("not on float or string".to_string()) _ => Err("not on float or string".to_string())
} }
} }
ExprBinary(op, a, b) => { ExprBinary(op, ref a, ref b) => {
match (eval_const_expr_partial(tcx, a), match (eval_const_expr_partial(tcx, &**a),
eval_const_expr_partial(tcx, b)) { eval_const_expr_partial(tcx, &**b)) {
(Ok(const_float(a)), Ok(const_float(b))) => { (Ok(const_float(a)), Ok(const_float(b))) => {
match op { match op {
BiAdd => Ok(const_float(a + b)), BiAdd => Ok(const_float(a + b)),
@ -431,19 +434,19 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
_ => Err("bad operands for binary".to_string()) _ => Err("bad operands for binary".to_string())
} }
} }
ExprCast(base, target_ty) => { ExprCast(ref base, ref target_ty) => {
// This tends to get called w/o the type actually having been // This tends to get called w/o the type actually having been
// populated in the ctxt, which was causing things to blow up // populated in the ctxt, which was causing things to blow up
// (#5900). Fall back to doing a limited lookup to get past it. // (#5900). Fall back to doing a limited lookup to get past it.
let ety = ty::expr_ty_opt(tcx.ty_ctxt(), e) let ety = ty::expr_ty_opt(tcx.ty_ctxt(), e)
.or_else(|| astconv::ast_ty_to_prim_ty(tcx.ty_ctxt(), target_ty)) .or_else(|| astconv::ast_ty_to_prim_ty(tcx.ty_ctxt(), &**target_ty))
.unwrap_or_else(|| { .unwrap_or_else(|| {
tcx.ty_ctxt().sess.span_fatal(target_ty.span, tcx.ty_ctxt().sess.span_fatal(target_ty.span,
"target type not found for \ "target type not found for \
const cast") const cast")
}); });
let base = eval_const_expr_partial(tcx, base); let base = eval_const_expr_partial(tcx, &**base);
match base { match base {
Err(_) => base, Err(_) => base,
Ok(val) => { Ok(val) => {
@ -479,14 +482,14 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
} }
ExprPath(_) => { ExprPath(_) => {
match lookup_const(tcx.ty_ctxt(), e) { match lookup_const(tcx.ty_ctxt(), e) {
Some(actual_e) => eval_const_expr_partial(tcx.ty_ctxt(), actual_e), Some(actual_e) => eval_const_expr_partial(tcx.ty_ctxt(), &*actual_e),
None => Err("non-constant path in constant expr".to_string()) None => Err("non-constant path in constant expr".to_string())
} }
} }
ExprLit(lit) => Ok(lit_to_const(lit)), ExprLit(ref lit) => Ok(lit_to_const(&**lit)),
// If we have a vstore, just keep going; it has to be a string // If we have a vstore, just keep going; it has to be a string
ExprVstore(e, _) => eval_const_expr_partial(tcx, e), ExprVstore(ref e, _) => eval_const_expr_partial(tcx, &**e),
ExprParen(e) => eval_const_expr_partial(tcx, e), ExprParen(ref e) => eval_const_expr_partial(tcx, &**e),
ExprBlock(ref block) => { ExprBlock(ref block) => {
match block.expr { match block.expr {
Some(ref expr) => eval_const_expr_partial(tcx, &**expr), Some(ref expr) => eval_const_expr_partial(tcx, &**expr),

View File

@ -21,7 +21,7 @@ use middle::def;
use middle::ty; use middle::ty;
use middle::typeck; use middle::typeck;
use std::io; use std::io;
use std::string::String; use std::gc::Gc;
use std::uint; use std::uint;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
@ -346,8 +346,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
self.merge_with_entry_set(blk.id, in_out); self.merge_with_entry_set(blk.id, in_out);
for &stmt in blk.stmts.iter() { for stmt in blk.stmts.iter() {
self.walk_stmt(stmt, in_out, loop_scopes); self.walk_stmt(stmt.clone(), in_out, loop_scopes);
} }
self.walk_opt_expr(blk.expr, in_out, loop_scopes); self.walk_opt_expr(blk.expr, in_out, loop_scopes);
@ -356,16 +356,16 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
} }
fn walk_stmt(&mut self, fn walk_stmt(&mut self,
stmt: @ast::Stmt, stmt: Gc<ast::Stmt>,
in_out: &mut [uint], in_out: &mut [uint],
loop_scopes: &mut Vec<LoopScope> ) { loop_scopes: &mut Vec<LoopScope> ) {
match stmt.node { match stmt.node {
ast::StmtDecl(decl, _) => { ast::StmtDecl(ref decl, _) => {
self.walk_decl(decl, in_out, loop_scopes); self.walk_decl(decl.clone(), in_out, loop_scopes);
} }
ast::StmtExpr(expr, _) | ast::StmtSemi(expr, _) => { ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
self.walk_expr(expr, in_out, loop_scopes); self.walk_expr(&**expr, in_out, loop_scopes);
} }
ast::StmtMac(..) => { ast::StmtMac(..) => {
@ -375,11 +375,11 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
} }
fn walk_decl(&mut self, fn walk_decl(&mut self,
decl: @ast::Decl, decl: Gc<ast::Decl>,
in_out: &mut [uint], in_out: &mut [uint],
loop_scopes: &mut Vec<LoopScope> ) { loop_scopes: &mut Vec<LoopScope> ) {
match decl.node { match decl.node {
ast::DeclLocal(local) => { ast::DeclLocal(ref local) => {
self.walk_opt_expr(local.init, in_out, loop_scopes); self.walk_opt_expr(local.init, in_out, loop_scopes);
self.walk_pat(local.pat, in_out, loop_scopes); self.walk_pat(local.pat, in_out, loop_scopes);
} }
@ -415,10 +415,10 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
// v v // v v
// ( succ ) // ( succ )
// //
self.walk_expr(cond, in_out, loop_scopes); self.walk_expr(&*cond, in_out, loop_scopes);
let mut then_bits = in_out.to_owned(); let mut then_bits = in_out.to_owned();
self.walk_block(then, then_bits, loop_scopes); self.walk_block(&*then, then_bits, loop_scopes);
self.walk_opt_expr(els, in_out, loop_scopes); self.walk_opt_expr(els, in_out, loop_scopes);
join_bits(&self.dfcx.oper, then_bits, in_out); join_bits(&self.dfcx.oper, then_bits, in_out);
@ -437,14 +437,14 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
// <--+ (break) // <--+ (break)
// //
self.walk_expr(cond, in_out, loop_scopes); self.walk_expr(&*cond, in_out, loop_scopes);
let mut body_bits = in_out.to_owned(); let mut body_bits = in_out.to_owned();
loop_scopes.push(LoopScope { loop_scopes.push(LoopScope {
loop_id: expr.id, loop_id: expr.id,
break_bits: Vec::from_slice(in_out) break_bits: Vec::from_slice(in_out)
}); });
self.walk_block(blk, body_bits, loop_scopes); self.walk_block(&*blk, body_bits, loop_scopes);
self.add_to_entry_set(expr.id, body_bits); self.add_to_entry_set(expr.id, body_bits);
let new_loop_scope = loop_scopes.pop().unwrap(); let new_loop_scope = loop_scopes.pop().unwrap();
copy_bits(new_loop_scope.break_bits.as_slice(), in_out); copy_bits(new_loop_scope.break_bits.as_slice(), in_out);
@ -452,7 +452,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
ast::ExprLoop(blk, _) => { ast::ExprLoop(ref blk, _) => {
// //
// (expr) <--+ // (expr) <--+
// | | // | |
@ -468,7 +468,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
loop_id: expr.id, loop_id: expr.id,
break_bits: Vec::from_slice(in_out) break_bits: Vec::from_slice(in_out)
}); });
self.walk_block(blk, body_bits, loop_scopes); self.walk_block(&**blk, body_bits, loop_scopes);
self.add_to_entry_set(expr.id, body_bits); self.add_to_entry_set(expr.id, body_bits);
let new_loop_scope = loop_scopes.pop().unwrap(); let new_loop_scope = loop_scopes.pop().unwrap();
@ -476,7 +476,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
copy_bits(new_loop_scope.break_bits.as_slice(), in_out); copy_bits(new_loop_scope.break_bits.as_slice(), in_out);
} }
ast::ExprMatch(discr, ref arms) => { ast::ExprMatch(ref discr, ref arms) => {
// //
// (discr) // (discr)
// / | \ // / | \
@ -488,7 +488,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
// ( succ ) // ( succ )
// //
// //
self.walk_expr(discr, in_out, loop_scopes); self.walk_expr(&**discr, in_out, loop_scopes);
let mut guards = in_out.to_owned(); let mut guards = in_out.to_owned();
@ -507,7 +507,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
self.walk_pat_alternatives(arm.pats.as_slice(), self.walk_pat_alternatives(arm.pats.as_slice(),
body, body,
loop_scopes); loop_scopes);
self.walk_expr(arm.body, body, loop_scopes); self.walk_expr(&*arm.body, body, loop_scopes);
join_bits(&self.dfcx.oper, body, in_out); join_bits(&self.dfcx.oper, body, in_out);
} }
} }
@ -530,30 +530,30 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
self.reset(in_out); self.reset(in_out);
} }
ast::ExprAssign(l, r) | ast::ExprAssign(ref l, ref r) |
ast::ExprAssignOp(_, l, r) => { ast::ExprAssignOp(_, ref l, ref r) => {
self.walk_expr(r, in_out, loop_scopes); self.walk_expr(&**r, in_out, loop_scopes);
self.walk_expr(l, in_out, loop_scopes); self.walk_expr(&**l, in_out, loop_scopes);
} }
ast::ExprVec(ref exprs) => { ast::ExprVec(ref exprs) => {
self.walk_exprs(exprs.as_slice(), in_out, loop_scopes) self.walk_exprs(exprs.as_slice(), in_out, loop_scopes)
} }
ast::ExprRepeat(l, r) => { ast::ExprRepeat(ref l, ref r) => {
self.walk_expr(l, in_out, loop_scopes); self.walk_expr(&**l, in_out, loop_scopes);
self.walk_expr(r, in_out, loop_scopes); self.walk_expr(&**r, in_out, loop_scopes);
} }
ast::ExprStruct(_, ref fields, with_expr) => { ast::ExprStruct(_, ref fields, with_expr) => {
for field in fields.iter() { for field in fields.iter() {
self.walk_expr(field.expr, in_out, loop_scopes); self.walk_expr(&*field.expr, in_out, loop_scopes);
} }
self.walk_opt_expr(with_expr, in_out, loop_scopes); self.walk_opt_expr(with_expr, in_out, loop_scopes);
} }
ast::ExprCall(f, ref args) => { ast::ExprCall(ref f, ref args) => {
self.walk_expr(f, in_out, loop_scopes); self.walk_expr(&**f, in_out, loop_scopes);
self.walk_call(expr.id, args.as_slice(), in_out, loop_scopes); self.walk_call(expr.id, args.as_slice(), in_out, loop_scopes);
} }
@ -574,10 +574,10 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
self.walk_exprs(exprs.as_slice(), in_out, loop_scopes); self.walk_exprs(exprs.as_slice(), in_out, loop_scopes);
} }
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => { ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
self.walk_expr(l, in_out, loop_scopes); self.walk_expr(&**l, in_out, loop_scopes);
let temp = in_out.to_owned(); let temp = in_out.to_owned();
self.walk_expr(r, in_out, loop_scopes); self.walk_expr(&**r, in_out, loop_scopes);
join_bits(&self.dfcx.oper, temp, in_out); join_bits(&self.dfcx.oper, temp, in_out);
} }
@ -589,31 +589,31 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
ast::ExprLit(..) | ast::ExprLit(..) |
ast::ExprPath(..) => {} ast::ExprPath(..) => {}
ast::ExprAddrOf(_, e) | ast::ExprAddrOf(_, ref e) |
ast::ExprCast(e, _) | ast::ExprCast(ref e, _) |
ast::ExprUnary(_, e) | ast::ExprUnary(_, ref e) |
ast::ExprParen(e) | ast::ExprParen(ref e) |
ast::ExprVstore(e, _) | ast::ExprVstore(ref e, _) |
ast::ExprField(e, _, _) => { ast::ExprField(ref e, _, _) => {
self.walk_expr(e, in_out, loop_scopes); self.walk_expr(&**e, in_out, loop_scopes);
} }
ast::ExprBox(s, e) => { ast::ExprBox(ref s, ref e) => {
self.walk_expr(s, in_out, loop_scopes); self.walk_expr(&**s, in_out, loop_scopes);
self.walk_expr(e, in_out, loop_scopes); self.walk_expr(&**e, in_out, loop_scopes);
} }
ast::ExprInlineAsm(ref inline_asm) => { ast::ExprInlineAsm(ref inline_asm) => {
for &(_, expr) in inline_asm.inputs.iter() { for &(_, ref expr) in inline_asm.inputs.iter() {
self.walk_expr(expr, in_out, loop_scopes); self.walk_expr(&**expr, in_out, loop_scopes);
} }
for &(_, expr) in inline_asm.outputs.iter() { for &(_, ref expr) in inline_asm.outputs.iter() {
self.walk_expr(expr, in_out, loop_scopes); self.walk_expr(&**expr, in_out, loop_scopes);
} }
} }
ast::ExprBlock(blk) => { ast::ExprBlock(ref blk) => {
self.walk_block(blk, in_out, loop_scopes); self.walk_block(&**blk, in_out, loop_scopes);
} }
ast::ExprMac(..) => { ast::ExprMac(..) => {
@ -674,26 +674,26 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
} }
fn walk_exprs(&mut self, fn walk_exprs(&mut self,
exprs: &[@ast::Expr], exprs: &[Gc<ast::Expr>],
in_out: &mut [uint], in_out: &mut [uint],
loop_scopes: &mut Vec<LoopScope> ) { loop_scopes: &mut Vec<LoopScope> ) {
for &expr in exprs.iter() { for expr in exprs.iter() {
self.walk_expr(expr, in_out, loop_scopes); self.walk_expr(&**expr, in_out, loop_scopes);
} }
} }
fn walk_opt_expr(&mut self, fn walk_opt_expr(&mut self,
opt_expr: Option<@ast::Expr>, opt_expr: Option<Gc<ast::Expr>>,
in_out: &mut [uint], in_out: &mut [uint],
loop_scopes: &mut Vec<LoopScope> ) { loop_scopes: &mut Vec<LoopScope> ) {
for &expr in opt_expr.iter() { for expr in opt_expr.iter() {
self.walk_expr(expr, in_out, loop_scopes); self.walk_expr(&**expr, in_out, loop_scopes);
} }
} }
fn walk_call(&mut self, fn walk_call(&mut self,
call_id: ast::NodeId, call_id: ast::NodeId,
args: &[@ast::Expr], args: &[Gc<ast::Expr>],
in_out: &mut [uint], in_out: &mut [uint],
loop_scopes: &mut Vec<LoopScope> ) { loop_scopes: &mut Vec<LoopScope> ) {
self.walk_exprs(args, in_out, loop_scopes); self.walk_exprs(args, in_out, loop_scopes);
@ -710,13 +710,13 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
} }
fn walk_pat(&mut self, fn walk_pat(&mut self,
pat: @ast::Pat, pat: Gc<ast::Pat>,
in_out: &mut [uint], in_out: &mut [uint],
_loop_scopes: &mut Vec<LoopScope> ) { _loop_scopes: &mut Vec<LoopScope> ) {
debug!("DataFlowContext::walk_pat(pat={}, in_out={})", debug!("DataFlowContext::walk_pat(pat={}, in_out={})",
pat.repr(self.dfcx.tcx), bits_to_str(in_out)); pat.repr(self.dfcx.tcx), bits_to_str(in_out));
ast_util::walk_pat(pat, |p| { ast_util::walk_pat(&*pat, |p| {
debug!(" p.id={} in_out={}", p.id, bits_to_str(in_out)); debug!(" p.id={} in_out={}", p.id, bits_to_str(in_out));
self.merge_with_entry_set(p.id, in_out); self.merge_with_entry_set(p.id, in_out);
self.dfcx.apply_gen_kill(p.id, in_out); self.dfcx.apply_gen_kill(p.id, in_out);
@ -725,7 +725,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
} }
fn walk_pat_alternatives(&mut self, fn walk_pat_alternatives(&mut self,
pats: &[@ast::Pat], pats: &[Gc<ast::Pat>],
in_out: &mut [uint], in_out: &mut [uint],
loop_scopes: &mut Vec<LoopScope> ) { loop_scopes: &mut Vec<LoopScope> ) {
if pats.len() == 1 { if pats.len() == 1 {

View File

@ -184,25 +184,25 @@ impl<'a> MarkSymbolVisitor<'a> {
} }
}); });
self.live_symbols.extend(live_fields.map(|f| f.node.id)); self.live_symbols.extend(live_fields.map(|f| f.node.id));
visit::walk_item(self, item, ()); visit::walk_item(self, &*item, ());
} }
ast::ItemFn(..) ast::ItemFn(..)
| ast::ItemTy(..) | ast::ItemTy(..)
| ast::ItemEnum(..) | ast::ItemEnum(..)
| ast::ItemStatic(..) => { | ast::ItemStatic(..) => {
visit::walk_item(self, item, ()); visit::walk_item(self, &*item, ());
} }
_ => () _ => ()
} }
} }
ast_map::NodeTraitMethod(trait_method) => { ast_map::NodeTraitMethod(trait_method) => {
visit::walk_trait_method(self, trait_method, ()); visit::walk_trait_method(self, &*trait_method, ());
} }
ast_map::NodeMethod(method) => { ast_map::NodeMethod(method) => {
visit::walk_block(self, method.body, ()); visit::walk_block(self, &*method.body, ());
} }
ast_map::NodeForeignItem(foreign_item) => { ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, foreign_item, ()); visit::walk_foreign_item(self, &*foreign_item, ());
} }
_ => () _ => ()
} }
@ -217,7 +217,7 @@ impl<'a> Visitor<()> for MarkSymbolVisitor<'a> {
self.lookup_and_handle_method(expr.id, expr.span); self.lookup_and_handle_method(expr.id, expr.span);
} }
ast::ExprField(ref lhs, ref ident, _) => { ast::ExprField(ref lhs, ref ident, _) => {
self.handle_field_access(*lhs, ident); self.handle_field_access(&**lhs, ident);
} }
_ => () _ => ()
} }
@ -479,7 +479,7 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
// Overwrite so that we don't warn the trait method itself. // Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) { fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method { match *trait_method {
ast::Provided(method) => visit::walk_block(self, method.body, ()), ast::Provided(ref method) => visit::walk_block(self, &*method.body, ()),
ast::Required(_) => () ast::Required(_) => ()
} }
} }

View File

@ -11,6 +11,8 @@
use syntax::ast; use syntax::ast;
use syntax::ast_util::local_def; use syntax::ast_util::local_def;
use std::gc::Gc;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Def { pub enum Def {
DefFn(ast::DefId, ast::FnStyle), DefFn(ast::DefId, ast::FnStyle),
@ -29,7 +31,7 @@ pub enum Def {
DefBinding(ast::NodeId, ast::BindingMode), DefBinding(ast::NodeId, ast::BindingMode),
DefUse(ast::DefId), DefUse(ast::DefId),
DefUpvar(ast::NodeId, // id of closed over var DefUpvar(ast::NodeId, // id of closed over var
@Def, // closed over def Gc<Def>, // closed over def
ast::NodeId, // expr node that creates the closure ast::NodeId, // expr node that creates the closure
ast::NodeId), // id for the block/body of the closure expr ast::NodeId), // id for the block/body of the closure expr

View File

@ -62,7 +62,7 @@ impl<'a> EffectCheckVisitor<'a> {
} }
} }
fn check_str_index(&mut self, e: @ast::Expr) { fn check_str_index(&mut self, e: &ast::Expr) {
let base_type = match e.node { let base_type = match e.node {
ast::ExprIndex(base, _) => ty::node_id_to_type(self.tcx, base.id), ast::ExprIndex(base, _) => ty::node_id_to_type(self.tcx, base.id),
_ => return _ => return
@ -173,11 +173,11 @@ impl<'a> Visitor<()> for EffectCheckVisitor<'a> {
_ => {} _ => {}
} }
} }
ast::ExprAssign(base, _) | ast::ExprAssignOp(_, base, _) => { ast::ExprAssign(ref base, _) | ast::ExprAssignOp(_, ref base, _) => {
self.check_str_index(base); self.check_str_index(&**base);
} }
ast::ExprAddrOf(ast::MutMutable, base) => { ast::ExprAddrOf(ast::MutMutable, ref base) => {
self.check_str_index(base); self.check_str_index(&**base);
} }
ast::ExprInlineAsm(..) => { ast::ExprInlineAsm(..) => {
self.require_unsafe(expr.span, "use of inline assembly") self.require_unsafe(expr.span, "use of inline assembly")

View File

@ -25,6 +25,8 @@ use syntax::ast;
use syntax::codemap::{Span}; use syntax::codemap::{Span};
use util::ppaux::Repr; use util::ppaux::Repr;
use std::gc::Gc;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// The Delegate trait // The Delegate trait
@ -157,7 +159,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
ty::ReScope(body.id), // Args live only as long as the fn body. ty::ReScope(body.id), // Args live only as long as the fn body.
arg_ty); arg_ty);
self.walk_pat(arg_cmt, arg.pat); self.walk_pat(arg_cmt, arg.pat.clone());
} }
} }
@ -173,9 +175,9 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
self.delegate.consume(consume_id, consume_span, cmt, mode); self.delegate.consume(consume_id, consume_span, cmt, mode);
} }
fn consume_exprs(&mut self, exprs: &Vec<@ast::Expr>) { fn consume_exprs(&mut self, exprs: &Vec<Gc<ast::Expr>>) {
for &expr in exprs.iter() { for expr in exprs.iter() {
self.consume_expr(expr); self.consume_expr(&**expr);
} }
} }
@ -186,7 +188,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
self.delegate_consume(expr.id, expr.span, cmt); self.delegate_consume(expr.id, expr.span, cmt);
match expr.node { match expr.node {
ast::ExprParen(subexpr) => { ast::ExprParen(ref subexpr) => {
// Argh but is ExprParen horrible. So, if we consume // Argh but is ExprParen horrible. So, if we consume
// `(x)`, that generally is also consuming `x`, UNLESS // `(x)`, that generally is also consuming `x`, UNLESS
// there are adjustments on the `(x)` expression // there are adjustments on the `(x)` expression
@ -194,7 +196,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
if self.typer.adjustments().borrow().contains_key(&expr.id) { if self.typer.adjustments().borrow().contains_key(&expr.id) {
self.walk_expr(expr); self.walk_expr(expr);
} else { } else {
self.consume_expr(subexpr); self.consume_expr(&**subexpr);
} }
} }
@ -240,31 +242,31 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
self.walk_adjustment(expr); self.walk_adjustment(expr);
match expr.node { match expr.node {
ast::ExprParen(subexpr) => { ast::ExprParen(ref subexpr) => {
self.walk_expr(subexpr) self.walk_expr(&**subexpr)
} }
ast::ExprPath(..) => { } ast::ExprPath(..) => { }
ast::ExprUnary(ast::UnDeref, base) => { // *base ast::ExprUnary(ast::UnDeref, ref base) => { // *base
if !self.walk_overloaded_operator(expr, base, []) { if !self.walk_overloaded_operator(expr, &**base, []) {
self.select_from_expr(base); self.select_from_expr(&**base);
} }
} }
ast::ExprField(base, _, _) => { // base.f ast::ExprField(ref base, _, _) => { // base.f
self.select_from_expr(base); self.select_from_expr(&**base);
} }
ast::ExprIndex(lhs, rhs) => { // lhs[rhs] ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
if !self.walk_overloaded_operator(expr, lhs, [rhs]) { if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
self.select_from_expr(lhs); self.select_from_expr(&**lhs);
self.consume_expr(rhs); self.consume_expr(&**rhs);
} }
} }
ast::ExprCall(callee, ref args) => { // callee(args) ast::ExprCall(ref callee, ref args) => { // callee(args)
self.walk_callee(expr, callee); self.walk_callee(expr, &**callee);
self.consume_exprs(args); self.consume_exprs(args);
} }
@ -272,27 +274,27 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
self.consume_exprs(args); self.consume_exprs(args);
} }
ast::ExprStruct(_, ref fields, opt_with) => { ast::ExprStruct(_, ref fields, ref opt_with) => {
self.walk_struct_expr(expr, fields, opt_with); self.walk_struct_expr(expr, fields, opt_with.clone());
} }
ast::ExprTup(ref exprs) => { ast::ExprTup(ref exprs) => {
self.consume_exprs(exprs); self.consume_exprs(exprs);
} }
ast::ExprIf(cond_expr, then_blk, opt_else_expr) => { ast::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
self.consume_expr(cond_expr); self.consume_expr(&**cond_expr);
self.walk_block(then_blk); self.walk_block(&**then_blk);
for else_expr in opt_else_expr.iter() { for else_expr in opt_else_expr.iter() {
self.consume_expr(*else_expr); self.consume_expr(&**else_expr);
} }
} }
ast::ExprMatch(discr, ref arms) => { ast::ExprMatch(ref discr, ref arms) => {
// treatment of the discriminant is handled while // treatment of the discriminant is handled while
// walking the arms: // walking the arms:
self.walk_expr(discr); self.walk_expr(&**discr);
let discr_cmt = return_if_err!(self.mc.cat_expr(discr)); let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
for arm in arms.iter() { for arm in arms.iter() {
self.walk_arm(discr_cmt.clone(), arm); self.walk_arm(discr_cmt.clone(), arm);
} }
@ -302,26 +304,26 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
self.consume_exprs(exprs); self.consume_exprs(exprs);
} }
ast::ExprAddrOf(m, base) => { // &base ast::ExprAddrOf(m, ref base) => { // &base
// make sure that the thing we are pointing out stays valid // make sure that the thing we are pointing out stays valid
// for the lifetime `scope_r` of the resulting ptr: // for the lifetime `scope_r` of the resulting ptr:
let expr_ty = ty::expr_ty(self.tcx(), expr); let expr_ty = ty::expr_ty(self.tcx(), expr);
if !ty::type_is_bot(expr_ty) { if !ty::type_is_bot(expr_ty) {
let r = ty::ty_region(self.tcx(), expr.span, expr_ty); let r = ty::ty_region(self.tcx(), expr.span, expr_ty);
let bk = ty::BorrowKind::from_mutbl(m); let bk = ty::BorrowKind::from_mutbl(m);
self.borrow_expr(base, r, bk, AddrOf); self.borrow_expr(&**base, r, bk, AddrOf);
} else { } else {
self.walk_expr(base); self.walk_expr(&**base);
} }
} }
ast::ExprInlineAsm(ref ia) => { ast::ExprInlineAsm(ref ia) => {
for &(_, input) in ia.inputs.iter() { for &(_, ref input) in ia.inputs.iter() {
self.consume_expr(input); self.consume_expr(&**input);
} }
for &(_, output) in ia.outputs.iter() { for &(_, ref output) in ia.outputs.iter() {
self.mutate_expr(expr, output, JustWrite); self.mutate_expr(expr, &**output, JustWrite);
} }
} }
@ -329,59 +331,59 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
ast::ExprAgain(..) | ast::ExprAgain(..) |
ast::ExprLit(..) => {} ast::ExprLit(..) => {}
ast::ExprLoop(blk, _) => { ast::ExprLoop(ref blk, _) => {
self.walk_block(blk); self.walk_block(&**blk);
} }
ast::ExprWhile(cond_expr, blk) => { ast::ExprWhile(ref cond_expr, ref blk) => {
self.consume_expr(cond_expr); self.consume_expr(&**cond_expr);
self.walk_block(blk); self.walk_block(&**blk);
} }
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
ast::ExprUnary(_, lhs) => { ast::ExprUnary(_, ref lhs) => {
if !self.walk_overloaded_operator(expr, lhs, []) { if !self.walk_overloaded_operator(expr, &**lhs, []) {
self.consume_expr(lhs); self.consume_expr(&**lhs);
} }
} }
ast::ExprBinary(_, lhs, rhs) => { ast::ExprBinary(_, ref lhs, ref rhs) => {
if !self.walk_overloaded_operator(expr, lhs, [rhs]) { if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
self.consume_expr(lhs); self.consume_expr(&**lhs);
self.consume_expr(rhs); self.consume_expr(&**rhs);
} }
} }
ast::ExprBlock(blk) => { ast::ExprBlock(ref blk) => {
self.walk_block(blk); self.walk_block(&**blk);
} }
ast::ExprRet(ref opt_expr) => { ast::ExprRet(ref opt_expr) => {
for expr in opt_expr.iter() { for expr in opt_expr.iter() {
self.consume_expr(*expr); self.consume_expr(&**expr);
} }
} }
ast::ExprAssign(lhs, rhs) => { ast::ExprAssign(ref lhs, ref rhs) => {
self.mutate_expr(expr, lhs, JustWrite); self.mutate_expr(expr, &**lhs, JustWrite);
self.consume_expr(rhs); self.consume_expr(&**rhs);
} }
ast::ExprCast(base, _) => { ast::ExprCast(ref base, _) => {
self.consume_expr(base); self.consume_expr(&**base);
} }
ast::ExprAssignOp(_, lhs, rhs) => { ast::ExprAssignOp(_, ref lhs, ref rhs) => {
// This will have to change if/when we support // This will have to change if/when we support
// overloaded operators for `+=` and so forth. // overloaded operators for `+=` and so forth.
self.mutate_expr(expr, lhs, WriteAndRead); self.mutate_expr(expr, &**lhs, WriteAndRead);
self.consume_expr(rhs); self.consume_expr(&**rhs);
} }
ast::ExprRepeat(base, count) => { ast::ExprRepeat(ref base, ref count) => {
self.consume_expr(base); self.consume_expr(&**base);
self.consume_expr(count); self.consume_expr(&**count);
} }
ast::ExprFnBlock(..) | ast::ExprFnBlock(..) |
@ -389,13 +391,13 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
self.walk_captures(expr) self.walk_captures(expr)
} }
ast::ExprVstore(base, _) => { ast::ExprVstore(ref base, _) => {
self.consume_expr(base); self.consume_expr(&**base);
} }
ast::ExprBox(place, base) => { ast::ExprBox(ref place, ref base) => {
self.consume_expr(place); self.consume_expr(&**place);
self.consume_expr(base); self.consume_expr(&**base);
} }
ast::ExprMac(..) => { ast::ExprMac(..) => {
@ -448,10 +450,10 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
fn walk_stmt(&mut self, stmt: &ast::Stmt) { fn walk_stmt(&mut self, stmt: &ast::Stmt) {
match stmt.node { match stmt.node {
ast::StmtDecl(decl, _) => { ast::StmtDecl(ref decl, _) => {
match decl.node { match decl.node {
ast::DeclLocal(local) => { ast::DeclLocal(ref local) => {
self.walk_local(local); self.walk_local(local.clone());
} }
ast::DeclItem(_) => { ast::DeclItem(_) => {
@ -461,9 +463,9 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
} }
} }
ast::StmtExpr(expr, _) | ast::StmtExpr(ref expr, _) |
ast::StmtSemi(expr, _) => { ast::StmtSemi(ref expr, _) => {
self.consume_expr(expr); self.consume_expr(&**expr);
} }
ast::StmtMac(..) => { ast::StmtMac(..) => {
@ -472,22 +474,23 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
} }
} }
fn walk_local(&mut self, local: @ast::Local) { fn walk_local(&mut self, local: Gc<ast::Local>) {
match local.init { match local.init {
None => { None => {
let delegate = &mut self.delegate; let delegate = &mut self.delegate;
pat_util::pat_bindings(&self.typer.tcx().def_map, local.pat, |_, id, span, _| { pat_util::pat_bindings(&self.typer.tcx().def_map, &*local.pat,
|_, id, span, _| {
delegate.decl_without_init(id, span); delegate.decl_without_init(id, span);
}) })
} }
Some(expr) => { Some(ref expr) => {
// Variable declarations with // Variable declarations with
// initializers are considered // initializers are considered
// "assigns", which is handled by // "assigns", which is handled by
// `walk_pat`: // `walk_pat`:
self.walk_expr(expr); self.walk_expr(&**expr);
let init_cmt = return_if_err!(self.mc.cat_expr(expr)); let init_cmt = return_if_err!(self.mc.cat_expr(&**expr));
self.walk_pat(init_cmt, local.pat); self.walk_pat(init_cmt, local.pat);
} }
} }
@ -502,29 +505,29 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
debug!("walk_block(blk.id={:?})", blk.id); debug!("walk_block(blk.id={:?})", blk.id);
for stmt in blk.stmts.iter() { for stmt in blk.stmts.iter() {
self.walk_stmt(*stmt); self.walk_stmt(&**stmt);
} }
for tail_expr in blk.expr.iter() { for tail_expr in blk.expr.iter() {
self.consume_expr(*tail_expr); self.consume_expr(&**tail_expr);
} }
} }
fn walk_struct_expr(&mut self, fn walk_struct_expr(&mut self,
_expr: &ast::Expr, _expr: &ast::Expr,
fields: &Vec<ast::Field>, fields: &Vec<ast::Field>,
opt_with: Option<@ast::Expr>) { opt_with: Option<Gc<ast::Expr>>) {
// Consume the expressions supplying values for each field. // Consume the expressions supplying values for each field.
for field in fields.iter() { for field in fields.iter() {
self.consume_expr(field.expr); self.consume_expr(&*field.expr);
} }
let with_expr = match opt_with { let with_expr = match opt_with {
Some(w) => { w } Some(ref w) => { w.clone() }
None => { return; } None => { return; }
}; };
let with_cmt = return_if_err!(self.mc.cat_expr(with_expr)); let with_cmt = return_if_err!(self.mc.cat_expr(&*with_expr));
// Select just those fields of the `with` // Select just those fields of the `with`
// expression that will actually be used // expression that will actually be used
@ -542,7 +545,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
// Consume those fields of the with expression that are needed. // Consume those fields of the with expression that are needed.
for with_field in with_fields.iter() { for with_field in with_fields.iter() {
if !contains_field_named(with_field, fields) { if !contains_field_named(with_field, fields) {
let cmt_field = self.mc.cat_field(with_expr, let cmt_field = self.mc.cat_field(&*with_expr,
with_cmt.clone(), with_cmt.clone(),
with_field.ident, with_field.ident,
with_field.mt.ty); with_field.mt.ty);
@ -673,7 +676,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
fn walk_overloaded_operator(&mut self, fn walk_overloaded_operator(&mut self,
expr: &ast::Expr, expr: &ast::Expr,
receiver: &ast::Expr, receiver: &ast::Expr,
args: &[@ast::Expr]) args: &[Gc<ast::Expr>])
-> bool -> bool
{ {
if !self.typer.is_method_call(expr.id) { if !self.typer.is_method_call(expr.id) {
@ -689,8 +692,8 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
let r = ty::ReScope(expr.id); let r = ty::ReScope(expr.id);
let bk = ty::ImmBorrow; let bk = ty::ImmBorrow;
for &arg in args.iter() { for arg in args.iter() {
self.borrow_expr(arg, r, bk, OverloadedOperator); self.borrow_expr(&**arg, r, bk, OverloadedOperator);
} }
return true; return true;
} }
@ -701,13 +704,13 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
} }
for guard in arm.guard.iter() { for guard in arm.guard.iter() {
self.consume_expr(*guard); self.consume_expr(&**guard);
} }
self.consume_expr(arm.body); self.consume_expr(&*arm.body);
} }
fn walk_pat(&mut self, cmt_discr: mc::cmt, pat: @ast::Pat) { fn walk_pat(&mut self, cmt_discr: mc::cmt, pat: Gc<ast::Pat>) {
debug!("walk_pat cmt_discr={} pat={}", cmt_discr.repr(self.tcx()), debug!("walk_pat cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
pat.repr(self.tcx())); pat.repr(self.tcx()));
let mc = &self.mc; let mc = &self.mc;
@ -715,7 +718,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
let tcx = typer.tcx(); let tcx = typer.tcx();
let def_map = &self.typer.tcx().def_map; let def_map = &self.typer.tcx().def_map;
let delegate = &mut self.delegate; let delegate = &mut self.delegate;
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| { return_if_err!(mc.cat_pattern(cmt_discr, &*pat, |mc, cmt_pat, pat| {
if pat_util::pat_is_binding(def_map, pat) { if pat_util::pat_is_binding(def_map, pat) {
let tcx = typer.tcx(); let tcx = typer.tcx();
@ -765,7 +768,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
// matched. // matched.
let (slice_cmt, slice_mutbl, slice_r) = { let (slice_cmt, slice_mutbl, slice_r) = {
match mc.cat_slice_pattern(cmt_pat, slice_pat) { match mc.cat_slice_pattern(cmt_pat, &*slice_pat) {
Ok(v) => v, Ok(v) => v,
Err(()) => { Err(()) => {
tcx.sess.span_bug(slice_pat.span, tcx.sess.span_bug(slice_pat.span,

View File

@ -155,8 +155,8 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t
fn check_item(cx: &mut Context, item: &Item) { fn check_item(cx: &mut Context, item: &Item) {
if !attr::contains_name(item.attrs.as_slice(), "unsafe_destructor") { if !attr::contains_name(item.attrs.as_slice(), "unsafe_destructor") {
match item.node { match item.node {
ItemImpl(_, Some(ref trait_ref), self_type, _) => { ItemImpl(_, Some(ref trait_ref), ref self_type, _) => {
check_impl_of_trait(cx, item, trait_ref, self_type); check_impl_of_trait(cx, item, trait_ref, &**self_type);
} }
_ => {} _ => {}
} }
@ -292,19 +292,19 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
} }
match e.node { match e.node {
ExprUnary(UnBox, interior) => { ExprUnary(UnBox, ref interior) => {
let interior_type = ty::expr_ty(cx.tcx, interior); let interior_type = ty::expr_ty(cx.tcx, &**interior);
let _ = check_static(cx.tcx, interior_type, interior.span); let _ = check_static(cx.tcx, interior_type, interior.span);
} }
ExprCast(source, _) => { ExprCast(ref source, _) => {
let source_ty = ty::expr_ty(cx.tcx, source); let source_ty = ty::expr_ty(cx.tcx, &**source);
let target_ty = ty::expr_ty(cx.tcx, e); let target_ty = ty::expr_ty(cx.tcx, e);
check_trait_cast(cx, source_ty, target_ty, source.span); check_trait_cast(cx, source_ty, target_ty, source.span);
} }
ExprRepeat(element, count_expr) => { ExprRepeat(ref element, ref count_expr) => {
let count = ty::eval_repeat_count(cx.tcx, count_expr); let count = ty::eval_repeat_count(cx.tcx, &**count_expr);
if count > 1 { if count > 1 {
let element_ty = ty::expr_ty(cx.tcx, element); let element_ty = ty::expr_ty(cx.tcx, &**element);
check_copy(cx, element_ty, element.span, check_copy(cx, element_ty, element.span,
"repeated element will be copied"); "repeated element will be copied");
} }

View File

@ -57,6 +57,7 @@ use std::i32;
use std::i64; use std::i64;
use std::i8; use std::i8;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
use std::to_str::ToStr; use std::to_str::ToStr;
use std::u16; use std::u16;
use std::u32; use std::u32;
@ -652,7 +653,7 @@ impl<'a> Context<'a> {
/// Return true if that's the case. Otherwise return false. /// Return true if that's the case. Otherwise return false.
pub fn each_lint(sess: &session::Session, pub fn each_lint(sess: &session::Session,
attrs: &[ast::Attribute], attrs: &[ast::Attribute],
f: |@ast::MetaItem, Level, InternedString| -> bool) f: |Gc<ast::MetaItem>, Level, InternedString| -> bool)
-> bool { -> bool {
let xs = [Allow, Warn, Deny, Forbid]; let xs = [Allow, Warn, Deny, Forbid];
for &level in xs.iter() { for &level in xs.iter() {
@ -745,8 +746,8 @@ impl<'a> AstConv for Context<'a>{
fn check_unused_casts(cx: &Context, e: &ast::Expr) { fn check_unused_casts(cx: &Context, e: &ast::Expr) {
return match e.node { return match e.node {
ast::ExprCast(expr, ty) => { ast::ExprCast(expr, ty) => {
let t_t = ast_ty_to_ty(cx, &infer::new_infer_ctxt(cx.tcx), ty); let t_t = ast_ty_to_ty(cx, &infer::new_infer_ctxt(cx.tcx), &*ty);
if ty::get(ty::expr_ty(cx.tcx, expr)).sty == ty::get(t_t).sty { if ty::get(ty::expr_ty(cx.tcx, &*expr)).sty == ty::get(t_t).sty {
cx.span_lint(UnnecessaryTypecast, ty.span, cx.span_lint(UnnecessaryTypecast, ty.span,
"unnecessary type cast"); "unnecessary type cast");
} }
@ -769,7 +770,7 @@ fn check_type_limits(cx: &Context, e: &ast::Expr) {
} }
}, },
_ => { _ => {
let t = ty::expr_ty(cx.tcx, ex); let t = ty::expr_ty(cx.tcx, &*ex);
match ty::get(t).sty { match ty::get(t).sty {
ty::ty_uint(_) => { ty::ty_uint(_) => {
cx.span_lint(UnsignedNegate, e.span, cx.span_lint(UnsignedNegate, e.span,
@ -781,7 +782,7 @@ fn check_type_limits(cx: &Context, e: &ast::Expr) {
} }
}, },
ast::ExprBinary(binop, l, r) => { ast::ExprBinary(binop, l, r) => {
if is_comparison(binop) && !check_limits(cx.tcx, binop, l, r) { if is_comparison(binop) && !check_limits(cx.tcx, binop, &*l, &*r) {
cx.span_lint(TypeLimits, e.span, cx.span_lint(TypeLimits, e.span,
"comparison is useless due to type limits"); "comparison is useless due to type limits");
} }
@ -950,24 +951,24 @@ fn check_item_ctypes(cx: &Context, it: &ast::Item) {
_ => () _ => ()
} }
} }
ast::TyPtr(ref mt) => { check_ty(cx, mt.ty) } ast::TyPtr(ref mt) => { check_ty(cx, &*mt.ty) }
_ => {} _ => {}
} }
} }
fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) { fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
for input in decl.inputs.iter() { for input in decl.inputs.iter() {
check_ty(cx, input.ty); check_ty(cx, &*input.ty);
} }
check_ty(cx, decl.output) check_ty(cx, &*decl.output)
} }
match it.node { match it.node {
ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => { ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
for ni in nmod.items.iter() { for ni in nmod.items.iter() {
match ni.node { match ni.node {
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, decl), ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, &*decl),
ast::ForeignItemStatic(t, _) => check_ty(cx, t) ast::ForeignItemStatic(t, _) => check_ty(cx, &*t)
} }
} }
} }
@ -1082,7 +1083,7 @@ fn check_raw_ptr_deriving(cx: &mut Context, item: &ast::Item) {
match item.node { match item.node {
ast::ItemStruct(..) | ast::ItemEnum(..) => { ast::ItemStruct(..) | ast::ItemEnum(..) => {
let mut visitor = RawPtrDerivingVisitor { cx: cx }; let mut visitor = RawPtrDerivingVisitor { cx: cx };
visit::walk_item(&mut visitor, item, ()); visit::walk_item(&mut visitor, &*item, ());
} }
_ => {} _ => {}
} }
@ -1184,7 +1185,7 @@ fn check_unused_result(cx: &Context, s: &ast::Stmt) {
ast::StmtSemi(expr, _) => expr, ast::StmtSemi(expr, _) => expr,
_ => return _ => return
}; };
let t = ty::expr_ty(cx.tcx, expr); let t = ty::expr_ty(cx.tcx, &*expr);
match ty::get(t).sty { match ty::get(t).sty {
ty::ty_nil | ty::ty_bot | ty::ty_bool => return, ty::ty_nil | ty::ty_bot | ty::ty_bool => return,
_ => {} _ => {}
@ -1194,7 +1195,7 @@ fn check_unused_result(cx: &Context, s: &ast::Stmt) {
_ => {} _ => {}
} }
let t = ty::expr_ty(cx.tcx, expr); let t = ty::expr_ty(cx.tcx, &*expr);
let mut warned = false; let mut warned = false;
match ty::get(t).sty { match ty::get(t).sty {
ty::ty_struct(did, _) | ty::ty_struct(did, _) |
@ -1431,7 +1432,7 @@ fn check_unnecessary_parens_expr(cx: &Context, e: &ast::Expr) {
ast::ExprAssignOp(_, _, value) => (value, "assigned value"), ast::ExprAssignOp(_, _, value) => (value, "assigned value"),
_ => return _ => return
}; };
check_unnecessary_parens_core(cx, value, msg); check_unnecessary_parens_core(cx, &*value, msg);
} }
fn check_unnecessary_parens_stmt(cx: &Context, s: &ast::Stmt) { fn check_unnecessary_parens_stmt(cx: &Context, s: &ast::Stmt) {
@ -1445,7 +1446,7 @@ fn check_unnecessary_parens_stmt(cx: &Context, s: &ast::Stmt) {
}, },
_ => return _ => return
}; };
check_unnecessary_parens_core(cx, value, msg); check_unnecessary_parens_core(cx, &*value, msg);
} }
fn check_unused_unsafe(cx: &Context, e: &ast::Expr) { fn check_unused_unsafe(cx: &Context, e: &ast::Expr) {
@ -1472,12 +1473,12 @@ fn check_unsafe_block(cx: &Context, e: &ast::Expr) {
} }
} }
fn check_unused_mut_pat(cx: &Context, pats: &[@ast::Pat]) { fn check_unused_mut_pat(cx: &Context, pats: &[Gc<ast::Pat>]) {
// collect all mutable pattern and group their NodeIDs by their Identifier to // collect all mutable pattern and group their NodeIDs by their Identifier to
// avoid false warnings in match arms with multiple patterns // avoid false warnings in match arms with multiple patterns
let mut mutables = HashMap::new(); let mut mutables = HashMap::new();
for &p in pats.iter() { for &p in pats.iter() {
pat_util::pat_bindings(&cx.tcx.def_map, p, |mode, id, _, path| { pat_util::pat_bindings(&cx.tcx.def_map, &*p, |mode, id, _, path| {
match mode { match mode {
ast::BindByValue(ast::MutMutable) => { ast::BindByValue(ast::MutMutable) => {
if path.segments.len() != 1 { if path.segments.len() != 1 {

View File

@ -110,9 +110,10 @@ use middle::pat_util;
use middle::ty; use middle::ty;
use util::nodemap::NodeMap; use util::nodemap::NodeMap;
use std::mem::transmute;
use std::fmt; use std::fmt;
use std::gc::Gc;
use std::io; use std::io;
use std::mem::transmute;
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
use std::uint; use std::uint;
@ -364,7 +365,7 @@ fn visit_fn(ir: &mut IrMaps,
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
pat_util::pat_bindings(&ir.tcx.def_map, pat_util::pat_bindings(&ir.tcx.def_map,
arg.pat, &*arg.pat,
|_bm, arg_id, _x, path| { |_bm, arg_id, _x, path| {
debug!("adding argument {}", arg_id); debug!("adding argument {}", arg_id);
let ident = ast_util::path_to_ident(path); let ident = ast_util::path_to_ident(path);
@ -397,7 +398,7 @@ fn visit_fn(ir: &mut IrMaps,
} }
fn visit_local(ir: &mut IrMaps, local: &Local) { fn visit_local(ir: &mut IrMaps, local: &Local) {
pat_util::pat_bindings(&ir.tcx.def_map, local.pat, |_, p_id, sp, path| { pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path| {
debug!("adding local variable {}", p_id); debug!("adding local variable {}", p_id);
let name = ast_util::path_to_ident(path); let name = ast_util::path_to_ident(path);
ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_live_node_for_node(p_id, VarDefNode(sp));
@ -411,7 +412,7 @@ fn visit_local(ir: &mut IrMaps, local: &Local) {
fn visit_arm(ir: &mut IrMaps, arm: &Arm) { fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
for pat in arm.pats.iter() { for pat in arm.pats.iter() {
pat_util::pat_bindings(&ir.tcx.def_map, *pat, |bm, p_id, sp, path| { pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path| {
debug!("adding local variable {} from match with bm {:?}", debug!("adding local variable {} from match with bm {:?}",
p_id, bm); p_id, bm);
let name = ast_util::path_to_ident(path); let name = ast_util::path_to_ident(path);
@ -588,22 +589,22 @@ impl<'a> Liveness<'a> {
} }
fn arm_pats_bindings(&mut self, fn arm_pats_bindings(&mut self,
pats: &[@Pat], pats: &[Gc<Pat>],
f: |&mut Liveness<'a>, LiveNode, Variable, Span, NodeId|) { f: |&mut Liveness<'a>, LiveNode, Variable, Span, NodeId|) {
// only consider the first pattern; any later patterns must have // only consider the first pattern; any later patterns must have
// the same bindings, and we also consider the first pattern to be // the same bindings, and we also consider the first pattern to be
// the "authoritative" set of ids // the "authoritative" set of ids
if !pats.is_empty() { if !pats.is_empty() {
self.pat_bindings(pats[0], f) self.pat_bindings(&*pats[0], f)
} }
} }
fn define_bindings_in_pat(&mut self, pat: @Pat, succ: LiveNode) fn define_bindings_in_pat(&mut self, pat: Gc<Pat>, succ: LiveNode)
-> LiveNode { -> LiveNode {
self.define_bindings_in_arm_pats([pat], succ) self.define_bindings_in_arm_pats([pat], succ)
} }
fn define_bindings_in_arm_pats(&mut self, pats: &[@Pat], succ: LiveNode) fn define_bindings_in_arm_pats(&mut self, pats: &[Gc<Pat>], succ: LiveNode)
-> LiveNode { -> LiveNode {
let mut succ = succ; let mut succ = succ;
self.arm_pats_bindings(pats, |this, ln, var, _sp, _id| { self.arm_pats_bindings(pats, |this, ln, var, _sp, _id| {
@ -858,19 +859,19 @@ impl<'a> Liveness<'a> {
-> LiveNode { -> LiveNode {
let succ = self.propagate_through_opt_expr(blk.expr, succ); let succ = self.propagate_through_opt_expr(blk.expr, succ);
blk.stmts.iter().rev().fold(succ, |succ, stmt| { blk.stmts.iter().rev().fold(succ, |succ, stmt| {
self.propagate_through_stmt(*stmt, succ) self.propagate_through_stmt(&**stmt, succ)
}) })
} }
fn propagate_through_stmt(&mut self, stmt: &Stmt, succ: LiveNode) fn propagate_through_stmt(&mut self, stmt: &Stmt, succ: LiveNode)
-> LiveNode { -> LiveNode {
match stmt.node { match stmt.node {
StmtDecl(decl, _) => { StmtDecl(ref decl, _) => {
self.propagate_through_decl(decl, succ) self.propagate_through_decl(&**decl, succ)
} }
StmtExpr(expr, _) | StmtSemi(expr, _) => { StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => {
self.propagate_through_expr(expr, succ) self.propagate_through_expr(&**expr, succ)
} }
StmtMac(..) => { StmtMac(..) => {
@ -883,7 +884,7 @@ impl<'a> Liveness<'a> {
-> LiveNode { -> LiveNode {
match decl.node { match decl.node {
DeclLocal(ref local) => { DeclLocal(ref local) => {
self.propagate_through_local(*local, succ) self.propagate_through_local(&**local, succ)
} }
DeclItem(_) => succ, DeclItem(_) => succ,
} }
@ -909,19 +910,19 @@ impl<'a> Liveness<'a> {
self.define_bindings_in_pat(local.pat, succ) self.define_bindings_in_pat(local.pat, succ)
} }
fn propagate_through_exprs(&mut self, exprs: &[@Expr], succ: LiveNode) fn propagate_through_exprs(&mut self, exprs: &[Gc<Expr>], succ: LiveNode)
-> LiveNode { -> LiveNode {
exprs.iter().rev().fold(succ, |succ, expr| { exprs.iter().rev().fold(succ, |succ, expr| {
self.propagate_through_expr(*expr, succ) self.propagate_through_expr(&**expr, succ)
}) })
} }
fn propagate_through_opt_expr(&mut self, fn propagate_through_opt_expr(&mut self,
opt_expr: Option<@Expr>, opt_expr: Option<Gc<Expr>>,
succ: LiveNode) succ: LiveNode)
-> LiveNode { -> LiveNode {
opt_expr.iter().fold(succ, |succ, expr| { opt_expr.iter().fold(succ, |succ, expr| {
self.propagate_through_expr(*expr, succ) self.propagate_through_expr(&**expr, succ)
}) })
} }
@ -936,11 +937,11 @@ impl<'a> Liveness<'a> {
self.access_path(expr, succ, ACC_READ | ACC_USE) self.access_path(expr, succ, ACC_READ | ACC_USE)
} }
ExprField(e, _, _) => { ExprField(ref e, _, _) => {
self.propagate_through_expr(e, succ) self.propagate_through_expr(&**e, succ)
} }
ExprFnBlock(_, blk) | ExprProc(_, blk) => { ExprFnBlock(_, ref blk) | ExprProc(_, ref blk) => {
debug!("{} is an ExprFnBlock or ExprProc", expr_to_str(expr)); debug!("{} is an ExprFnBlock or ExprProc", expr_to_str(expr));
/* /*
@ -967,7 +968,7 @@ impl<'a> Liveness<'a> {
}) })
} }
ExprIf(cond, then, els) => { ExprIf(ref cond, ref then, ref els) => {
// //
// (cond) // (cond)
// | // |
@ -981,27 +982,27 @@ impl<'a> Liveness<'a> {
// v v // v v
// ( succ ) // ( succ )
// //
let else_ln = self.propagate_through_opt_expr(els, succ); let else_ln = self.propagate_through_opt_expr(els.clone(), succ);
let then_ln = self.propagate_through_block(then, succ); let then_ln = self.propagate_through_block(&**then, succ);
let ln = self.live_node(expr.id, expr.span); let ln = self.live_node(expr.id, expr.span);
self.init_from_succ(ln, else_ln); self.init_from_succ(ln, else_ln);
self.merge_from_succ(ln, then_ln, false); self.merge_from_succ(ln, then_ln, false);
self.propagate_through_expr(cond, ln) self.propagate_through_expr(&**cond, ln)
} }
ExprWhile(cond, blk) => { ExprWhile(ref cond, ref blk) => {
self.propagate_through_loop(expr, Some(cond), blk, succ) self.propagate_through_loop(expr, Some(cond.clone()), &**blk, succ)
} }
ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
// Note that labels have been resolved, so we don't need to look // Note that labels have been resolved, so we don't need to look
// at the label ident // at the label ident
ExprLoop(blk, _) => { ExprLoop(ref blk, _) => {
self.propagate_through_loop(expr, None, blk, succ) self.propagate_through_loop(expr, None, &**blk, succ)
} }
ExprMatch(e, ref arms) => { ExprMatch(ref e, ref arms) => {
// //
// (e) // (e)
// | // |
@ -1021,7 +1022,7 @@ impl<'a> Liveness<'a> {
let mut first_merge = true; let mut first_merge = true;
for arm in arms.iter() { for arm in arms.iter() {
let body_succ = let body_succ =
self.propagate_through_expr(arm.body, succ); self.propagate_through_expr(&*arm.body, succ);
let guard_succ = let guard_succ =
self.propagate_through_opt_expr(arm.guard, body_succ); self.propagate_through_opt_expr(arm.guard, body_succ);
let arm_succ = let arm_succ =
@ -1030,7 +1031,7 @@ impl<'a> Liveness<'a> {
self.merge_from_succ(ln, arm_succ, first_merge); self.merge_from_succ(ln, arm_succ, first_merge);
first_merge = false; first_merge = false;
}; };
self.propagate_through_expr(e, ln) self.propagate_through_expr(&**e, ln)
} }
ExprRet(o_e) => { ExprRet(o_e) => {
@ -1066,49 +1067,49 @@ impl<'a> Liveness<'a> {
} }
} }
ExprAssign(l, r) => { ExprAssign(ref l, ref r) => {
// see comment on lvalues in // see comment on lvalues in
// propagate_through_lvalue_components() // propagate_through_lvalue_components()
let succ = self.write_lvalue(l, succ, ACC_WRITE); let succ = self.write_lvalue(&**l, succ, ACC_WRITE);
let succ = self.propagate_through_lvalue_components(l, succ); let succ = self.propagate_through_lvalue_components(&**l, succ);
self.propagate_through_expr(r, succ) self.propagate_through_expr(&**r, succ)
} }
ExprAssignOp(_, l, r) => { ExprAssignOp(_, ref l, ref r) => {
// see comment on lvalues in // see comment on lvalues in
// propagate_through_lvalue_components() // propagate_through_lvalue_components()
let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ); let succ = self.write_lvalue(&**l, succ, ACC_WRITE|ACC_READ);
let succ = self.propagate_through_expr(r, succ); let succ = self.propagate_through_expr(&**r, succ);
self.propagate_through_lvalue_components(l, succ) self.propagate_through_lvalue_components(&**l, succ)
} }
// Uninteresting cases: just propagate in rev exec order // Uninteresting cases: just propagate in rev exec order
ExprVstore(expr, _) => { ExprVstore(ref expr, _) => {
self.propagate_through_expr(expr, succ) self.propagate_through_expr(&**expr, succ)
} }
ExprVec(ref exprs) => { ExprVec(ref exprs) => {
self.propagate_through_exprs(exprs.as_slice(), succ) self.propagate_through_exprs(exprs.as_slice(), succ)
} }
ExprRepeat(element, count) => { ExprRepeat(ref element, ref count) => {
let succ = self.propagate_through_expr(count, succ); let succ = self.propagate_through_expr(&**count, succ);
self.propagate_through_expr(element, succ) self.propagate_through_expr(&**element, succ)
} }
ExprStruct(_, ref fields, with_expr) => { ExprStruct(_, ref fields, ref with_expr) => {
let succ = self.propagate_through_opt_expr(with_expr, succ); let succ = self.propagate_through_opt_expr(with_expr.clone(), succ);
fields.iter().rev().fold(succ, |succ, field| { fields.iter().rev().fold(succ, |succ, field| {
self.propagate_through_expr(field.expr, succ) self.propagate_through_expr(&*field.expr, succ)
}) })
} }
ExprCall(f, ref args) => { ExprCall(ref f, ref args) => {
// calling a fn with bot return type means that the fn // calling a fn with bot return type means that the fn
// will fail, and hence the successors can be ignored // will fail, and hence the successors can be ignored
let is_bot = !self.ir.tcx.is_method_call(expr.id) && { let is_bot = !self.ir.tcx.is_method_call(expr.id) && {
let t_ret = ty::ty_fn_ret(ty::expr_ty(self.ir.tcx, f)); let t_ret = ty::ty_fn_ret(ty::expr_ty(self.ir.tcx, &**f));
ty::type_is_bot(t_ret) ty::type_is_bot(t_ret)
}; };
let succ = if is_bot { let succ = if is_bot {
@ -1117,7 +1118,7 @@ impl<'a> Liveness<'a> {
succ succ
}; };
let succ = self.propagate_through_exprs(args.as_slice(), succ); let succ = self.propagate_through_exprs(args.as_slice(), succ);
self.propagate_through_expr(f, succ) self.propagate_through_expr(&**f, succ)
} }
ExprMethodCall(_, _, ref args) => { ExprMethodCall(_, _, ref args) => {
@ -1133,39 +1134,39 @@ impl<'a> Liveness<'a> {
self.propagate_through_exprs(exprs.as_slice(), succ) self.propagate_through_exprs(exprs.as_slice(), succ)
} }
ExprBinary(op, l, r) if ast_util::lazy_binop(op) => { ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
let r_succ = self.propagate_through_expr(r, succ); let r_succ = self.propagate_through_expr(&**r, succ);
let ln = self.live_node(expr.id, expr.span); let ln = self.live_node(expr.id, expr.span);
self.init_from_succ(ln, succ); self.init_from_succ(ln, succ);
self.merge_from_succ(ln, r_succ, false); self.merge_from_succ(ln, r_succ, false);
self.propagate_through_expr(l, ln) self.propagate_through_expr(&**l, ln)
} }
ExprIndex(l, r) | ExprIndex(ref l, ref r) |
ExprBinary(_, l, r) | ExprBinary(_, ref l, ref r) |
ExprBox(l, r) => { ExprBox(ref l, ref r) => {
self.propagate_through_exprs([l, r], succ) self.propagate_through_exprs([l.clone(), r.clone()], succ)
} }
ExprAddrOf(_, e) | ExprAddrOf(_, ref e) |
ExprCast(e, _) | ExprCast(ref e, _) |
ExprUnary(_, e) | ExprUnary(_, ref e) |
ExprParen(e) => { ExprParen(ref e) => {
self.propagate_through_expr(e, succ) self.propagate_through_expr(&**e, succ)
} }
ExprInlineAsm(ref ia) => { ExprInlineAsm(ref ia) => {
let succ = ia.outputs.iter().rev().fold(succ, |succ, &(_, expr)| { let succ = ia.outputs.iter().rev().fold(succ, |succ, &(_, ref expr)| {
// see comment on lvalues in // see comment on lvalues in
// propagate_through_lvalue_components() // propagate_through_lvalue_components()
let succ = self.write_lvalue(expr, succ, ACC_WRITE); let succ = self.write_lvalue(&**expr, succ, ACC_WRITE);
self.propagate_through_lvalue_components(expr, succ) self.propagate_through_lvalue_components(&**expr, succ)
}); });
// Inputs are executed first. Propagate last because of rev order // Inputs are executed first. Propagate last because of rev order
ia.inputs.iter().rev().fold(succ, |succ, &(_, expr)| { ia.inputs.iter().rev().fold(succ, |succ, &(_, ref expr)| {
self.propagate_through_expr(expr, succ) self.propagate_through_expr(&**expr, succ)
}) })
} }
@ -1173,8 +1174,8 @@ impl<'a> Liveness<'a> {
succ succ
} }
ExprBlock(blk) => { ExprBlock(ref blk) => {
self.propagate_through_block(blk, succ) self.propagate_through_block(&**blk, succ)
} }
ExprMac(..) => { ExprMac(..) => {
@ -1238,7 +1239,7 @@ impl<'a> Liveness<'a> {
match expr.node { match expr.node {
ExprPath(_) => succ, ExprPath(_) => succ,
ExprField(e, _, _) => self.propagate_through_expr(e, succ), ExprField(ref e, _, _) => self.propagate_through_expr(&**e, succ),
_ => self.propagate_through_expr(expr, succ) _ => self.propagate_through_expr(expr, succ)
} }
} }
@ -1276,7 +1277,7 @@ impl<'a> Liveness<'a> {
fn propagate_through_loop(&mut self, fn propagate_through_loop(&mut self,
expr: &Expr, expr: &Expr,
cond: Option<@Expr>, cond: Option<Gc<Expr>>,
body: &Block, body: &Block,
succ: LiveNode) succ: LiveNode)
-> LiveNode { -> LiveNode {
@ -1353,10 +1354,10 @@ impl<'a> Liveness<'a> {
fn check_local(this: &mut Liveness, local: &Local) { fn check_local(this: &mut Liveness, local: &Local) {
match local.init { match local.init {
Some(_) => { Some(_) => {
this.warn_about_unused_or_dead_vars_in_pat(local.pat); this.warn_about_unused_or_dead_vars_in_pat(&*local.pat);
}, },
None => { None => {
this.pat_bindings(local.pat, |this, ln, var, sp, id| { this.pat_bindings(&*local.pat, |this, ln, var, sp, id| {
this.warn_about_unused(sp, id, ln, var); this.warn_about_unused(sp, id, ln, var);
}) })
} }
@ -1374,28 +1375,28 @@ fn check_arm(this: &mut Liveness, arm: &Arm) {
fn check_expr(this: &mut Liveness, expr: &Expr) { fn check_expr(this: &mut Liveness, expr: &Expr) {
match expr.node { match expr.node {
ExprAssign(l, r) => { ExprAssign(ref l, ref r) => {
this.check_lvalue(l); this.check_lvalue(&**l);
this.visit_expr(r, ()); this.visit_expr(&**r, ());
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr, ());
} }
ExprAssignOp(_, l, _) => { ExprAssignOp(_, ref l, _) => {
this.check_lvalue(l); this.check_lvalue(&**l);
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr, ());
} }
ExprInlineAsm(ref ia) => { ExprInlineAsm(ref ia) => {
for &(_, input) in ia.inputs.iter() { for &(_, ref input) in ia.inputs.iter() {
this.visit_expr(input, ()); this.visit_expr(&**input, ());
} }
// Output operands must be lvalues // Output operands must be lvalues
for &(_, out) in ia.outputs.iter() { for &(_, ref out) in ia.outputs.iter() {
this.check_lvalue(out); this.check_lvalue(&**out);
this.visit_expr(out, ()); this.visit_expr(&**out, ());
} }
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr, ());
@ -1448,8 +1449,8 @@ impl<'a> Liveness<'a> {
let ends_with_stmt = match body.expr { let ends_with_stmt = match body.expr {
None if body.stmts.len() > 0 => None if body.stmts.len() > 0 =>
match body.stmts.last().unwrap().node { match body.stmts.last().unwrap().node {
StmtSemi(e, _) => { StmtSemi(ref e, _) => {
let t_stmt = ty::expr_ty(self.ir.tcx, e); let t_stmt = ty::expr_ty(self.ir.tcx, &**e);
ty::get(t_stmt).sty == ty::get(t_ret).sty ty::get(t_stmt).sty == ty::get(t_ret).sty
}, },
_ => false _ => false
@ -1519,7 +1520,7 @@ impl<'a> Liveness<'a> {
fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) { fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) {
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
pat_util::pat_bindings(&self.ir.tcx.def_map, pat_util::pat_bindings(&self.ir.tcx.def_map,
arg.pat, &*arg.pat,
|_bm, p_id, sp, path| { |_bm, p_id, sp, path| {
let var = self.variable(p_id, sp); let var = self.variable(p_id, sp);
// Ignore unused self. // Ignore unused self.

View File

@ -440,22 +440,22 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
let expr_ty = if_ok!(self.expr_ty(expr)); let expr_ty = if_ok!(self.expr_ty(expr));
match expr.node { match expr.node {
ast::ExprUnary(ast::UnDeref, e_base) => { ast::ExprUnary(ast::UnDeref, ref e_base) => {
let base_cmt = if_ok!(self.cat_expr(e_base)); let base_cmt = if_ok!(self.cat_expr(&**e_base));
Ok(self.cat_deref(expr, base_cmt, 0)) Ok(self.cat_deref(expr, base_cmt, 0))
} }
ast::ExprField(base, f_name, _) => { ast::ExprField(ref base, f_name, _) => {
let base_cmt = if_ok!(self.cat_expr(base)); let base_cmt = if_ok!(self.cat_expr(&**base));
Ok(self.cat_field(expr, base_cmt, f_name, expr_ty)) Ok(self.cat_field(expr, base_cmt, f_name, expr_ty))
} }
ast::ExprIndex(base, _) => { ast::ExprIndex(ref base, _) => {
if self.typer.is_method_call(expr.id) { if self.typer.is_method_call(expr.id) {
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)); return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
} }
let base_cmt = if_ok!(self.cat_expr(base)); let base_cmt = if_ok!(self.cat_expr(&**base));
Ok(self.cat_index(expr, base_cmt, 0)) Ok(self.cat_index(expr, base_cmt, 0))
} }
@ -464,8 +464,8 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
self.cat_def(expr.id, expr.span, expr_ty, def) self.cat_def(expr.id, expr.span, expr_ty, def)
} }
ast::ExprParen(e) => { ast::ExprParen(ref e) => {
self.cat_expr(e) self.cat_expr(&**e)
} }
ast::ExprAddrOf(..) | ast::ExprCall(..) | ast::ExprAddrOf(..) | ast::ExprCall(..) |
@ -999,31 +999,32 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
} }
}; };
for (i, &subpat) in subpats.iter().enumerate() { for (i, subpat) in subpats.iter().enumerate() {
let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
let subcmt = let subcmt =
self.cat_imm_interior( self.cat_imm_interior(
pat, downcast_cmt.clone(), subpat_ty, pat, downcast_cmt.clone(), subpat_ty,
InteriorField(PositionalField(i))); InteriorField(PositionalField(i)));
if_ok!(self.cat_pattern(subcmt, subpat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)));
} }
} }
Some(&def::DefFn(..)) | Some(&def::DefFn(..)) |
Some(&def::DefStruct(..)) => { Some(&def::DefStruct(..)) => {
for (i, &subpat) in subpats.iter().enumerate() { for (i, subpat) in subpats.iter().enumerate() {
let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
let cmt_field = let cmt_field =
self.cat_imm_interior( self.cat_imm_interior(
pat, cmt.clone(), subpat_ty, pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i))); InteriorField(PositionalField(i)));
if_ok!(self.cat_pattern(cmt_field, subpat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(cmt_field, &**subpat,
|x,y,z| op(x,y,z)));
} }
} }
Some(&def::DefStatic(..)) => { Some(&def::DefStatic(..)) => {
for &subpat in subpats.iter() { for subpat in subpats.iter() {
if_ok!(self.cat_pattern(cmt.clone(), subpat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z)));
} }
} }
_ => { _ => {
@ -1034,8 +1035,8 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
} }
} }
ast::PatIdent(_, _, Some(subpat)) => { ast::PatIdent(_, _, Some(ref subpat)) => {
if_ok!(self.cat_pattern(cmt, subpat, op)); if_ok!(self.cat_pattern(cmt, &**subpat, op));
} }
ast::PatIdent(_, _, None) => { ast::PatIdent(_, _, None) => {
@ -1045,42 +1046,43 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
ast::PatStruct(_, ref field_pats, _) => { ast::PatStruct(_, ref field_pats, _) => {
// {f1: p1, ..., fN: pN} // {f1: p1, ..., fN: pN}
for fp in field_pats.iter() { for fp in field_pats.iter() {
let field_ty = if_ok!(self.pat_ty(fp.pat)); // see (*2) let field_ty = if_ok!(self.pat_ty(&*fp.pat)); // see (*2)
let cmt_field = self.cat_field(pat, cmt.clone(), fp.ident, field_ty); let cmt_field = self.cat_field(pat, cmt.clone(), fp.ident, field_ty);
if_ok!(self.cat_pattern(cmt_field, fp.pat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(cmt_field, &*fp.pat, |x,y,z| op(x,y,z)));
} }
} }
ast::PatTup(ref subpats) => { ast::PatTup(ref subpats) => {
// (p1, ..., pN) // (p1, ..., pN)
for (i, &subpat) in subpats.iter().enumerate() { for (i, subpat) in subpats.iter().enumerate() {
let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
let subcmt = let subcmt =
self.cat_imm_interior( self.cat_imm_interior(
pat, cmt.clone(), subpat_ty, pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i))); InteriorField(PositionalField(i)));
if_ok!(self.cat_pattern(subcmt, subpat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)));
} }
} }
ast::PatBox(subpat) | ast::PatRegion(subpat) => { ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
// @p1, ~p1 // @p1, ~p1
let subcmt = self.cat_deref(pat, cmt, 0); let subcmt = self.cat_deref(pat, cmt, 0);
if_ok!(self.cat_pattern(subcmt, subpat, op)); if_ok!(self.cat_pattern(subcmt, &**subpat, op));
} }
ast::PatVec(ref before, slice, ref after) => { ast::PatVec(ref before, slice, ref after) => {
let elt_cmt = self.cat_index(pat, cmt, 0); let elt_cmt = self.cat_index(pat, cmt, 0);
for &before_pat in before.iter() { for before_pat in before.iter() {
if_ok!(self.cat_pattern(elt_cmt.clone(), before_pat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(elt_cmt.clone(), &**before_pat,
|x,y,z| op(x,y,z)));
} }
for &slice_pat in slice.iter() { for slice_pat in slice.iter() {
let slice_ty = if_ok!(self.pat_ty(slice_pat)); let slice_ty = if_ok!(self.pat_ty(&**slice_pat));
let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty); let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
if_ok!(self.cat_pattern(slice_cmt, slice_pat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(slice_cmt, &**slice_pat, |x,y,z| op(x,y,z)));
} }
for &after_pat in after.iter() { for after_pat in after.iter() {
if_ok!(self.cat_pattern(elt_cmt.clone(), after_pat, |x,y,z| op(x,y,z))); if_ok!(self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z)));
} }
} }

View File

@ -12,6 +12,7 @@
//! outside their scopes. This pass will also generate a set of exported items //! outside their scopes. This pass will also generate a set of exported items
//! which are available for use externally when compiled as a library. //! which are available for use externally when compiled as a library.
use std::gc::Gc;
use std::mem::replace; use std::mem::replace;
use metadata::csearch; use metadata::csearch;
@ -797,8 +798,8 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) { fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
match expr.node { match expr.node {
ast::ExprField(base, ident, _) => { ast::ExprField(ref base, ident, _) => {
match ty::get(ty::expr_ty_adjusted(self.tcx, base)).sty { match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
ty::ty_struct(id, _) => { ty::ty_struct(id, _) => {
self.check_field(expr.span, id, NamedField(ident)); self.check_field(expr.span, id, NamedField(ident));
} }
@ -1134,7 +1135,7 @@ impl<'a> SanePrivacyVisitor<'a> {
tcx.sess.span_err(sp, "visibility has no effect inside functions"); tcx.sess.span_err(sp, "visibility has no effect inside functions");
} }
} }
let check_struct = |def: &@ast::StructDef| { let check_struct = |def: &Gc<ast::StructDef>| {
for f in def.fields.iter() { for f in def.fields.iter() {
match f.node.kind { match f.node.kind {
ast::NamedField(_, p) => check_inherited(tcx, f.span, p), ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
@ -1281,7 +1282,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
at_outer_type: true, at_outer_type: true,
outer_type_is_public_path: false, outer_type_is_public_path: false,
}; };
visitor.visit_ty(self_, ()); visitor.visit_ty(&*self_, ());
self_contains_private = visitor.contains_private; self_contains_private = visitor.contains_private;
self_is_public_path = visitor.outer_type_is_public_path; self_is_public_path = visitor.outer_type_is_public_path;
} }
@ -1318,7 +1319,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
match *trait_ref { match *trait_ref {
None => { None => {
for method in methods.iter() { for method in methods.iter() {
visit::walk_method_helper(self, *method, ()) visit::walk_method_helper(self, &**method, ())
} }
} }
Some(ref tr) => { Some(ref tr) => {
@ -1345,7 +1346,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
if method.explicit_self.node == ast::SelfStatic && if method.explicit_self.node == ast::SelfStatic &&
self.exported_items.contains(&method.id) { self.exported_items.contains(&method.id) {
found_pub_static = true; found_pub_static = true;
visit::walk_method_helper(self, *method, ()); visit::walk_method_helper(self, &**method, ());
} }
} }
if found_pub_static { if found_pub_static {

View File

@ -70,7 +70,7 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
{ {
match tcx.map.find(impl_src.node) { match tcx.map.find(impl_src.node) {
Some(ast_map::NodeItem(item)) => { Some(ast_map::NodeItem(item)) => {
item_might_be_inlined(item) item_might_be_inlined(&*item)
} }
Some(..) | None => { Some(..) | None => {
tcx.sess.span_bug(method.span, "impl did is not an item") tcx.sess.span_bug(method.span, "impl did is not an item")
@ -184,7 +184,7 @@ impl<'a> ReachableContext<'a> {
match self.tcx.map.find(node_id) { match self.tcx.map.find(node_id) {
Some(ast_map::NodeItem(item)) => { Some(ast_map::NodeItem(item)) => {
match item.node { match item.node {
ast::ItemFn(..) => item_might_be_inlined(item), ast::ItemFn(..) => item_might_be_inlined(&*item),
_ => false, _ => false,
} }
} }
@ -273,20 +273,20 @@ impl<'a> ReachableContext<'a> {
match *node { match *node {
ast_map::NodeItem(item) => { ast_map::NodeItem(item) => {
match item.node { match item.node {
ast::ItemFn(_, _, _, _, search_block) => { ast::ItemFn(_, _, _, _, ref search_block) => {
if item_might_be_inlined(item) { if item_might_be_inlined(&*item) {
visit::walk_block(self, search_block, ()) visit::walk_block(self, &**search_block, ())
} }
} }
// Statics with insignificant addresses are not reachable // Statics with insignificant addresses are not reachable
// because they're inlined specially into all other crates. // because they're inlined specially into all other crates.
ast::ItemStatic(_, _, init) => { ast::ItemStatic(_, _, ref init) => {
if attr::contains_name(item.attrs.as_slice(), if attr::contains_name(item.attrs.as_slice(),
"address_insignificant") { "address_insignificant") {
self.reachable_symbols.remove(&search_item); self.reachable_symbols.remove(&search_item);
} }
visit::walk_expr(self, init, ()); visit::walk_expr(self, &**init, ());
} }
// These are normal, nothing reachable about these // These are normal, nothing reachable about these
@ -310,14 +310,14 @@ impl<'a> ReachableContext<'a> {
// Keep going, nothing to get exported // Keep going, nothing to get exported
} }
ast::Provided(ref method) => { ast::Provided(ref method) => {
visit::walk_block(self, method.body, ()) visit::walk_block(self, &*method.body, ())
} }
} }
} }
ast_map::NodeMethod(method) => { ast_map::NodeMethod(method) => {
let did = self.tcx.map.get_parent_did(search_item); let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, method, did) { if method_might_be_inlined(self.tcx, &*method, did) {
visit::walk_block(self, method.body, ()) visit::walk_block(self, &*method.body, ())
} }
} }
// Nothing to recurse on for these // Nothing to recurse on for these

View File

@ -28,6 +28,7 @@ use util::nodemap::NodeMap;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::gc::Gc;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::{ast, visit}; use syntax::{ast, visit};
use syntax::visit::{Visitor, FnKind}; use syntax::visit::{Visitor, FnKind};
@ -628,11 +629,11 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
// FIXME(#6308) -- Note that `[]` patterns work more smoothly post-DST. // FIXME(#6308) -- Note that `[]` patterns work more smoothly post-DST.
match local.init { match local.init {
Some(expr) => { Some(ref expr) => {
record_rvalue_scope_if_borrow_expr(visitor, expr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, &**expr, blk_id);
if is_binding_pat(local.pat) || is_borrowed_ty(local.ty) { if is_binding_pat(&*local.pat) || is_borrowed_ty(&*local.ty) {
record_rvalue_scope(visitor, expr, blk_id); record_rvalue_scope(visitor, &**expr, blk_id);
} }
} }
@ -657,22 +658,22 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
ast::PatIdent(ast::BindByRef(_), _, _) => true, ast::PatIdent(ast::BindByRef(_), _, _) => true,
ast::PatStruct(_, ref field_pats, _) => { ast::PatStruct(_, ref field_pats, _) => {
field_pats.iter().any(|fp| is_binding_pat(fp.pat)) field_pats.iter().any(|fp| is_binding_pat(&*fp.pat))
} }
ast::PatVec(ref pats1, ref pats2, ref pats3) => { ast::PatVec(ref pats1, ref pats2, ref pats3) => {
pats1.iter().any(|&p| is_binding_pat(p)) || pats1.iter().any(|p| is_binding_pat(&**p)) ||
pats2.iter().any(|&p| is_binding_pat(p)) || pats2.iter().any(|p| is_binding_pat(&**p)) ||
pats3.iter().any(|&p| is_binding_pat(p)) pats3.iter().any(|p| is_binding_pat(&**p))
} }
ast::PatEnum(_, Some(ref subpats)) | ast::PatEnum(_, Some(ref subpats)) |
ast::PatTup(ref subpats) => { ast::PatTup(ref subpats) => {
subpats.iter().any(|&p| is_binding_pat(p)) subpats.iter().any(|p| is_binding_pat(&**p))
} }
ast::PatBox(subpat) => { ast::PatBox(ref subpat) => {
is_binding_pat(subpat) is_binding_pat(&**subpat)
} }
_ => false, _ => false,
@ -709,39 +710,39 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
*/ */
match expr.node { match expr.node {
ast::ExprAddrOf(_, subexpr) => { ast::ExprAddrOf(_, ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
record_rvalue_scope(visitor, subexpr, blk_id); record_rvalue_scope(visitor, &**subexpr, blk_id);
} }
ast::ExprStruct(_, ref fields, _) => { ast::ExprStruct(_, ref fields, _) => {
for field in fields.iter() { for field in fields.iter() {
record_rvalue_scope_if_borrow_expr( record_rvalue_scope_if_borrow_expr(
visitor, field.expr, blk_id); visitor, &*field.expr, blk_id);
} }
} }
ast::ExprVstore(subexpr, _) => { ast::ExprVstore(ref subexpr, _) => {
visitor.region_maps.record_rvalue_scope(subexpr.id, blk_id); visitor.region_maps.record_rvalue_scope(subexpr.id, blk_id);
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
} }
ast::ExprVec(ref subexprs) | ast::ExprVec(ref subexprs) |
ast::ExprTup(ref subexprs) => { ast::ExprTup(ref subexprs) => {
for &subexpr in subexprs.iter() { for subexpr in subexprs.iter() {
record_rvalue_scope_if_borrow_expr( record_rvalue_scope_if_borrow_expr(
visitor, subexpr, blk_id); visitor, &**subexpr, blk_id);
} }
} }
ast::ExprUnary(ast::UnUniq, subexpr) => { ast::ExprUnary(ast::UnUniq, ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
} }
ast::ExprCast(subexpr, _) | ast::ExprCast(ref subexpr, _) |
ast::ExprParen(subexpr) => { ast::ExprParen(ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id) record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id)
} }
ast::ExprBlock(ref block) => { ast::ExprBlock(ref block) => {
match block.expr { match block.expr {
Some(subexpr) => { Some(ref subexpr) => {
record_rvalue_scope_if_borrow_expr( record_rvalue_scope_if_borrow_expr(
visitor, subexpr, blk_id); visitor, &**subexpr, blk_id);
} }
None => { } None => { }
} }
@ -789,7 +790,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
ast::ExprField(ref subexpr, _, _) | ast::ExprField(ref subexpr, _, _) |
ast::ExprIndex(ref subexpr, _) | ast::ExprIndex(ref subexpr, _) |
ast::ExprParen(ref subexpr) => { ast::ExprParen(ref subexpr) => {
let subexpr: &'a @Expr = subexpr; // FIXME(#11586) let subexpr: &'a Gc<Expr> = subexpr; // FIXME(#11586)
expr = &**subexpr; expr = &**subexpr;
} }
_ => { _ => {

View File

@ -34,9 +34,9 @@ use syntax::visit::Visitor;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::gc::Gc;
use std::mem::replace; use std::mem::replace;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::string::String;
use std::uint; use std::uint;
// Definition mapping // Definition mapping
@ -1195,9 +1195,9 @@ impl<'a> Resolver<'a> {
name_bindings.define_type name_bindings.define_type
(DefTy(local_def(item.id)), sp, is_public); (DefTy(local_def(item.id)), sp, is_public);
for &variant in (*enum_definition).variants.iter() { for variant in (*enum_definition).variants.iter() {
self.build_reduced_graph_for_variant( self.build_reduced_graph_for_variant(
variant, &**variant,
local_def(item.id), local_def(item.id),
parent.clone(), parent.clone(),
is_public); is_public);
@ -3430,7 +3430,7 @@ impl<'a> Resolver<'a> {
FunctionRibKind(function_id, body_id) => { FunctionRibKind(function_id, body_id) => {
if !is_ty_param { if !is_ty_param {
def = DefUpvar(def.def_id().node, def = DefUpvar(def.def_id().node,
@def, box(GC) def,
function_id, function_id,
body_id); body_id);
} }
@ -3565,7 +3565,7 @@ impl<'a> Resolver<'a> {
// resolve the discriminator expr // resolve the discriminator expr
// as a constant // as a constant
self.with_constant_rib(|this| { self.with_constant_rib(|this| {
this.resolve_expr(*dis_expr); this.resolve_expr(&**dis_expr);
}); });
} }
} }
@ -3593,13 +3593,13 @@ impl<'a> Resolver<'a> {
} }
ItemImpl(ref generics, ItemImpl(ref generics,
ref implemented_traits, ref implemented_traits,
self_type, ref self_type,
ref methods) => { ref methods) => {
self.resolve_implementation(item.id, self.resolve_implementation(item.id,
generics, generics,
implemented_traits, implemented_traits,
self_type, &**self_type,
methods.as_slice()); methods.as_slice());
} }
@ -3647,16 +3647,16 @@ impl<'a> Resolver<'a> {
&ty_m.generics.ty_params); &ty_m.generics.ty_params);
for argument in ty_m.decl.inputs.iter() { for argument in ty_m.decl.inputs.iter() {
this.resolve_type(argument.ty); this.resolve_type(&*argument.ty);
} }
this.resolve_type(ty_m.decl.output); this.resolve_type(&*ty_m.decl.output);
}); });
} }
ast::Provided(m) => { ast::Provided(ref m) => {
this.resolve_method(MethodRibKind(item.id, this.resolve_method(MethodRibKind(item.id,
Provided(m.id)), Provided(m.id)),
m, &**m,
generics.ty_params.len()) generics.ty_params.len())
} }
} }
@ -3690,12 +3690,12 @@ impl<'a> Resolver<'a> {
generics, foreign_item.id, 0, generics, foreign_item.id, 0,
ItemRibKind), ItemRibKind),
|this| visit::walk_foreign_item(this, |this| visit::walk_foreign_item(this,
*foreign_item, &**foreign_item,
())); ()));
} }
ForeignItemStatic(..) => { ForeignItemStatic(..) => {
visit::walk_foreign_item(this, visit::walk_foreign_item(this,
*foreign_item, &**foreign_item,
()); ());
} }
} }
@ -3812,21 +3812,21 @@ impl<'a> Resolver<'a> {
} }
Some(declaration) => { Some(declaration) => {
for argument in declaration.inputs.iter() { for argument in declaration.inputs.iter() {
this.resolve_pattern(argument.pat, this.resolve_pattern(&*argument.pat,
ArgumentIrrefutableMode, ArgumentIrrefutableMode,
None); None);
this.resolve_type(argument.ty); this.resolve_type(&*argument.ty);
debug!("(resolving function) recorded argument"); debug!("(resolving function) recorded argument");
} }
this.resolve_type(declaration.output); this.resolve_type(&*declaration.output);
} }
} }
// Resolve the function body. // Resolve the function body.
this.resolve_block(block); this.resolve_block(&*block);
debug!("(resolving function) leaving function"); debug!("(resolving function) leaving function");
}); });
@ -3842,7 +3842,7 @@ impl<'a> Resolver<'a> {
self.resolve_type_parameter_bound(type_parameter.id, bound); self.resolve_type_parameter_bound(type_parameter.id, bound);
} }
match type_parameter.default { match type_parameter.default {
Some(ty) => self.resolve_type(ty), Some(ref ty) => self.resolve_type(&**ty),
None => {} None => {}
} }
} }
@ -3857,10 +3857,10 @@ impl<'a> Resolver<'a> {
} }
UnboxedFnTyParamBound(ref unboxed_function) => { UnboxedFnTyParamBound(ref unboxed_function) => {
for argument in unboxed_function.decl.inputs.iter() { for argument in unboxed_function.decl.inputs.iter() {
self.resolve_type(argument.ty); self.resolve_type(&*argument.ty);
} }
self.resolve_type(unboxed_function.decl.output); self.resolve_type(&*unboxed_function.decl.output);
} }
StaticRegionTyParamBound | OtherRegionTyParamBound(_) => {} StaticRegionTyParamBound | OtherRegionTyParamBound(_) => {}
} }
@ -3938,7 +3938,7 @@ impl<'a> Resolver<'a> {
// Resolve fields. // Resolve fields.
for field in fields.iter() { for field in fields.iter() {
this.resolve_type(field.node.ty); this.resolve_type(&*field.node.ty);
} }
}); });
} }
@ -3995,7 +3995,7 @@ impl<'a> Resolver<'a> {
generics: &Generics, generics: &Generics,
opt_trait_reference: &Option<TraitRef>, opt_trait_reference: &Option<TraitRef>,
self_type: &Ty, self_type: &Ty,
methods: &[@Method]) { methods: &[Gc<Method>]) {
// If applicable, create a rib for the type parameters. // If applicable, create a rib for the type parameters.
let outer_type_parameter_count = generics.ty_params.len(); let outer_type_parameter_count = generics.ty_params.len();
self.with_type_parameter_rib(HasTypeParameters(generics, self.with_type_parameter_rib(HasTypeParameters(generics,
@ -4015,7 +4015,7 @@ impl<'a> Resolver<'a> {
for method in methods.iter() { for method in methods.iter() {
// We also need a new scope for the method-specific type parameters. // We also need a new scope for the method-specific type parameters.
this.resolve_method(MethodRibKind(id, Provided(method.id)), this.resolve_method(MethodRibKind(id, Provided(method.id)),
*method, &**method,
outer_type_parameter_count); outer_type_parameter_count);
} }
}); });
@ -4032,20 +4032,20 @@ impl<'a> Resolver<'a> {
fn resolve_local(&mut self, local: &Local) { fn resolve_local(&mut self, local: &Local) {
// Resolve the type. // Resolve the type.
self.resolve_type(local.ty); self.resolve_type(&*local.ty);
// Resolve the initializer, if necessary. // Resolve the initializer, if necessary.
match local.init { match local.init {
None => { None => {
// Nothing to do. // Nothing to do.
} }
Some(initializer) => { Some(ref initializer) => {
self.resolve_expr(initializer); self.resolve_expr(&**initializer);
} }
} }
// Resolve the pattern. // Resolve the pattern.
self.resolve_pattern(local.pat, LocalIrrefutableMode, None); self.resolve_pattern(&*local.pat, LocalIrrefutableMode, None);
} }
// build a map from pattern identifiers to binding-info's. // build a map from pattern identifiers to binding-info's.
@ -4069,9 +4069,9 @@ impl<'a> Resolver<'a> {
if arm.pats.len() == 0 { if arm.pats.len() == 0 {
return return
} }
let map_0 = self.binding_mode_map(*arm.pats.get(0)); let map_0 = self.binding_mode_map(&**arm.pats.get(0));
for (i, p) in arm.pats.iter().enumerate() { for (i, p) in arm.pats.iter().enumerate() {
let map_i = self.binding_mode_map(*p); let map_i = self.binding_mode_map(&**p);
for (&key, &binding_0) in map_0.iter() { for (&key, &binding_0) in map_0.iter() {
match map_i.find(&key) { match map_i.find(&key) {
@ -4114,7 +4114,7 @@ impl<'a> Resolver<'a> {
let mut bindings_list = HashMap::new(); let mut bindings_list = HashMap::new();
for pattern in arm.pats.iter() { for pattern in arm.pats.iter() {
self.resolve_pattern(*pattern, self.resolve_pattern(&**pattern,
RefutableMode, RefutableMode,
Some(&mut bindings_list)); Some(&mut bindings_list));
} }
@ -4124,7 +4124,7 @@ impl<'a> Resolver<'a> {
self.check_consistent_bindings(arm); self.check_consistent_bindings(arm);
visit::walk_expr_opt(self, arm.guard, ()); visit::walk_expr_opt(self, arm.guard, ());
self.resolve_expr(arm.body); self.resolve_expr(&*arm.body);
self.value_ribs.borrow_mut().pop(); self.value_ribs.borrow_mut().pop();
} }
@ -4392,10 +4392,10 @@ impl<'a> Resolver<'a> {
} }
// Check the types in the path pattern. // Check the types in the path pattern.
for &ty in path.segments for ty in path.segments
.iter() .iter()
.flat_map(|seg| seg.types.iter()) { .flat_map(|seg| seg.types.iter()) {
self.resolve_type(ty); self.resolve_type(&**ty);
} }
} }
@ -4430,10 +4430,10 @@ impl<'a> Resolver<'a> {
} }
// Check the types in the path pattern. // Check the types in the path pattern.
for &ty in path.segments for ty in path.segments
.iter() .iter()
.flat_map(|s| s.types.iter()) { .flat_map(|s| s.types.iter()) {
self.resolve_type(ty); self.resolve_type(&**ty);
} }
} }
@ -4467,20 +4467,20 @@ impl<'a> Resolver<'a> {
} }
// Check the types in the path pattern. // Check the types in the path pattern.
for &ty in path.segments for ty in path.segments
.iter() .iter()
.flat_map(|s| s.types.iter()) { .flat_map(|s| s.types.iter()) {
self.resolve_type(ty); self.resolve_type(&**ty);
} }
} }
PatLit(expr) => { PatLit(ref expr) => {
self.resolve_expr(expr); self.resolve_expr(&**expr);
} }
PatRange(first_expr, last_expr) => { PatRange(ref first_expr, ref last_expr) => {
self.resolve_expr(first_expr); self.resolve_expr(&**first_expr);
self.resolve_expr(last_expr); self.resolve_expr(&**last_expr);
} }
PatStruct(ref path, _, _) => { PatStruct(ref path, _, _) => {
@ -4571,8 +4571,8 @@ impl<'a> Resolver<'a> {
namespace: Namespace, namespace: Namespace,
check_ribs: bool) -> Option<(Def, LastPrivate)> { check_ribs: bool) -> Option<(Def, LastPrivate)> {
// First, resolve the types. // First, resolve the types.
for &ty in path.segments.iter().flat_map(|s| s.types.iter()) { for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
self.resolve_type(ty); self.resolve_type(&**ty);
} }
if path.global { if path.global {
@ -4919,8 +4919,8 @@ impl<'a> Resolver<'a> {
-> Option<(Path, NodeId, FallbackChecks)> { -> Option<(Path, NodeId, FallbackChecks)> {
match t.node { match t.node {
TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)), TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
TyPtr(mut_ty) => extract_path_and_node_id(mut_ty.ty, OnlyTraitAndStatics), TyPtr(mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
TyRptr(_, mut_ty) => extract_path_and_node_id(mut_ty.ty, allow), TyRptr(_, mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
// This doesn't handle the remaining `Ty` variants as they are not // This doesn't handle the remaining `Ty` variants as they are not
// that commonly the self_type, it might be interesting to provide // that commonly the self_type, it might be interesting to provide
// support for those in future. // support for those in future.

View File

@ -226,6 +226,7 @@ use util::ppaux::{Repr, vec_map_to_str};
use std::collections::HashMap; use std::collections::HashMap;
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
use syntax::ast; use syntax::ast;
use syntax::ast::Ident; use syntax::ast::Ident;
use syntax::ast_util::path_to_ident; use syntax::ast_util::path_to_ident;
@ -237,7 +238,7 @@ use syntax::parse::token::InternedString;
// expression. // expression.
enum Lit { enum Lit {
UnitLikeStructLit(ast::NodeId), // the node ID of the pattern UnitLikeStructLit(ast::NodeId), // the node ID of the pattern
ExprLit(@ast::Expr), ExprLit(Gc<ast::Expr>),
ConstLit(ast::DefId), // the def ID of the constant ConstLit(ast::DefId), // the def ID of the constant
} }
@ -252,11 +253,11 @@ pub enum VecLenOpt {
enum Opt { enum Opt {
lit(Lit), lit(Lit),
var(ty::Disr, Rc<adt::Repr>), var(ty::Disr, Rc<adt::Repr>),
range(@ast::Expr, @ast::Expr), range(Gc<ast::Expr>, Gc<ast::Expr>),
vec_len(/* length */ uint, VecLenOpt, /*range of matches*/(uint, uint)) vec_len(/* length */ uint, VecLenOpt, /*range of matches*/(uint, uint))
} }
fn lit_to_expr(tcx: &ty::ctxt, a: &Lit) -> @ast::Expr { fn lit_to_expr(tcx: &ty::ctxt, a: &Lit) -> Gc<ast::Expr> {
match *a { match *a {
ExprLit(existing_a_expr) => existing_a_expr, ExprLit(existing_a_expr) => existing_a_expr,
ConstLit(a_const) => const_eval::lookup_const_by_id(tcx, a_const).unwrap(), ConstLit(a_const) => const_eval::lookup_const_by_id(tcx, a_const).unwrap(),
@ -270,14 +271,14 @@ fn opt_eq(tcx: &ty::ctxt, a: &Opt, b: &Opt) -> bool {
(&lit(a), &lit(b)) => { (&lit(a), &lit(b)) => {
let a_expr = lit_to_expr(tcx, &a); let a_expr = lit_to_expr(tcx, &a);
let b_expr = lit_to_expr(tcx, &b); let b_expr = lit_to_expr(tcx, &b);
match const_eval::compare_lit_exprs(tcx, a_expr, b_expr) { match const_eval::compare_lit_exprs(tcx, &*a_expr, &*b_expr) {
Some(val1) => val1 == 0, Some(val1) => val1 == 0,
None => fail!("compare_list_exprs: type mismatch"), None => fail!("compare_list_exprs: type mismatch"),
} }
} }
(&range(a1, a2), &range(b1, b2)) => { (&range(ref a1, ref a2), &range(ref b1, ref b2)) => {
let m1 = const_eval::compare_lit_exprs(tcx, a1, b1); let m1 = const_eval::compare_lit_exprs(tcx, &**a1, &**b1);
let m2 = const_eval::compare_lit_exprs(tcx, a2, b2); let m2 = const_eval::compare_lit_exprs(tcx, &**a2, &**b2);
match (m1, m2) { match (m1, m2) {
(Some(val1), Some(val2)) => (val1 == 0 && val2 == 0), (Some(val1), Some(val2)) => (val1 == 0 && val2 == 0),
_ => fail!("compare_list_exprs: type mismatch"), _ => fail!("compare_list_exprs: type mismatch"),
@ -301,8 +302,8 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let mut bcx = bcx; let mut bcx = bcx;
match *o { match *o {
lit(ExprLit(lit_expr)) => { lit(ExprLit(ref lit_expr)) => {
let lit_datum = unpack_datum!(bcx, expr::trans(bcx, lit_expr)); let lit_datum = unpack_datum!(bcx, expr::trans(bcx, &**lit_expr));
let lit_datum = lit_datum.assert_rvalue(bcx); // literals are rvalues let lit_datum = lit_datum.assert_rvalue(bcx); // literals are rvalues
let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx)); let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
return single_result(Result::new(bcx, lit_datum.val)); return single_result(Result::new(bcx, lit_datum.val));
@ -322,9 +323,9 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
var(disr_val, ref repr) => { var(disr_val, ref repr) => {
return adt::trans_case(bcx, &**repr, disr_val); return adt::trans_case(bcx, &**repr, disr_val);
} }
range(l1, l2) => { range(ref l1, ref l2) => {
let (l1, _) = consts::const_expr(ccx, l1, true); let (l1, _) = consts::const_expr(ccx, &**l1, true);
let (l2, _) = consts::const_expr(ccx, l2, true); let (l2, _) = consts::const_expr(ccx, &**l2, true);
return range_result(Result::new(bcx, l1), Result::new(bcx, l2)); return range_result(Result::new(bcx, l1), Result::new(bcx, l2));
} }
vec_len(n, vec_len_eq, _) => { vec_len(n, vec_len_eq, _) => {
@ -398,7 +399,7 @@ struct ArmData<'a, 'b> {
* these pointers are stored in llmatch variables just before executing `data` arm. * these pointers are stored in llmatch variables just before executing `data` arm.
*/ */
struct Match<'a, 'b> { struct Match<'a, 'b> {
pats: Vec<@ast::Pat>, pats: Vec<Gc<ast::Pat>>,
data: &'a ArmData<'a, 'b>, data: &'a ArmData<'a, 'b>,
bound_ptrs: Vec<(Ident, ValueRef)> bound_ptrs: Vec<(Ident, ValueRef)>
} }
@ -461,8 +462,8 @@ fn expand_nested_bindings<'a, 'b>(
}).collect() }).collect()
} }
fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) { fn assert_is_binding_or_wild(bcx: &Block, p: Gc<ast::Pat>) {
if !pat_is_binding_or_wild(&bcx.tcx().def_map, p) { if !pat_is_binding_or_wild(&bcx.tcx().def_map, &*p) {
bcx.sess().span_bug( bcx.sess().span_bug(
p.span, p.span,
format!("expected an identifier pattern but found p: {}", format!("expected an identifier pattern but found p: {}",
@ -470,7 +471,7 @@ fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) {
} }
} }
type enter_pat<'a> = |@ast::Pat|: 'a -> Option<Vec<@ast::Pat>>; type enter_pat<'a> = |Gc<ast::Pat>|: 'a -> Option<Vec<Gc<ast::Pat>>>;
fn enter_match<'a, 'b>( fn enter_match<'a, 'b>(
bcx: &'b Block<'b>, bcx: &'b Block<'b>,
@ -496,7 +497,7 @@ fn enter_match<'a, 'b>(
let mut bound_ptrs = br.bound_ptrs.clone(); let mut bound_ptrs = br.bound_ptrs.clone();
match this.node { match this.node {
ast::PatIdent(_, ref path, None) => { ast::PatIdent(_, ref path, None) => {
if pat_is_binding(dm, this) { if pat_is_binding(dm, &*this) {
bound_ptrs.push((path_to_ident(path), val)); bound_ptrs.push((path_to_ident(path), val));
} }
} }
@ -531,7 +532,7 @@ fn enter_default<'a, 'b>(
let matches = enter_match(bcx, dm, m, col, val, |p| { let matches = enter_match(bcx, dm, m, col, val, |p| {
match p.node { match p.node {
ast::PatWild | ast::PatWildMulti => Some(Vec::new()), ast::PatWild | ast::PatWildMulti => Some(Vec::new()),
ast::PatIdent(_, _, None) if pat_is_binding(dm, p) => Some(Vec::new()), ast::PatIdent(_, _, None) if pat_is_binding(dm, &*p) => Some(Vec::new()),
_ => None _ => None
} }
}); });
@ -600,12 +601,12 @@ fn enter_opt<'a, 'b>(
let _indenter = indenter(); let _indenter = indenter();
let tcx = bcx.tcx(); let tcx = bcx.tcx();
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP}; let dummy = box(GC) ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
let mut i = 0; let mut i = 0;
enter_match(bcx, &tcx.def_map, m, col, val, |p| { enter_match(bcx, &tcx.def_map, m, col, val, |p| {
let answer = match p.node { let answer = match p.node {
ast::PatEnum(..) | ast::PatEnum(..) |
ast::PatIdent(_, _, None) if pat_is_const(&tcx.def_map, p) => { ast::PatIdent(_, _, None) if pat_is_const(&tcx.def_map, &*p) => {
let const_def = tcx.def_map.borrow().get_copy(&p.id); let const_def = tcx.def_map.borrow().get_copy(&p.id);
let const_def_id = const_def.def_id(); let const_def_id = const_def.def_id();
if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) { if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
@ -628,7 +629,7 @@ fn enter_opt<'a, 'b>(
} }
} }
ast::PatIdent(_, _, None) ast::PatIdent(_, _, None)
if pat_is_variant_or_struct(&tcx.def_map, p) => { if pat_is_variant_or_struct(&tcx.def_map, &*p) => {
if opt_eq(tcx, &variant_opt(bcx, p.id), opt) { if opt_eq(tcx, &variant_opt(bcx, p.id), opt) {
Some(Vec::new()) Some(Vec::new())
} else { } else {
@ -739,7 +740,7 @@ fn enter_rec_or_struct<'a, 'b>(
bcx.val_to_str(val)); bcx.val_to_str(val));
let _indenter = indenter(); let _indenter = indenter();
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP}; let dummy = box(GC) ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
enter_match(bcx, dm, m, col, val, |p| { enter_match(bcx, dm, m, col, val, |p| {
match p.node { match p.node {
ast::PatStruct(_, ref fpats, _) => { ast::PatStruct(_, ref fpats, _) => {
@ -775,7 +776,7 @@ fn enter_tup<'a, 'b>(
bcx.val_to_str(val)); bcx.val_to_str(val));
let _indenter = indenter(); let _indenter = indenter();
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP}; let dummy = box(GC) ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
enter_match(bcx, dm, m, col, val, |p| { enter_match(bcx, dm, m, col, val, |p| {
match p.node { match p.node {
ast::PatTup(ref elts) => { ast::PatTup(ref elts) => {
@ -808,7 +809,7 @@ fn enter_tuple_struct<'a, 'b>(
bcx.val_to_str(val)); bcx.val_to_str(val));
let _indenter = indenter(); let _indenter = indenter();
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP}; let dummy = box(GC) ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
enter_match(bcx, dm, m, col, val, |p| { enter_match(bcx, dm, m, col, val, |p| {
match p.node { match p.node {
ast::PatEnum(_, Some(ref elts)) => { ast::PatEnum(_, Some(ref elts)) => {
@ -839,7 +840,7 @@ fn enter_uniq<'a, 'b>(
bcx.val_to_str(val)); bcx.val_to_str(val));
let _indenter = indenter(); let _indenter = indenter();
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP}; let dummy = box(GC) ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
enter_match(bcx, dm, m, col, val, |p| { enter_match(bcx, dm, m, col, val, |p| {
match p.node { match p.node {
ast::PatBox(sub) => { ast::PatBox(sub) => {
@ -867,7 +868,7 @@ fn enter_region<'a, 'b>(
bcx.val_to_str(val)); bcx.val_to_str(val));
let _indenter = indenter(); let _indenter = indenter();
let dummy = @ast::Pat { id: 0, node: ast::PatWild, span: DUMMY_SP }; let dummy = box(GC) ast::Pat { id: 0, node: ast::PatWild, span: DUMMY_SP };
enter_match(bcx, dm, m, col, val, |p| { enter_match(bcx, dm, m, col, val, |p| {
match p.node { match p.node {
ast::PatRegion(sub) => { ast::PatRegion(sub) => {
@ -1194,14 +1195,14 @@ fn pick_col(m: &[Match]) -> uint {
fn score(p: &ast::Pat) -> uint { fn score(p: &ast::Pat) -> uint {
match p.node { match p.node {
ast::PatLit(_) | ast::PatEnum(_, _) | ast::PatRange(_, _) => 1u, ast::PatLit(_) | ast::PatEnum(_, _) | ast::PatRange(_, _) => 1u,
ast::PatIdent(_, _, Some(p)) => score(p), ast::PatIdent(_, _, Some(ref p)) => score(&**p),
_ => 0u _ => 0u
} }
} }
let mut scores = Vec::from_elem(m[0].pats.len(), 0u); let mut scores = Vec::from_elem(m[0].pats.len(), 0u);
for br in m.iter() { for br in m.iter() {
for (i, p) in br.pats.iter().enumerate() { for (i, ref p) in br.pats.iter().enumerate() {
*scores.get_mut(i) += score(*p); *scores.get_mut(i) += score(&***p);
} }
} }
let mut max_score = 0u; let mut max_score = 0u;
@ -1454,9 +1455,9 @@ fn compile_submatch<'a, 'b>(
Store(bcx, *value_ptr, llmatch); Store(bcx, *value_ptr, llmatch);
} }
match data.arm.guard { match data.arm.guard {
Some(guard_expr) => { Some(ref guard_expr) => {
bcx = compile_guard(bcx, bcx = compile_guard(bcx,
guard_expr, &**guard_expr,
m[0].data, m[0].data,
m.slice(1, m.len()), m.slice(1, m.len()),
vals, vals,
@ -1841,7 +1842,7 @@ pub fn trans_match<'a>(
trans_match_inner(bcx, match_expr.id, discr_expr, arms, dest) trans_match_inner(bcx, match_expr.id, discr_expr, arms, dest)
} }
fn create_bindings_map(bcx: &Block, pat: @ast::Pat) -> BindingsMap { fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
// Create the bindings map, which is a mapping from each binding name // Create the bindings map, which is a mapping from each binding name
// to an alloca() that will be the value for that local variable. // to an alloca() that will be the value for that local variable.
// Note that we use the names because each binding will have many ids // Note that we use the names because each binding will have many ids
@ -1849,7 +1850,7 @@ fn create_bindings_map(bcx: &Block, pat: @ast::Pat) -> BindingsMap {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let tcx = bcx.tcx(); let tcx = bcx.tcx();
let mut bindings_map = HashMap::new(); let mut bindings_map = HashMap::new();
pat_bindings(&tcx.def_map, pat, |bm, p_id, span, path| { pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path| {
let ident = path_to_ident(path); let ident = path_to_ident(path);
let variable_ty = node_id_type(bcx, p_id); let variable_ty = node_id_type(bcx, p_id);
let llvariable_ty = type_of::type_of(ccx, variable_ty); let llvariable_ty = type_of::type_of(ccx, variable_ty);
@ -1966,7 +1967,7 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
let cleanup_scope = fcx.push_custom_cleanup_scope(); let cleanup_scope = fcx.push_custom_cleanup_scope();
bcx = insert_lllocals(bcx, &arm_data.bindings_map, bcx = insert_lllocals(bcx, &arm_data.bindings_map,
cleanup::CustomScope(cleanup_scope)); cleanup::CustomScope(cleanup_scope));
bcx = expr::trans_into(bcx, arm_data.arm.body, dest); bcx = expr::trans_into(bcx, &*arm_data.arm.body, dest);
bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
arm_cxs.push(bcx); arm_cxs.push(bcx);
} }
@ -2007,12 +2008,12 @@ pub fn store_local<'a>(bcx: &'a Block<'a>,
// //
// In such cases, the more general path is unsafe, because // In such cases, the more general path is unsafe, because
// it assumes it is matching against a valid value. // it assumes it is matching against a valid value.
match simple_identifier(pat) { match simple_identifier(&*pat) {
Some(path) => { Some(path) => {
let var_scope = cleanup::var_scope(tcx, local.id); let var_scope = cleanup::var_scope(tcx, local.id);
return mk_binding_alloca( return mk_binding_alloca(
bcx, pat.id, path, BindLocal, var_scope, (), bcx, pat.id, path, BindLocal, var_scope, (),
|(), bcx, v, _| expr::trans_into(bcx, init_expr, |(), bcx, v, _| expr::trans_into(bcx, &*init_expr,
expr::SaveIn(v))); expr::SaveIn(v)));
} }
@ -2021,8 +2022,8 @@ pub fn store_local<'a>(bcx: &'a Block<'a>,
// General path. // General path.
let init_datum = let init_datum =
unpack_datum!(bcx, expr::trans_to_lvalue(bcx, init_expr, "let")); unpack_datum!(bcx, expr::trans_to_lvalue(bcx, &*init_expr, "let"));
if ty::type_is_bot(expr_ty(bcx, init_expr)) { if ty::type_is_bot(expr_ty(bcx, &*init_expr)) {
create_dummy_locals(bcx, pat) create_dummy_locals(bcx, pat)
} else { } else {
if bcx.sess().asm_comments() { if bcx.sess().asm_comments() {
@ -2038,12 +2039,12 @@ pub fn store_local<'a>(bcx: &'a Block<'a>,
}; };
fn create_dummy_locals<'a>(mut bcx: &'a Block<'a>, fn create_dummy_locals<'a>(mut bcx: &'a Block<'a>,
pat: @ast::Pat) pat: Gc<ast::Pat>)
-> &'a Block<'a> { -> &'a Block<'a> {
// create dummy memory for the variables if we have no // create dummy memory for the variables if we have no
// value to store into them immediately // value to store into them immediately
let tcx = bcx.tcx(); let tcx = bcx.tcx();
pat_bindings(&tcx.def_map, pat, |_, p_id, _, path| { pat_bindings(&tcx.def_map, &*pat, |_, p_id, _, path| {
let scope = cleanup::var_scope(tcx, p_id); let scope = cleanup::var_scope(tcx, p_id);
bcx = mk_binding_alloca( bcx = mk_binding_alloca(
bcx, p_id, path, BindLocal, scope, (), bcx, p_id, path, BindLocal, scope, (),
@ -2054,7 +2055,7 @@ pub fn store_local<'a>(bcx: &'a Block<'a>,
} }
pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pub fn store_arg<'a>(mut bcx: &'a Block<'a>,
pat: @ast::Pat, pat: Gc<ast::Pat>,
arg: Datum<Rvalue>, arg: Datum<Rvalue>,
arg_scope: cleanup::ScopeId) arg_scope: cleanup::ScopeId)
-> &'a Block<'a> { -> &'a Block<'a> {
@ -2073,7 +2074,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>,
let _icx = push_ctxt("match::store_arg"); let _icx = push_ctxt("match::store_arg");
match simple_identifier(pat) { match simple_identifier(&*pat) {
Some(path) => { Some(path) => {
// Generate nicer LLVM for the common case of fn a pattern // Generate nicer LLVM for the common case of fn a pattern
// like `x: T` // like `x: T`
@ -2137,7 +2138,7 @@ fn mk_binding_alloca<'a,A>(bcx: &'a Block<'a>,
fn bind_irrefutable_pat<'a>( fn bind_irrefutable_pat<'a>(
bcx: &'a Block<'a>, bcx: &'a Block<'a>,
pat: @ast::Pat, pat: Gc<ast::Pat>,
val: ValueRef, val: ValueRef,
binding_mode: IrrefutablePatternBindingMode, binding_mode: IrrefutablePatternBindingMode,
cleanup_scope: cleanup::ScopeId) cleanup_scope: cleanup::ScopeId)
@ -2176,7 +2177,7 @@ fn bind_irrefutable_pat<'a>(
let ccx = bcx.ccx(); let ccx = bcx.ccx();
match pat.node { match pat.node {
ast::PatIdent(pat_binding_mode, ref path, inner) => { ast::PatIdent(pat_binding_mode, ref path, inner) => {
if pat_is_binding(&tcx.def_map, pat) { if pat_is_binding(&tcx.def_map, &*pat) {
// Allocate the stack slot where the value of this // Allocate the stack slot where the value of this
// binding will live and place it into the appropriate // binding will live and place it into the appropriate
// map. // map.

View File

@ -37,23 +37,23 @@ pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::InlineAsm)
let temp_scope = fcx.push_custom_cleanup_scope(); let temp_scope = fcx.push_custom_cleanup_scope();
// Prepare the output operands // Prepare the output operands
let outputs = ia.outputs.iter().map(|&(ref c, out)| { let outputs = ia.outputs.iter().map(|&(ref c, ref out)| {
constraints.push((*c).clone()); constraints.push((*c).clone());
let out_datum = unpack_datum!(bcx, expr::trans(bcx, out)); let out_datum = unpack_datum!(bcx, expr::trans(bcx, &**out));
output_types.push(type_of::type_of(bcx.ccx(), out_datum.ty)); output_types.push(type_of::type_of(bcx.ccx(), out_datum.ty));
out_datum.val out_datum.val
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
// Now the input operands // Now the input operands
let inputs = ia.inputs.iter().map(|&(ref c, input)| { let inputs = ia.inputs.iter().map(|&(ref c, ref input)| {
constraints.push((*c).clone()); constraints.push((*c).clone());
let in_datum = unpack_datum!(bcx, expr::trans(bcx, input)); let in_datum = unpack_datum!(bcx, expr::trans(bcx, &**input));
unpack_result!(bcx, { unpack_result!(bcx, {
callee::trans_arg_datum(bcx, callee::trans_arg_datum(bcx,
expr_ty(bcx, input), expr_ty(bcx, &**input),
in_datum, in_datum,
cleanup::CustomScope(temp_scope), cleanup::CustomScope(temp_scope),
callee::DontAutorefArg) callee::DontAutorefArg)

View File

@ -81,6 +81,7 @@ use std::c_str::ToCStr;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
use std::{i8, i16, i32, i64}; use std::{i8, i16, i32, i64};
use std::gc::Gc;
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic}; use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
use syntax::ast_util::{local_def, is_local}; use syntax::ast_util::{local_def, is_local};
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
@ -977,8 +978,8 @@ pub fn init_local<'a>(bcx: &'a Block<'a>, local: &ast::Local)
if ignore_lhs(bcx, local) { if ignore_lhs(bcx, local) {
// Handle let _ = e; just like e; // Handle let _ = e; just like e;
match local.init { match local.init {
Some(init) => { Some(ref init) => {
return controlflow::trans_stmt_semi(bcx, init) return controlflow::trans_stmt_semi(bcx, &**init)
} }
None => { return bcx; } None => { return bcx; }
} }
@ -1537,14 +1538,14 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef, fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
sp: Span, id: ast::NodeId, vi: &[Rc<ty::VariantInfo>], sp: Span, id: ast::NodeId, vi: &[Rc<ty::VariantInfo>],
i: &mut uint) { i: &mut uint) {
for &variant in enum_definition.variants.iter() { for variant in enum_definition.variants.iter() {
let disr_val = vi[*i].disr_val; let disr_val = vi[*i].disr_val;
*i += 1; *i += 1;
match variant.node.kind { match variant.node.kind {
ast::TupleVariantKind(ref args) if args.len() > 0 => { ast::TupleVariantKind(ref args) if args.len() > 0 => {
let llfn = get_item_val(ccx, variant.node.id); let llfn = get_item_val(ccx, variant.node.id);
trans_enum_variant(ccx, id, variant, args.as_slice(), trans_enum_variant(ccx, id, &**variant, args.as_slice(),
disr_val, &param_substs::empty(), llfn); disr_val, &param_substs::empty(), llfn);
} }
ast::TupleVariantKind(_) => { ast::TupleVariantKind(_) => {
@ -1621,16 +1622,16 @@ impl<'a> Visitor<()> for TransItemVisitor<'a> {
pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
let _icx = push_ctxt("trans_item"); let _icx = push_ctxt("trans_item");
match item.node { match item.node {
ast::ItemFn(decl, _fn_style, abi, ref generics, body) => { ast::ItemFn(ref decl, _fn_style, abi, ref generics, ref body) => {
if abi != Rust { if abi != Rust {
let llfndecl = get_item_val(ccx, item.id); let llfndecl = get_item_val(ccx, item.id);
foreign::trans_rust_fn_with_foreign_abi( foreign::trans_rust_fn_with_foreign_abi(
ccx, decl, body, item.attrs.as_slice(), llfndecl, item.id); ccx, &**decl, &**body, item.attrs.as_slice(), llfndecl, item.id);
} else if !generics.is_type_parameterized() { } else if !generics.is_type_parameterized() {
let llfn = get_item_val(ccx, item.id); let llfn = get_item_val(ccx, item.id);
trans_fn(ccx, trans_fn(ccx,
decl, &**decl,
body, &**body,
llfn, llfn,
&param_substs::empty(), &param_substs::empty(),
item.id, item.id,
@ -1639,7 +1640,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
// Be sure to travel more than just one layer deep to catch nested // Be sure to travel more than just one layer deep to catch nested
// items in blocks and such. // items in blocks and such.
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
v.visit_block(body, ()); v.visit_block(&**body, ());
} }
} }
ast::ItemImpl(ref generics, _, _, ref ms) => { ast::ItemImpl(ref generics, _, _, ref ms) => {
@ -1655,10 +1656,10 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
trans_enum_def(ccx, enum_definition, item.span, item.id, vi.as_slice(), &mut i); trans_enum_def(ccx, enum_definition, item.span, item.id, vi.as_slice(), &mut i);
} }
} }
ast::ItemStatic(_, m, expr) => { ast::ItemStatic(_, m, ref expr) => {
// Recurse on the expression to catch items in blocks // Recurse on the expression to catch items in blocks
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
v.visit_expr(expr, ()); v.visit_expr(&**expr, ());
consts::trans_const(ccx, m, item.id); consts::trans_const(ccx, m, item.id);
// Do static_assert checking. It can't really be done much earlier // Do static_assert checking. It can't really be done much earlier
// because we need to get the value of the bool out of LLVM // because we need to get the value of the bool out of LLVM
@ -1697,7 +1698,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
} }
} }
pub fn trans_struct_def(ccx: &CrateContext, struct_def: @ast::StructDef) { pub fn trans_struct_def(ccx: &CrateContext, struct_def: Gc<ast::StructDef>) {
// If this is a tuple-like struct, translate the constructor. // If this is a tuple-like struct, translate the constructor.
match struct_def.ctor_id { match struct_def.ctor_id {
// We only need to translate a constructor if there are fields; // We only need to translate a constructor if there are fields;
@ -1719,7 +1720,7 @@ pub fn trans_struct_def(ccx: &CrateContext, struct_def: @ast::StructDef) {
pub fn trans_mod(ccx: &CrateContext, m: &ast::Mod) { pub fn trans_mod(ccx: &CrateContext, m: &ast::Mod) {
let _icx = push_ctxt("trans_mod"); let _icx = push_ctxt("trans_mod");
for item in m.items.iter() { for item in m.items.iter() {
trans_item(ccx, *item); trans_item(ccx, &**item);
} }
} }
@ -2003,7 +2004,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
let sym = exported_name(ccx, id, ty, i.attrs.as_slice()); let sym = exported_name(ccx, id, ty, i.attrs.as_slice());
let v = match i.node { let v = match i.node {
ast::ItemStatic(_, _, expr) => { ast::ItemStatic(_, _, ref expr) => {
// If this static came from an external crate, then // If this static came from an external crate, then
// we need to get the symbol from csearch instead of // we need to get the symbol from csearch instead of
// using the current crate's name/version // using the current crate's name/version
@ -2022,7 +2023,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
// We need the translated value here, because for enums the // We need the translated value here, because for enums the
// LLVM type is not fully determined by the Rust type. // LLVM type is not fully determined by the Rust type.
let (v, inlineable) = consts::const_expr(ccx, expr, is_local); let (v, inlineable) = consts::const_expr(ccx, &**expr, is_local);
ccx.const_values.borrow_mut().insert(id, v); ccx.const_values.borrow_mut().insert(id, v);
let mut inlineable = inlineable; let mut inlineable = inlineable;
@ -2118,13 +2119,13 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
get_item_val()"); get_item_val()");
} }
ast::Provided(m) => { ast::Provided(m) => {
register_method(ccx, id, m) register_method(ccx, id, &*m)
} }
} }
} }
ast_map::NodeMethod(m) => { ast_map::NodeMethod(m) => {
register_method(ccx, id, m) register_method(ccx, id, &*m)
} }
ast_map::NodeForeignItem(ni) => { ast_map::NodeForeignItem(ni) => {
@ -2134,13 +2135,13 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
ast::ForeignItemFn(..) => { ast::ForeignItemFn(..) => {
let abi = ccx.tcx.map.get_foreign_abi(id); let abi = ccx.tcx.map.get_foreign_abi(id);
let ty = ty::node_id_to_type(ccx.tcx(), ni.id); let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
let name = foreign::link_name(ni); let name = foreign::link_name(&*ni);
foreign::register_foreign_item_fn(ccx, abi, ty, foreign::register_foreign_item_fn(ccx, abi, ty,
name.get().as_slice(), name.get().as_slice(),
Some(ni.span)) Some(ni.span))
} }
ast::ForeignItemStatic(..) => { ast::ForeignItemStatic(..) => {
foreign::register_static(ccx, ni) foreign::register_static(ccx, &*ni)
} }
} }
} }

View File

@ -53,6 +53,8 @@ use syntax::ast;
use synabi = syntax::abi; use synabi = syntax::abi;
use syntax::ast_map; use syntax::ast_map;
use std::gc::Gc;
pub struct MethodData { pub struct MethodData {
pub llfn: ValueRef, pub llfn: ValueRef,
pub llself: ValueRef, pub llself: ValueRef,
@ -649,7 +651,7 @@ pub fn trans_call_inner<'a>(
let mut llargs = Vec::new(); let mut llargs = Vec::new();
let arg_tys = match args { let arg_tys = match args {
ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, *x)).collect(), ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, &**x)).collect(),
_ => fail!("expected arg exprs.") _ => fail!("expected arg exprs.")
}; };
bcx = trans_args(bcx, args, callee_ty, &mut llargs, bcx = trans_args(bcx, args, callee_ty, &mut llargs,
@ -683,7 +685,7 @@ pub fn trans_call_inner<'a>(
pub enum CallArgs<'a> { pub enum CallArgs<'a> {
// Supply value of arguments as a list of expressions that must be // Supply value of arguments as a list of expressions that must be
// translated. This is used in the common case of `foo(bar, qux)`. // translated. This is used in the common case of `foo(bar, qux)`.
ArgExprs(&'a [@ast::Expr]), ArgExprs(&'a [Gc<ast::Expr>]),
// Supply value of arguments as a list of LLVM value refs; frequently // Supply value of arguments as a list of LLVM value refs; frequently
// used with lang items and so forth, when the argument is an internal // used with lang items and so forth, when the argument is an internal
@ -715,18 +717,18 @@ fn trans_args<'a>(cx: &'a Block<'a>,
match args { match args {
ArgExprs(arg_exprs) => { ArgExprs(arg_exprs) => {
let num_formal_args = arg_tys.len(); let num_formal_args = arg_tys.len();
for (i, &arg_expr) in arg_exprs.iter().enumerate() { for (i, arg_expr) in arg_exprs.iter().enumerate() {
if i == 0 && ignore_self { if i == 0 && ignore_self {
continue; continue;
} }
let arg_ty = if i >= num_formal_args { let arg_ty = if i >= num_formal_args {
assert!(variadic); assert!(variadic);
expr_ty_adjusted(cx, arg_expr) expr_ty_adjusted(cx, &**arg_expr)
} else { } else {
*arg_tys.get(i) *arg_tys.get(i)
}; };
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_expr)); let arg_datum = unpack_datum!(bcx, expr::trans(bcx, &**arg_expr));
llargs.push(unpack_result!(bcx, { llargs.push(unpack_result!(bcx, {
trans_arg_datum(bcx, arg_ty, arg_datum, trans_arg_datum(bcx, arg_ty, arg_datum,
arg_cleanup_scope, arg_cleanup_scope,

View File

@ -34,8 +34,8 @@ use middle::ty;
use util::ppaux::{Repr, ty_to_str}; use util::ppaux::{Repr, ty_to_str};
use std::c_str::ToCStr; use std::c_str::ToCStr;
use std::gc::Gc;
use std::vec; use std::vec;
use std::vec::Vec;
use libc::c_uint; use libc::c_uint;
use syntax::{ast, ast_util}; use syntax::{ast, ast_util};
@ -92,11 +92,11 @@ pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
} }
fn const_vec(cx: &CrateContext, e: &ast::Expr, fn const_vec(cx: &CrateContext, e: &ast::Expr,
es: &[@ast::Expr], is_local: bool) -> (ValueRef, Type, bool) { es: &[Gc<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
let vec_ty = ty::expr_ty(cx.tcx(), e); let vec_ty = ty::expr_ty(cx.tcx(), e);
let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty); let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
let llunitty = type_of::type_of(cx, unit_ty); let llunitty = type_of::type_of(cx, unit_ty);
let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e, is_local))); let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, &**e, is_local)));
// If the vector contains enums, an LLVM array won't work. // If the vector contains enums, an LLVM array won't work.
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) { let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
C_struct(cx, vs.as_slice(), false) C_struct(cx, vs.as_slice(), false)
@ -292,8 +292,8 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
// if it's assigned to a static. // if it's assigned to a static.
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr, fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
is_local: bool) -> (ValueRef, bool) { is_local: bool) -> (ValueRef, bool) {
let map_list = |exprs: &[@ast::Expr]| { let map_list = |exprs: &[Gc<ast::Expr>]| {
exprs.iter().map(|&e| const_expr(cx, e, is_local)) exprs.iter().map(|e| const_expr(cx, &**e, is_local))
.fold((Vec::new(), true), .fold((Vec::new(), true),
|(l, all_inlineable), (val, inlineable)| { |(l, all_inlineable), (val, inlineable)| {
(l.append_one(val), all_inlineable && inlineable) (l.append_one(val), all_inlineable && inlineable)
@ -302,18 +302,18 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
unsafe { unsafe {
let _icx = push_ctxt("const_expr"); let _icx = push_ctxt("const_expr");
return match e.node { return match e.node {
ast::ExprLit(lit) => { ast::ExprLit(ref lit) => {
(consts::const_lit(cx, e, (*lit).clone()), true) (consts::const_lit(cx, e, (**lit).clone()), true)
} }
ast::ExprBinary(b, e1, e2) => { ast::ExprBinary(b, ref e1, ref e2) => {
let (te1, _) = const_expr(cx, e1, is_local); let (te1, _) = const_expr(cx, &**e1, is_local);
let (te2, _) = const_expr(cx, e2, is_local); let (te2, _) = const_expr(cx, &**e2, is_local);
let te2 = base::cast_shift_const_rhs(b, te1, te2); let te2 = base::cast_shift_const_rhs(b, te1, te2);
/* Neither type is bottom, and we expect them to be unified /* Neither type is bottom, and we expect them to be unified
* already, so the following is safe. */ * already, so the following is safe. */
let ty = ty::expr_ty(cx.tcx(), e1); let ty = ty::expr_ty(cx.tcx(), &**e1);
let is_float = ty::type_is_fp(ty); let is_float = ty::type_is_fp(ty);
let signed = ty::type_is_signed(ty); let signed = ty::type_is_signed(ty);
return (match b { return (match b {
@ -387,9 +387,9 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
}, },
}, true) }, true)
}, },
ast::ExprUnary(u, e) => { ast::ExprUnary(u, ref e) => {
let (te, _) = const_expr(cx, e, is_local); let (te, _) = const_expr(cx, &**e, is_local);
let ty = ty::expr_ty(cx.tcx(), e); let ty = ty::expr_ty(cx.tcx(), &**e);
let is_float = ty::type_is_fp(ty); let is_float = ty::type_is_fp(ty);
return (match u { return (match u {
ast::UnBox | ast::UnUniq | ast::UnDeref => { ast::UnBox | ast::UnUniq | ast::UnDeref => {
@ -414,20 +414,20 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
} }
}, true) }, true)
} }
ast::ExprField(base, field, _) => { ast::ExprField(ref base, field, _) => {
let bt = ty::expr_ty_adjusted(cx.tcx(), base); let bt = ty::expr_ty_adjusted(cx.tcx(), &**base);
let brepr = adt::represent_type(cx, bt); let brepr = adt::represent_type(cx, bt);
let (bv, inlineable) = const_expr(cx, base, is_local); let (bv, inlineable) = const_expr(cx, &**base, is_local);
expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| { expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| {
let ix = ty::field_idx_strict(cx.tcx(), field.name, field_tys); let ix = ty::field_idx_strict(cx.tcx(), field.name, field_tys);
(adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable) (adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
}) })
} }
ast::ExprIndex(base, index) => { ast::ExprIndex(ref base, ref index) => {
let bt = ty::expr_ty_adjusted(cx.tcx(), base); let bt = ty::expr_ty_adjusted(cx.tcx(), &**base);
let (bv, inlineable) = const_expr(cx, base, is_local); let (bv, inlineable) = const_expr(cx, &**base, is_local);
let iv = match const_eval::eval_const_expr(cx.tcx(), index) { let iv = match const_eval::eval_const_expr(cx.tcx(), &**index) {
const_eval::const_int(i) => i as u64, const_eval::const_int(i) => i as u64,
const_eval::const_uint(u) => u, const_eval::const_uint(u) => u,
_ => cx.sess().span_bug(index.span, _ => cx.sess().span_bug(index.span,
@ -466,11 +466,11 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
} }
(const_get_elt(cx, arr, [iv as c_uint]), inlineable) (const_get_elt(cx, arr, [iv as c_uint]), inlineable)
} }
ast::ExprCast(base, _) => { ast::ExprCast(ref base, _) => {
let ety = ty::expr_ty(cx.tcx(), e); let ety = ty::expr_ty(cx.tcx(), e);
let llty = type_of::type_of(cx, ety); let llty = type_of::type_of(cx, ety);
let basety = ty::expr_ty(cx.tcx(), base); let basety = ty::expr_ty(cx.tcx(), &**base);
let (v, inlineable) = const_expr(cx, base, is_local); let (v, inlineable) = const_expr(cx, &**base, is_local);
return (match (expr::cast_type_kind(basety), return (match (expr::cast_type_kind(basety),
expr::cast_type_kind(ety)) { expr::cast_type_kind(ety)) {
@ -520,8 +520,8 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
} }
}, inlineable) }, inlineable)
} }
ast::ExprAddrOf(ast::MutImmutable, sub) => { ast::ExprAddrOf(ast::MutImmutable, ref sub) => {
let (e, _) = const_expr(cx, sub, is_local); let (e, _) = const_expr(cx, &**sub, is_local);
(const_addr_of(cx, e), false) (const_addr_of(cx, e), false)
} }
ast::ExprTup(ref es) => { ast::ExprTup(ref es) => {
@ -536,7 +536,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
let tcx = cx.tcx(); let tcx = cx.tcx();
let base_val = match *base_opt { let base_val = match *base_opt {
Some(base) => Some(const_expr(cx, base, is_local)), Some(ref base) => Some(const_expr(cx, &**base, is_local)),
None => None None => None
}; };
@ -544,7 +544,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
let (cs, inlineable) = vec::unzip(field_tys.iter().enumerate() let (cs, inlineable) = vec::unzip(field_tys.iter().enumerate()
.map(|(ix, &field_ty)| { .map(|(ix, &field_ty)| {
match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) { match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) {
Some(f) => const_expr(cx, (*f).expr, is_local), Some(ref f) => const_expr(cx, &*f.expr, is_local),
None => { None => {
match base_val { match base_val {
Some((bv, inlineable)) => { Some((bv, inlineable)) => {
@ -567,12 +567,12 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
is_local); is_local);
(v, inlineable) (v, inlineable)
} }
ast::ExprVstore(sub, store @ ast::ExprVstoreSlice) | ast::ExprVstore(ref sub, store @ ast::ExprVstoreSlice) |
ast::ExprVstore(sub, store @ ast::ExprVstoreMutSlice) => { ast::ExprVstore(ref sub, store @ ast::ExprVstoreMutSlice) => {
match sub.node { match sub.node {
ast::ExprLit(ref lit) => { ast::ExprLit(ref lit) => {
match lit.node { match lit.node {
ast::LitStr(..) => { const_expr(cx, sub, is_local) } ast::LitStr(..) => { const_expr(cx, &**sub, is_local) }
_ => { cx.sess().span_bug(e.span, "bad const-slice lit") } _ => { cx.sess().span_bug(e.span, "bad const-slice lit") }
} }
} }
@ -595,16 +595,16 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
_ => cx.sess().span_bug(e.span, "bad const-slice expr") _ => cx.sess().span_bug(e.span, "bad const-slice expr")
} }
} }
ast::ExprRepeat(elem, count) => { ast::ExprRepeat(ref elem, ref count) => {
let vec_ty = ty::expr_ty(cx.tcx(), e); let vec_ty = ty::expr_ty(cx.tcx(), e);
let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty); let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
let llunitty = type_of::type_of(cx, unit_ty); let llunitty = type_of::type_of(cx, unit_ty);
let n = match const_eval::eval_const_expr(cx.tcx(), count) { let n = match const_eval::eval_const_expr(cx.tcx(), &**count) {
const_eval::const_int(i) => i as uint, const_eval::const_int(i) => i as uint,
const_eval::const_uint(i) => i as uint, const_eval::const_uint(i) => i as uint,
_ => cx.sess().span_bug(count.span, "count must be integral const expression.") _ => cx.sess().span_bug(count.span, "count must be integral const expression.")
}; };
let vs = Vec::from_elem(n, const_expr(cx, elem, is_local).val0()); let vs = Vec::from_elem(n, const_expr(cx, &**elem, is_local).val0());
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) { let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
C_struct(cx, vs.as_slice(), false) C_struct(cx, vs.as_slice(), false)
} else { } else {
@ -673,7 +673,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
_ => cx.sess().span_bug(e.span, "expected a struct or variant def") _ => cx.sess().span_bug(e.span, "expected a struct or variant def")
} }
} }
ast::ExprParen(e) => { const_expr(cx, e, is_local) } ast::ExprParen(ref e) => { const_expr(cx, &**e, is_local) }
ast::ExprBlock(ref block) => { ast::ExprBlock(ref block) => {
match block.expr { match block.expr {
Some(ref expr) => const_expr(cx, &**expr, is_local), Some(ref expr) => const_expr(cx, &**expr, is_local),

View File

@ -31,6 +31,8 @@ use syntax::parse::token::InternedString;
use syntax::parse::token; use syntax::parse::token;
use syntax::visit::Visitor; use syntax::visit::Visitor;
use std::gc::Gc;
pub fn trans_stmt<'a>(cx: &'a Block<'a>, pub fn trans_stmt<'a>(cx: &'a Block<'a>,
s: &ast::Stmt) s: &ast::Stmt)
-> &'a Block<'a> { -> &'a Block<'a> {
@ -48,18 +50,18 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>,
fcx.push_ast_cleanup_scope(id); fcx.push_ast_cleanup_scope(id);
match s.node { match s.node {
ast::StmtExpr(e, _) | ast::StmtSemi(e, _) => { ast::StmtExpr(ref e, _) | ast::StmtSemi(ref e, _) => {
bcx = trans_stmt_semi(bcx, e); bcx = trans_stmt_semi(bcx, &**e);
} }
ast::StmtDecl(d, _) => { ast::StmtDecl(d, _) => {
match d.node { match d.node {
ast::DeclLocal(ref local) => { ast::DeclLocal(ref local) => {
bcx = init_local(bcx, *local); bcx = init_local(bcx, &**local);
if cx.sess().opts.debuginfo == FullDebugInfo { if cx.sess().opts.debuginfo == FullDebugInfo {
debuginfo::create_local_var_metadata(bcx, *local); debuginfo::create_local_var_metadata(bcx, &**local);
} }
} }
ast::DeclItem(i) => trans_item(cx.fcx.ccx, i) ast::DeclItem(ref i) => trans_item(cx.fcx.ccx, &**i)
} }
} }
ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro") ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro")
@ -92,7 +94,7 @@ pub fn trans_block<'a>(bcx: &'a Block<'a>,
fcx.push_ast_cleanup_scope(b.id); fcx.push_ast_cleanup_scope(b.id);
for s in b.stmts.iter() { for s in b.stmts.iter() {
bcx = trans_stmt(bcx, *s); bcx = trans_stmt(bcx, &**s);
} }
if dest != expr::Ignore { if dest != expr::Ignore {
@ -103,8 +105,8 @@ pub fn trans_block<'a>(bcx: &'a Block<'a>,
} }
match b.expr { match b.expr {
Some(e) => { Some(ref e) => {
bcx = expr::trans_into(bcx, e, dest); bcx = expr::trans_into(bcx, &**e, dest);
} }
None => { None => {
assert!(dest == expr::Ignore || bcx.unreachable.get()); assert!(dest == expr::Ignore || bcx.unreachable.get());
@ -120,7 +122,7 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
if_id: ast::NodeId, if_id: ast::NodeId,
cond: &ast::Expr, cond: &ast::Expr,
thn: ast::P<ast::Block>, thn: ast::P<ast::Block>,
els: Option<@ast::Expr>, els: Option<Gc<ast::Expr>>,
dest: expr::Dest) dest: expr::Dest)
-> &'a Block<'a> { -> &'a Block<'a> {
debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})", debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
@ -137,21 +139,21 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
match els { match els {
Some(elexpr) => { Some(elexpr) => {
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx }; let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
trans.visit_expr(elexpr, ()); trans.visit_expr(&*elexpr, ());
} }
None => {} None => {}
} }
// if true { .. } [else { .. }] // if true { .. } [else { .. }]
bcx = trans_block(bcx, thn, dest); bcx = trans_block(bcx, &*thn, dest);
debuginfo::clear_source_location(bcx.fcx); debuginfo::clear_source_location(bcx.fcx);
} else { } else {
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ; let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
trans.visit_block(thn, ()); trans.visit_block(&*thn, ());
match els { match els {
// if false { .. } else { .. } // if false { .. } else { .. }
Some(elexpr) => { Some(elexpr) => {
bcx = expr::trans_into(bcx, elexpr, dest); bcx = expr::trans_into(bcx, &*elexpr, dest);
debuginfo::clear_source_location(bcx.fcx); debuginfo::clear_source_location(bcx.fcx);
} }
@ -165,14 +167,14 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
let name = format!("then-block-{}-", thn.id); let name = format!("then-block-{}-", thn.id);
let then_bcx_in = bcx.fcx.new_id_block(name.as_slice(), thn.id); let then_bcx_in = bcx.fcx.new_id_block(name.as_slice(), thn.id);
let then_bcx_out = trans_block(then_bcx_in, thn, dest); let then_bcx_out = trans_block(then_bcx_in, &*thn, dest);
debuginfo::clear_source_location(bcx.fcx); debuginfo::clear_source_location(bcx.fcx);
let next_bcx; let next_bcx;
match els { match els {
Some(elexpr) => { Some(elexpr) => {
let else_bcx_in = bcx.fcx.new_id_block("else-block", elexpr.id); let else_bcx_in = bcx.fcx.new_id_block("else-block", elexpr.id);
let else_bcx_out = expr::trans_into(else_bcx_in, elexpr, dest); let else_bcx_out = expr::trans_into(else_bcx_in, &*elexpr, dest);
next_bcx = bcx.fcx.join_blocks(if_id, next_bcx = bcx.fcx.join_blocks(if_id,
[then_bcx_out, else_bcx_out]); [then_bcx_out, else_bcx_out]);
CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb); CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb);
@ -319,7 +321,7 @@ pub fn trans_cont<'a>(bcx: &'a Block<'a>,
} }
pub fn trans_ret<'a>(bcx: &'a Block<'a>, pub fn trans_ret<'a>(bcx: &'a Block<'a>,
e: Option<@ast::Expr>) e: Option<Gc<ast::Expr>>)
-> &'a Block<'a> { -> &'a Block<'a> {
let _icx = push_ctxt("trans_ret"); let _icx = push_ctxt("trans_ret");
let fcx = bcx.fcx; let fcx = bcx.fcx;
@ -330,7 +332,7 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
}; };
match e { match e {
Some(x) => { Some(x) => {
bcx = expr::trans_into(bcx, x, dest); bcx = expr::trans_into(bcx, &*x, dest);
} }
_ => {} _ => {}
} }

View File

@ -143,14 +143,14 @@ use middle::ty;
use middle::pat_util; use middle::pat_util;
use util::ppaux; use util::ppaux;
use libc::{c_uint, c_ulonglong, c_longlong};
use std::c_str::{CString, ToCStr}; use std::c_str::{CString, ToCStr};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use libc::{c_uint, c_ulonglong, c_longlong}; use std::gc::Gc;
use std::ptr; use std::ptr;
use std::string::String; use std::rc::{Rc, Weak};
use std::sync::atomics; use std::sync::atomics;
use syntax::codemap::{Span, Pos}; use syntax::codemap::{Span, Pos};
use syntax::{abi, ast, codemap, ast_util, ast_map}; use syntax::{abi, ast, codemap, ast_util, ast_map};
@ -379,7 +379,7 @@ pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) {
let cx = bcx.ccx(); let cx = bcx.ccx();
let def_map = &cx.tcx.def_map; let def_map = &cx.tcx.def_map;
pat_util::pat_bindings(def_map, local.pat, |_, node_id, span, path_ref| { pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path_ref| {
let var_ident = ast_util::path_to_ident(path_ref); let var_ident = ast_util::path_to_ident(path_ref);
let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) { let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
@ -524,7 +524,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
let def_map = &cx.tcx.def_map; let def_map = &cx.tcx.def_map;
let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
pat_util::pat_bindings(def_map, arg.pat, |_, node_id, span, path_ref| { pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path_ref| {
let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) { let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
Some(v) => v, Some(v) => v,
None => { None => {
@ -715,7 +715,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
let file_metadata = file_metadata(cx, loc.file.name.as_slice()); let file_metadata = file_metadata(cx, loc.file.name.as_slice());
let function_type_metadata = unsafe { let function_type_metadata = unsafe {
let fn_signature = get_function_signature(cx, fn_ast_id, fn_decl, param_substs, span); let fn_signature = get_function_signature(cx, fn_ast_id, &*fn_decl, param_substs, span);
llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature) llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
}; };
@ -779,7 +779,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>(); let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>();
populate_scope_map(cx, populate_scope_map(cx,
arg_pats.as_slice(), arg_pats.as_slice(),
top_level_block, &*top_level_block,
fn_metadata, fn_metadata,
&mut *fn_debug_context.scope_map.borrow_mut()); &mut *fn_debug_context.scope_map.borrow_mut());
@ -2519,7 +2519,7 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
// descriptors where necessary. These artificial scopes allow GDB to correctly handle name // descriptors where necessary. These artificial scopes allow GDB to correctly handle name
// shadowing. // shadowing.
fn populate_scope_map(cx: &CrateContext, fn populate_scope_map(cx: &CrateContext,
arg_pats: &[@ast::Pat], arg_pats: &[Gc<ast::Pat>],
fn_entry_block: &ast::Block, fn_entry_block: &ast::Block,
fn_metadata: DISubprogram, fn_metadata: DISubprogram,
scope_map: &mut HashMap<ast::NodeId, DIScope>) { scope_map: &mut HashMap<ast::NodeId, DIScope>) {
@ -2535,7 +2535,7 @@ fn populate_scope_map(cx: &CrateContext,
// Push argument identifiers onto the stack so arguments integrate nicely with variable // Push argument identifiers onto the stack so arguments integrate nicely with variable
// shadowing. // shadowing.
for &arg_pat in arg_pats.iter() { for &arg_pat in arg_pats.iter() {
pat_util::pat_bindings(def_map, arg_pat, |_, _, _, path_ref| { pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path_ref| {
let ident = ast_util::path_to_ident(path_ref); let ident = ast_util::path_to_ident(path_ref);
scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata, ident: Some(ident) }); scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata, ident: Some(ident) });
}) })
@ -2597,19 +2597,21 @@ fn populate_scope_map(cx: &CrateContext,
// The interesting things here are statements and the concluding expression. // The interesting things here are statements and the concluding expression.
for statement in block.stmts.iter() { for statement in block.stmts.iter() {
scope_map.insert(ast_util::stmt_id(*statement), scope_map.insert(ast_util::stmt_id(&**statement),
scope_stack.last().unwrap().scope_metadata); scope_stack.last().unwrap().scope_metadata);
match statement.node { match statement.node {
ast::StmtDecl(decl, _) => walk_decl(cx, decl, scope_stack, scope_map), ast::StmtDecl(ref decl, _) =>
ast::StmtExpr(exp, _) | walk_decl(cx, &**decl, scope_stack, scope_map),
ast::StmtSemi(exp, _) => walk_expr(cx, exp, scope_stack, scope_map), ast::StmtExpr(ref exp, _) |
ast::StmtSemi(ref exp, _) =>
walk_expr(cx, &**exp, scope_stack, scope_map),
ast::StmtMac(..) => () // ignore macros (which should be expanded anyway) ast::StmtMac(..) => () // ignore macros (which should be expanded anyway)
} }
} }
for exp in block.expr.iter() { for exp in block.expr.iter() {
walk_expr(cx, *exp, scope_stack, scope_map); walk_expr(cx, &**exp, scope_stack, scope_map);
} }
} }
@ -2624,7 +2626,7 @@ fn populate_scope_map(cx: &CrateContext,
walk_pattern(cx, local.pat, scope_stack, scope_map); walk_pattern(cx, local.pat, scope_stack, scope_map);
for exp in local.init.iter() { for exp in local.init.iter() {
walk_expr(cx, *exp, scope_stack, scope_map); walk_expr(cx, &**exp, scope_stack, scope_map);
} }
} }
_ => () _ => ()
@ -2632,7 +2634,7 @@ fn populate_scope_map(cx: &CrateContext,
} }
fn walk_pattern(cx: &CrateContext, fn walk_pattern(cx: &CrateContext,
pat: @ast::Pat, pat: Gc<ast::Pat>,
scope_stack: &mut Vec<ScopeStackEntry> , scope_stack: &mut Vec<ScopeStackEntry> ,
scope_map: &mut HashMap<ast::NodeId, DIScope>) { scope_map: &mut HashMap<ast::NodeId, DIScope>) {
@ -2646,7 +2648,7 @@ fn populate_scope_map(cx: &CrateContext,
// Check if this is a binding. If so we need to put it on the scope stack and maybe // Check if this is a binding. If so we need to put it on the scope stack and maybe
// introduce an artificial scope // introduce an artificial scope
if pat_util::pat_is_binding(def_map, pat) { if pat_util::pat_is_binding(def_map, &*pat) {
let ident = ast_util::path_to_ident(path_ref); let ident = ast_util::path_to_ident(path_ref);
@ -2741,25 +2743,25 @@ fn populate_scope_map(cx: &CrateContext,
ast::PatTup(ref sub_pats) => { ast::PatTup(ref sub_pats) => {
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
for &sub_pat in sub_pats.iter() { for sub_pat in sub_pats.iter() {
walk_pattern(cx, sub_pat, scope_stack, scope_map); walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
} }
} }
ast::PatBox(sub_pat) | ast::PatRegion(sub_pat) => { ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
walk_pattern(cx, sub_pat, scope_stack, scope_map); walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
} }
ast::PatLit(exp) => { ast::PatLit(ref exp) => {
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
walk_expr(cx, exp, scope_stack, scope_map); walk_expr(cx, &**exp, scope_stack, scope_map);
} }
ast::PatRange(exp1, exp2) => { ast::PatRange(ref exp1, ref exp2) => {
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
walk_expr(cx, exp1, scope_stack, scope_map); walk_expr(cx, &**exp1, scope_stack, scope_map);
walk_expr(cx, exp2, scope_stack, scope_map); walk_expr(cx, &**exp2, scope_stack, scope_map);
} }
ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => { ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
@ -2798,72 +2800,74 @@ fn populate_scope_map(cx: &CrateContext,
ast::ExprAgain(_) | ast::ExprAgain(_) |
ast::ExprPath(_) => {} ast::ExprPath(_) => {}
ast::ExprVstore(sub_exp, _) | ast::ExprVstore(ref sub_exp, _) |
ast::ExprCast(sub_exp, _) | ast::ExprCast(ref sub_exp, _) |
ast::ExprAddrOf(_, sub_exp) | ast::ExprAddrOf(_, ref sub_exp) |
ast::ExprField(sub_exp, _, _) | ast::ExprField(ref sub_exp, _, _) |
ast::ExprParen(sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map), ast::ExprParen(ref sub_exp) =>
walk_expr(cx, &**sub_exp, scope_stack, scope_map),
ast::ExprBox(place, sub_expr) => { ast::ExprBox(ref place, ref sub_expr) => {
walk_expr(cx, place, scope_stack, scope_map); walk_expr(cx, &**place, scope_stack, scope_map);
walk_expr(cx, sub_expr, scope_stack, scope_map); walk_expr(cx, &**sub_expr, scope_stack, scope_map);
} }
ast::ExprRet(exp_opt) => match exp_opt { ast::ExprRet(exp_opt) => match exp_opt {
Some(sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map), Some(sub_exp) => walk_expr(cx, &*sub_exp, scope_stack, scope_map),
None => () None => ()
}, },
ast::ExprUnary(_, sub_exp) => { ast::ExprUnary(_, ref sub_exp) => {
walk_expr(cx, sub_exp, scope_stack, scope_map); walk_expr(cx, &**sub_exp, scope_stack, scope_map);
} }
ast::ExprAssignOp(_, lhs, rhs) | ast::ExprAssignOp(_, ref lhs, ref rhs) |
ast::ExprIndex(lhs, rhs) | ast::ExprIndex(ref lhs, ref rhs) |
ast::ExprBinary(_, lhs, rhs) => { ast::ExprBinary(_, ref lhs, ref rhs) => {
walk_expr(cx, lhs, scope_stack, scope_map); walk_expr(cx, &**lhs, scope_stack, scope_map);
walk_expr(cx, rhs, scope_stack, scope_map); walk_expr(cx, &**rhs, scope_stack, scope_map);
} }
ast::ExprVec(ref init_expressions) | ast::ExprVec(ref init_expressions) |
ast::ExprTup(ref init_expressions) => { ast::ExprTup(ref init_expressions) => {
for ie in init_expressions.iter() { for ie in init_expressions.iter() {
walk_expr(cx, *ie, scope_stack, scope_map); walk_expr(cx, &**ie, scope_stack, scope_map);
} }
} }
ast::ExprAssign(sub_exp1, sub_exp2) | ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
ast::ExprRepeat(sub_exp1, sub_exp2) => { ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
walk_expr(cx, sub_exp1, scope_stack, scope_map); walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
walk_expr(cx, sub_exp2, scope_stack, scope_map); walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
} }
ast::ExprIf(cond_exp, then_block, ref opt_else_exp) => { ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
walk_expr(cx, cond_exp, scope_stack, scope_map); walk_expr(cx, &**cond_exp, scope_stack, scope_map);
with_new_scope(cx, with_new_scope(cx,
then_block.span, then_block.span,
scope_stack, scope_stack,
scope_map, scope_map,
|cx, scope_stack, scope_map| { |cx, scope_stack, scope_map| {
walk_block(cx, then_block, scope_stack, scope_map); walk_block(cx, &**then_block, scope_stack, scope_map);
}); });
match *opt_else_exp { match *opt_else_exp {
Some(else_exp) => walk_expr(cx, else_exp, scope_stack, scope_map), Some(ref else_exp) =>
walk_expr(cx, &**else_exp, scope_stack, scope_map),
_ => () _ => ()
} }
} }
ast::ExprWhile(cond_exp, loop_body) => { ast::ExprWhile(ref cond_exp, ref loop_body) => {
walk_expr(cx, cond_exp, scope_stack, scope_map); walk_expr(cx, &**cond_exp, scope_stack, scope_map);
with_new_scope(cx, with_new_scope(cx,
loop_body.span, loop_body.span,
scope_stack, scope_stack,
scope_map, scope_map,
|cx, scope_stack, scope_map| { |cx, scope_stack, scope_map| {
walk_block(cx, loop_body, scope_stack, scope_map); walk_block(cx, &**loop_body, scope_stack, scope_map);
}) })
} }
@ -2877,48 +2881,48 @@ fn populate_scope_map(cx: &CrateContext,
Found unexpanded macro."); Found unexpanded macro.");
} }
ast::ExprLoop(block, _) | ast::ExprLoop(ref block, _) |
ast::ExprBlock(block) => { ast::ExprBlock(ref block) => {
with_new_scope(cx, with_new_scope(cx,
block.span, block.span,
scope_stack, scope_stack,
scope_map, scope_map,
|cx, scope_stack, scope_map| { |cx, scope_stack, scope_map| {
walk_block(cx, block, scope_stack, scope_map); walk_block(cx, &**block, scope_stack, scope_map);
}) })
} }
ast::ExprFnBlock(decl, block) | ast::ExprFnBlock(ref decl, ref block) |
ast::ExprProc(decl, block) => { ast::ExprProc(ref decl, ref block) => {
with_new_scope(cx, with_new_scope(cx,
block.span, block.span,
scope_stack, scope_stack,
scope_map, scope_map,
|cx, scope_stack, scope_map| { |cx, scope_stack, scope_map| {
for &ast::Arg { pat: pattern, .. } in decl.inputs.iter() { for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
walk_pattern(cx, pattern, scope_stack, scope_map); walk_pattern(cx, pattern.clone(), scope_stack, scope_map);
} }
walk_block(cx, block, scope_stack, scope_map); walk_block(cx, &**block, scope_stack, scope_map);
}) })
} }
ast::ExprCall(fn_exp, ref args) => { ast::ExprCall(ref fn_exp, ref args) => {
walk_expr(cx, fn_exp, scope_stack, scope_map); walk_expr(cx, &**fn_exp, scope_stack, scope_map);
for arg_exp in args.iter() { for arg_exp in args.iter() {
walk_expr(cx, *arg_exp, scope_stack, scope_map); walk_expr(cx, &**arg_exp, scope_stack, scope_map);
} }
} }
ast::ExprMethodCall(_, _, ref args) => { ast::ExprMethodCall(_, _, ref args) => {
for arg_exp in args.iter() { for arg_exp in args.iter() {
walk_expr(cx, *arg_exp, scope_stack, scope_map); walk_expr(cx, &**arg_exp, scope_stack, scope_map);
} }
} }
ast::ExprMatch(discriminant_exp, ref arms) => { ast::ExprMatch(ref discriminant_exp, ref arms) => {
walk_expr(cx, discriminant_exp, scope_stack, scope_map); walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
// for each arm we have to first walk the pattern as these might introduce new // for each arm we have to first walk the pattern as these might introduce new
// artificial scopes. It should be sufficient to walk only one pattern per arm, as // artificial scopes. It should be sufficient to walk only one pattern per arm, as
@ -2937,21 +2941,21 @@ fn populate_scope_map(cx: &CrateContext,
} }
for guard_exp in arm_ref.guard.iter() { for guard_exp in arm_ref.guard.iter() {
walk_expr(cx, *guard_exp, scope_stack, scope_map) walk_expr(cx, &**guard_exp, scope_stack, scope_map)
} }
walk_expr(cx, arm_ref.body, scope_stack, scope_map); walk_expr(cx, &*arm_ref.body, scope_stack, scope_map);
}) })
} }
} }
ast::ExprStruct(_, ref fields, ref base_exp) => { ast::ExprStruct(_, ref fields, ref base_exp) => {
for &ast::Field { expr: exp, .. } in fields.iter() { for &ast::Field { expr: ref exp, .. } in fields.iter() {
walk_expr(cx, exp, scope_stack, scope_map); walk_expr(cx, &**exp, scope_stack, scope_map);
} }
match *base_exp { match *base_exp {
Some(exp) => walk_expr(cx, exp, scope_stack, scope_map), Some(ref exp) => walk_expr(cx, &**exp, scope_stack, scope_map),
None => () None => ()
} }
} }
@ -2959,13 +2963,13 @@ fn populate_scope_map(cx: &CrateContext,
ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs, ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
outputs: ref outputs, outputs: ref outputs,
.. }) => { .. }) => {
// inputs, outputs: ~[(String, @expr)] // inputs, outputs: ~[(String, Gc<expr>)]
for &(_, exp) in inputs.iter() { for &(_, ref exp) in inputs.iter() {
walk_expr(cx, exp, scope_stack, scope_map); walk_expr(cx, &**exp, scope_stack, scope_map);
} }
for &(_, exp) in outputs.iter() { for &(_, ref exp) in outputs.iter() {
walk_expr(cx, exp, scope_stack, scope_map); walk_expr(cx, &**exp, scope_stack, scope_map);
} }
} }
} }

View File

@ -77,6 +77,8 @@ use syntax::ast;
use syntax::codemap; use syntax::codemap;
use syntax::print::pprust::{expr_to_str}; use syntax::print::pprust::{expr_to_str};
use std::gc::Gc;
// Destinations // Destinations
// These are passed around by the code generating functions to track the // These are passed around by the code generating functions to track the
@ -380,45 +382,53 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
let _icx = push_ctxt("trans_datum_unadjusted"); let _icx = push_ctxt("trans_datum_unadjusted");
match expr.node { match expr.node {
ast::ExprParen(e) => { ast::ExprParen(ref e) => {
trans(bcx, e) trans(bcx, &**e)
} }
ast::ExprPath(_) => { ast::ExprPath(_) => {
trans_def(bcx, expr, bcx.def(expr.id)) trans_def(bcx, expr, bcx.def(expr.id))
} }
ast::ExprField(base, ident, _) => { ast::ExprField(ref base, ident, _) => {
trans_rec_field(bcx, base, ident) trans_rec_field(bcx, &**base, ident)
} }
ast::ExprIndex(base, idx) => { ast::ExprIndex(ref base, ref idx) => {
trans_index(bcx, expr, base, idx) trans_index(bcx, expr, &**base, &**idx)
} }
ast::ExprVstore(contents, ast::ExprVstoreUniq) => { ast::ExprVstore(ref contents, ast::ExprVstoreUniq) => {
fcx.push_ast_cleanup_scope(contents.id); fcx.push_ast_cleanup_scope(contents.id);
let datum = unpack_datum!( let datum = unpack_datum!(
bcx, tvec::trans_uniq_vstore(bcx, expr, contents)); bcx, tvec::trans_uniq_vstore(bcx, expr, &**contents));
bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id); bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
DatumBlock::new(bcx, datum) DatumBlock::new(bcx, datum)
} }
ast::ExprBox(_, contents) => { ast::ExprBox(_, ref contents) => {
// Special case for `box T`. (The other case, for GC, is handled // Special case for `Box<T>` and `Gc<T>`
// in `trans_rvalue_dps_unadjusted`.)
let box_ty = expr_ty(bcx, expr); let box_ty = expr_ty(bcx, expr);
let contents_ty = expr_ty(bcx, contents); let contents_ty = expr_ty(bcx, &**contents);
trans_uniq_expr(bcx, box_ty, contents, contents_ty) match ty::get(box_ty).sty {
ty::ty_uniq(..) => {
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
}
ty::ty_box(..) => {
trans_managed_expr(bcx, box_ty, &**contents, contents_ty)
}
_ => bcx.sess().span_bug(expr.span,
"expected unique or managed box")
}
} }
ast::ExprLit(lit) => trans_immediate_lit(bcx, expr, (*lit).clone()), ast::ExprLit(ref lit) => trans_immediate_lit(bcx, expr, (**lit).clone()),
ast::ExprBinary(op, lhs, rhs) => { ast::ExprBinary(op, ref lhs, ref rhs) => {
trans_binary(bcx, expr, op, lhs, rhs) trans_binary(bcx, expr, op, &**lhs, &**rhs)
} }
ast::ExprUnary(op, x) => { ast::ExprUnary(op, ref x) => {
trans_unary(bcx, expr, op, x) trans_unary(bcx, expr, op, &**x)
} }
ast::ExprAddrOf(_, x) => { ast::ExprAddrOf(_, ref x) => {
trans_addr_of(bcx, expr, x) trans_addr_of(bcx, expr, &**x)
} }
ast::ExprCast(val, _) => { ast::ExprCast(ref val, _) => {
// Datum output mode means this is a scalar cast: // Datum output mode means this is a scalar cast:
trans_imm_cast(bcx, val, expr.id) trans_imm_cast(bcx, &**val, expr.id)
} }
_ => { _ => {
bcx.tcx().sess.span_bug( bcx.tcx().sess.span_bug(
@ -581,8 +591,8 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
} }
match expr.node { match expr.node {
ast::ExprParen(e) => { ast::ExprParen(ref e) => {
trans_into(bcx, e, Ignore) trans_into(bcx, &**e, Ignore)
} }
ast::ExprBreak(label_opt) => { ast::ExprBreak(label_opt) => {
controlflow::trans_break(bcx, expr.id, label_opt) controlflow::trans_break(bcx, expr.id, label_opt)
@ -593,15 +603,15 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
ast::ExprRet(ex) => { ast::ExprRet(ex) => {
controlflow::trans_ret(bcx, ex) controlflow::trans_ret(bcx, ex)
} }
ast::ExprWhile(cond, body) => { ast::ExprWhile(ref cond, ref body) => {
controlflow::trans_while(bcx, expr.id, cond, body) controlflow::trans_while(bcx, expr.id, &**cond, &**body)
} }
ast::ExprLoop(body, _) => { ast::ExprLoop(ref body, _) => {
controlflow::trans_loop(bcx, expr.id, body) controlflow::trans_loop(bcx, expr.id, &**body)
} }
ast::ExprAssign(dst, src) => { ast::ExprAssign(ref dst, ref src) => {
let src_datum = unpack_datum!(bcx, trans(bcx, src)); let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign")); let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
if ty::type_needs_drop(bcx.tcx(), dst_datum.ty) { if ty::type_needs_drop(bcx.tcx(), dst_datum.ty) {
// If there are destructors involved, make sure we // If there are destructors involved, make sure we
@ -628,8 +638,8 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
src_datum.store_to(bcx, dst_datum.val) src_datum.store_to(bcx, dst_datum.val)
} }
} }
ast::ExprAssignOp(op, dst, src) => { ast::ExprAssignOp(op, ref dst, ref src) => {
trans_assign_op(bcx, expr, op, dst, src) trans_assign_op(bcx, expr, op, &**dst, src.clone())
} }
ast::ExprInlineAsm(ref a) => { ast::ExprInlineAsm(ref a) => {
asm::trans_inline_asm(bcx, a) asm::trans_inline_asm(bcx, a)
@ -654,20 +664,20 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
let fcx = bcx.fcx; let fcx = bcx.fcx;
match expr.node { match expr.node {
ast::ExprParen(e) => { ast::ExprParen(ref e) => {
trans_into(bcx, e, dest) trans_into(bcx, &**e, dest)
} }
ast::ExprPath(_) => { ast::ExprPath(_) => {
trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest) trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
} }
ast::ExprIf(cond, thn, els) => { ast::ExprIf(ref cond, ref thn, els) => {
controlflow::trans_if(bcx, expr.id, cond, thn, els, dest) controlflow::trans_if(bcx, expr.id, &**cond, thn.clone(), els, dest)
} }
ast::ExprMatch(discr, ref arms) => { ast::ExprMatch(ref discr, ref arms) => {
_match::trans_match(bcx, expr, discr, arms.as_slice(), dest) _match::trans_match(bcx, expr, &**discr, arms.as_slice(), dest)
} }
ast::ExprBlock(blk) => { ast::ExprBlock(ref blk) => {
controlflow::trans_block(bcx, blk, dest) controlflow::trans_block(bcx, &**blk, dest)
} }
ast::ExprStruct(_, ref fields, base) => { ast::ExprStruct(_, ref fields, base) => {
trans_rec_or_struct(bcx, trans_rec_or_struct(bcx,
@ -679,7 +689,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
} }
ast::ExprTup(ref args) => { ast::ExprTup(ref args) => {
let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr)); let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
let numbered_fields: Vec<(uint, @ast::Expr)> = let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect(); args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
trans_adt(bcx, &*repr, 0, numbered_fields.as_slice(), None, dest) trans_adt(bcx, &*repr, 0, numbered_fields.as_slice(), None, dest)
} }
@ -697,26 +707,26 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
} }
} }
} }
ast::ExprVstore(contents, ast::ExprVstoreSlice) | ast::ExprVstore(ref contents, ast::ExprVstoreSlice) |
ast::ExprVstore(contents, ast::ExprVstoreMutSlice) => { ast::ExprVstore(ref contents, ast::ExprVstoreMutSlice) => {
fcx.push_ast_cleanup_scope(contents.id); fcx.push_ast_cleanup_scope(contents.id);
bcx = tvec::trans_slice_vstore(bcx, expr, contents, dest); bcx = tvec::trans_slice_vstore(bcx, expr, &**contents, dest);
fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id) fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id)
} }
ast::ExprVec(..) | ast::ExprRepeat(..) => { ast::ExprVec(..) | ast::ExprRepeat(..) => {
tvec::trans_fixed_vstore(bcx, expr, expr, dest) tvec::trans_fixed_vstore(bcx, expr, expr, dest)
} }
ast::ExprFnBlock(decl, body) | ast::ExprFnBlock(ref decl, ref body) |
ast::ExprProc(decl, body) => { ast::ExprProc(ref decl, ref body) => {
let expr_ty = expr_ty(bcx, expr); let expr_ty = expr_ty(bcx, expr);
let store = ty::ty_closure_store(expr_ty); let store = ty::ty_closure_store(expr_ty);
debug!("translating block function {} with type {}", debug!("translating block function {} with type {}",
expr_to_str(expr), expr_ty.repr(tcx)); expr_to_str(expr), expr_ty.repr(tcx));
closure::trans_expr_fn(bcx, store, decl, body, expr.id, dest) closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
} }
ast::ExprCall(f, ref args) => { ast::ExprCall(ref f, ref args) => {
if bcx.tcx().is_method_call(expr.id) { if bcx.tcx().is_method_call(expr.id) {
let callee_datum = unpack_datum!(bcx, trans(bcx, f)); let callee_datum = unpack_datum!(bcx, trans(bcx, &**f));
trans_overloaded_call(bcx, trans_overloaded_call(bcx,
expr, expr,
callee_datum, callee_datum,
@ -725,7 +735,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
} else { } else {
callee::trans_call(bcx, callee::trans_call(bcx,
expr, expr,
f, &**f,
callee::ArgExprs(args.as_slice()), callee::ArgExprs(args.as_slice()),
dest) dest)
} }
@ -733,35 +743,35 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
ast::ExprMethodCall(_, _, ref args) => { ast::ExprMethodCall(_, _, ref args) => {
callee::trans_method_call(bcx, callee::trans_method_call(bcx,
expr, expr,
*args.get(0), &**args.get(0),
callee::ArgExprs(args.as_slice()), callee::ArgExprs(args.as_slice()),
dest) dest)
} }
ast::ExprBinary(_, lhs, rhs) => { ast::ExprBinary(_, ref lhs, ref rhs) => {
// if not overloaded, would be RvalueDatumExpr // if not overloaded, would be RvalueDatumExpr
let lhs = unpack_datum!(bcx, trans(bcx, lhs)); let lhs = unpack_datum!(bcx, trans(bcx, &**lhs));
let rhs_datum = unpack_datum!(bcx, trans(bcx, rhs)); let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs));
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs, trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs,
Some((rhs_datum, rhs.id)), Some(dest)).bcx Some((rhs_datum, rhs.id)), Some(dest)).bcx
} }
ast::ExprUnary(_, subexpr) => { ast::ExprUnary(_, ref subexpr) => {
// if not overloaded, would be RvalueDatumExpr // if not overloaded, would be RvalueDatumExpr
let arg = unpack_datum!(bcx, trans(bcx, subexpr)); let arg = unpack_datum!(bcx, trans(bcx, &**subexpr));
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id),
arg, None, Some(dest)).bcx arg, None, Some(dest)).bcx
} }
ast::ExprIndex(base, idx) => { ast::ExprIndex(ref base, ref idx) => {
// if not overloaded, would be RvalueDatumExpr // if not overloaded, would be RvalueDatumExpr
let base = unpack_datum!(bcx, trans(bcx, base)); let base = unpack_datum!(bcx, trans(bcx, &**base));
let idx_datum = unpack_datum!(bcx, trans(bcx, idx)); let idx_datum = unpack_datum!(bcx, trans(bcx, &**idx));
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base, trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base,
Some((idx_datum, idx.id)), Some(dest)).bcx Some((idx_datum, idx.id)), Some(dest)).bcx
} }
ast::ExprCast(val, _) => { ast::ExprCast(ref val, _) => {
// DPS output mode means this is a trait cast: // DPS output mode means this is a trait cast:
match ty::get(node_id_type(bcx, expr.id)).sty { match ty::get(node_id_type(bcx, expr.id)).sty {
ty::ty_trait(..) => { ty::ty_trait(..) => {
let datum = unpack_datum!(bcx, trans(bcx, val)); let datum = unpack_datum!(bcx, trans(bcx, &**val));
meth::trans_trait_cast(bcx, datum, expr.id, dest) meth::trans_trait_cast(bcx, datum, expr.id, dest)
} }
_ => { _ => {
@ -770,13 +780,8 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
} }
} }
} }
ast::ExprAssignOp(op, dst, src) => { ast::ExprAssignOp(op, ref dst, ref src) => {
trans_assign_op(bcx, expr, op, dst, src) trans_assign_op(bcx, expr, op, &**dst, src.clone())
}
ast::ExprBox(_, contents) => {
// Special case for `Gc<T>` for now. The other case, for unique
// pointers, is handled in `trans_rvalue_datum_unadjusted`.
trans_gc(bcx, expr, contents, dest)
} }
_ => { _ => {
bcx.tcx().sess.span_bug( bcx.tcx().sess.span_bug(
@ -975,7 +980,7 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
fn trans_rec_or_struct<'a>( fn trans_rec_or_struct<'a>(
bcx: &'a Block<'a>, bcx: &'a Block<'a>,
fields: &[ast::Field], fields: &[ast::Field],
base: Option<@ast::Expr>, base: Option<Gc<ast::Expr>>,
expr_span: codemap::Span, expr_span: codemap::Span,
id: ast::NodeId, id: ast::NodeId,
dest: Dest) dest: Dest)
@ -1037,7 +1042,7 @@ fn trans_rec_or_struct<'a>(
*/ */
struct StructBaseInfo { struct StructBaseInfo {
/// The base expression; will be evaluated after all explicit fields. /// The base expression; will be evaluated after all explicit fields.
expr: @ast::Expr, expr: Gc<ast::Expr>,
/// The indices of fields to copy paired with their types. /// The indices of fields to copy paired with their types.
fields: Vec<(uint, ty::t)> } fields: Vec<(uint, ty::t)> }
@ -1055,7 +1060,7 @@ fn trans_adt<'a>(
bcx: &'a Block<'a>, bcx: &'a Block<'a>,
repr: &adt::Repr, repr: &adt::Repr,
discr: ty::Disr, discr: ty::Disr,
fields: &[(uint, @ast::Expr)], fields: &[(uint, Gc<ast::Expr>)],
optbase: Option<StructBaseInfo>, optbase: Option<StructBaseInfo>,
dest: Dest) dest: Dest)
-> &'a Block<'a> { -> &'a Block<'a> {
@ -1064,12 +1069,12 @@ fn trans_adt<'a>(
let mut bcx = bcx; let mut bcx = bcx;
let addr = match dest { let addr = match dest {
Ignore => { Ignore => {
for &(_i, e) in fields.iter() { for &(_i, ref e) in fields.iter() {
bcx = trans_into(bcx, e, Ignore); bcx = trans_into(bcx, &**e, Ignore);
} }
for sbi in optbase.iter() { for sbi in optbase.iter() {
// FIXME #7261: this moves entire base, not just certain fields // FIXME #7261: this moves entire base, not just certain fields
bcx = trans_into(bcx, sbi.expr, Ignore); bcx = trans_into(bcx, &*sbi.expr, Ignore);
} }
return bcx; return bcx;
} }
@ -1082,10 +1087,10 @@ fn trans_adt<'a>(
adt::trans_start_init(bcx, repr, addr, discr); adt::trans_start_init(bcx, repr, addr, discr);
for &(i, e) in fields.iter() { for &(i, ref e) in fields.iter() {
let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i); let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
let e_ty = expr_ty_adjusted(bcx, e); let e_ty = expr_ty_adjusted(bcx, &**e);
bcx = trans_into(bcx, e, SaveIn(dest)); bcx = trans_into(bcx, &**e, SaveIn(dest));
fcx.schedule_drop_mem(cleanup::CustomScope(custom_cleanup_scope), fcx.schedule_drop_mem(cleanup::CustomScope(custom_cleanup_scope),
dest, e_ty); dest, e_ty);
} }
@ -1093,7 +1098,7 @@ fn trans_adt<'a>(
for base in optbase.iter() { for base in optbase.iter() {
// FIXME #6573: is it sound to use the destination's repr on the base? // FIXME #6573: is it sound to use the destination's repr on the base?
// And, would it ever be reasonable to be here with discr != 0? // And, would it ever be reasonable to be here with discr != 0?
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base.expr, "base")); let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
for &(i, t) in base.fields.iter() { for &(i, t) in base.fields.iter() {
let datum = base_datum.get_element( let datum = base_datum.get_element(
t, t,
@ -1242,31 +1247,6 @@ fn trans_addr_of<'a>(bcx: &'a Block<'a>,
return immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock(); return immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock();
} }
fn trans_gc<'a>(mut bcx: &'a Block<'a>,
expr: &ast::Expr,
contents: &ast::Expr,
dest: Dest)
-> &'a Block<'a> {
let contents_ty = expr_ty(bcx, contents);
let box_ty = ty::mk_box(bcx.tcx(), contents_ty);
let contents_datum = unpack_datum!(bcx, trans_managed_expr(bcx,
box_ty,
contents,
contents_ty));
match dest {
Ignore => bcx,
SaveIn(addr) => {
let expr_ty = expr_ty(bcx, expr);
let repr = adt::represent_type(bcx.ccx(), expr_ty);
adt::trans_start_init(bcx, &*repr, addr, 0);
let field_dest = adt::trans_field_ptr(bcx, &*repr, addr, 0, 0);
contents_datum.store_to(bcx, field_dest)
}
}
}
// Important to get types for both lhs and rhs, because one might be _|_ // Important to get types for both lhs and rhs, because one might be _|_
// and the other not. // and the other not.
fn trans_eager_binop<'a>( fn trans_eager_binop<'a>(
@ -1480,16 +1460,16 @@ fn trans_overloaded_call<'a>(
mut bcx: &'a Block<'a>, mut bcx: &'a Block<'a>,
expr: &ast::Expr, expr: &ast::Expr,
callee: Datum<Expr>, callee: Datum<Expr>,
args: &[@ast::Expr], args: &[Gc<ast::Expr>],
dest: Option<Dest>) dest: Option<Dest>)
-> &'a Block<'a> { -> &'a Block<'a> {
// Evaluate and tuple the arguments. // Evaluate and tuple the arguments.
let tuple_type = ty::mk_tup(bcx.tcx(), let tuple_type = ty::mk_tup(bcx.tcx(),
args.iter() args.iter()
.map(|e| expr_ty(bcx, *e)) .map(|e| expr_ty(bcx, &**e))
.collect()); .collect());
let repr = adt::represent_type(bcx.ccx(), tuple_type); let repr = adt::represent_type(bcx.ccx(), tuple_type);
let numbered_fields: Vec<(uint, @ast::Expr)> = let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect(); args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
let argument_scope = bcx.fcx.push_custom_cleanup_scope(); let argument_scope = bcx.fcx.push_custom_cleanup_scope();
let tuple_datum = let tuple_datum =
@ -1701,7 +1681,7 @@ fn trans_assign_op<'a>(
expr: &ast::Expr, expr: &ast::Expr,
op: ast::BinOp, op: ast::BinOp,
dst: &ast::Expr, dst: &ast::Expr,
src: @ast::Expr) src: Gc<ast::Expr>)
-> &'a Block<'a> { -> &'a Block<'a> {
let _icx = push_ctxt("trans_assign_op"); let _icx = push_ctxt("trans_assign_op");
let mut bcx = bcx; let mut bcx = bcx;
@ -1718,7 +1698,7 @@ fn trans_assign_op<'a>(
let dst = Load(bcx, dst_datum.val); let dst = Load(bcx, dst_datum.val);
// Evaluate RHS // Evaluate RHS
let rhs_datum = unpack_datum!(bcx, trans(bcx, src)); let rhs_datum = unpack_datum!(bcx, trans(bcx, &*src));
let rhs_ty = rhs_datum.ty; let rhs_ty = rhs_datum.ty;
let rhs = rhs_datum.to_llscalarish(bcx); let rhs = rhs_datum.to_llscalarish(bcx);

View File

@ -443,8 +443,8 @@ pub fn trans_native_call<'a>(
pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) { pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
let _icx = push_ctxt("foreign::trans_foreign_mod"); let _icx = push_ctxt("foreign::trans_foreign_mod");
for &foreign_item in foreign_mod.items.iter() { for foreign_item in foreign_mod.items.iter() {
let lname = link_name(foreign_item); let lname = link_name(&**foreign_item);
match foreign_item.node { match foreign_item.node {
ast::ForeignItemFn(..) => { ast::ForeignItemFn(..) => {

View File

@ -51,7 +51,7 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
ccx.external_srcs.borrow_mut().insert(item.id, fn_id); ccx.external_srcs.borrow_mut().insert(item.id, fn_id);
ccx.stats.n_inlines.set(ccx.stats.n_inlines.get() + 1); ccx.stats.n_inlines.set(ccx.stats.n_inlines.get() + 1);
trans_item(ccx, item); trans_item(ccx, &*item);
// We're bringing an external global into this crate, but we don't // We're bringing an external global into this crate, but we don't
// want to create two copies of the global. If we do this, then if // want to create two copies of the global. If we do this, then if
@ -107,7 +107,7 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
_ => ccx.sess().bug("maybe_instantiate_inline: item has a \ _ => ccx.sess().bug("maybe_instantiate_inline: item has a \
non-enum, non-struct parent") non-enum, non-struct parent")
} }
trans_item(ccx, item); trans_item(ccx, &*item);
local_def(my_id) local_def(my_id)
} }
csearch::found_parent(_, _) => { csearch::found_parent(_, _) => {
@ -131,7 +131,7 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
if num_type_params == 0 { if num_type_params == 0 {
let llfn = get_item_val(ccx, mth.id); let llfn = get_item_val(ccx, mth.id);
trans_fn(ccx, mth.decl, mth.body, llfn, trans_fn(ccx, &*mth.decl, &*mth.body, llfn,
&param_substs::empty(), mth.id, []); &param_substs::empty(), mth.id, []);
} }
local_def(mth.id) local_def(mth.id)

View File

@ -35,6 +35,7 @@ use util::common::indenter;
use util::ppaux::Repr; use util::ppaux::Repr;
use std::c_str::ToCStr; use std::c_str::ToCStr;
use std::gc::Gc;
use syntax::abi::Rust; use syntax::abi::Rust;
use syntax::parse::token; use syntax::parse::token;
use syntax::{ast, ast_map, visit}; use syntax::{ast, ast_map, visit};
@ -47,7 +48,7 @@ see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
*/ */
pub fn trans_impl(ccx: &CrateContext, pub fn trans_impl(ccx: &CrateContext,
name: ast::Ident, name: ast::Ident,
methods: &[@ast::Method], methods: &[Gc<ast::Method>],
generics: &ast::Generics, generics: &ast::Generics,
id: ast::NodeId) { id: ast::NodeId) {
let _icx = push_ctxt("meth::trans_impl"); let _icx = push_ctxt("meth::trans_impl");
@ -60,18 +61,18 @@ pub fn trans_impl(ccx: &CrateContext,
if !generics.ty_params.is_empty() { if !generics.ty_params.is_empty() {
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
for method in methods.iter() { for method in methods.iter() {
visit::walk_method_helper(&mut v, *method, ()); visit::walk_method_helper(&mut v, &**method, ());
} }
return; return;
} }
for method in methods.iter() { for method in methods.iter() {
if method.generics.ty_params.len() == 0u { if method.generics.ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id); let llfn = get_item_val(ccx, method.id);
trans_fn(ccx, method.decl, method.body, trans_fn(ccx, &*method.decl, &*method.body,
llfn, &param_substs::empty(), method.id, []); llfn, &param_substs::empty(), method.id, []);
} else { } else {
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
visit::walk_method_helper(&mut v, *method, ()); visit::walk_method_helper(&mut v, &**method, ());
} }
} }
} }

View File

@ -201,12 +201,12 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast_map::NodeItem(i) => { ast_map::NodeItem(i) => {
match *i { match *i {
ast::Item { ast::Item {
node: ast::ItemFn(decl, _, _, _, body), node: ast::ItemFn(ref decl, _, _, _, ref body),
.. ..
} => { } => {
let d = mk_lldecl(); let d = mk_lldecl();
set_llvm_fn_attrs(i.attrs.as_slice(), d); set_llvm_fn_attrs(i.attrs.as_slice(), d);
trans_fn(ccx, decl, body, d, &psubsts, fn_id.node, []); trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, []);
d d
} }
_ => { _ => {
@ -215,12 +215,12 @@ pub fn monomorphic_fn(ccx: &CrateContext,
} }
} }
ast_map::NodeForeignItem(i) => { ast_map::NodeForeignItem(i) => {
let simple = intrinsic::get_simple_intrinsic(ccx, i); let simple = intrinsic::get_simple_intrinsic(ccx, &*i);
match simple { match simple {
Some(decl) => decl, Some(decl) => decl,
None => { None => {
let d = mk_lldecl(); let d = mk_lldecl();
intrinsic::trans_intrinsic(ccx, d, i, &psubsts, ref_id); intrinsic::trans_intrinsic(ccx, d, &*i, &psubsts, ref_id);
d d
} }
} }
@ -235,7 +235,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast::TupleVariantKind(ref args) => { ast::TupleVariantKind(ref args) => {
trans_enum_variant(ccx, trans_enum_variant(ccx,
parent, parent,
v, &*v,
args.as_slice(), args.as_slice(),
this_tv.disr_val, this_tv.disr_val,
&psubsts, &psubsts,
@ -249,7 +249,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast_map::NodeMethod(mth) => { ast_map::NodeMethod(mth) => {
let d = mk_lldecl(); let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d); set_llvm_fn_attrs(mth.attrs.as_slice(), d);
trans_fn(ccx, mth.decl, mth.body, d, &psubsts, mth.id, []); trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
d d
} }
ast_map::NodeTraitMethod(method) => { ast_map::NodeTraitMethod(method) => {
@ -257,7 +257,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast::Provided(mth) => { ast::Provided(mth) => {
let d = mk_lldecl(); let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d); set_llvm_fn_attrs(mth.attrs.as_slice(), d);
trans_fn(ccx, mth.decl, mth.body, d, &psubsts, mth.id, []); trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
d d
} }
_ => { _ => {

View File

@ -351,7 +351,7 @@ pub fn write_content<'a>(
match dest { match dest {
Ignore => { Ignore => {
for element in elements.iter() { for element in elements.iter() {
bcx = expr::trans_into(bcx, *element, Ignore); bcx = expr::trans_into(bcx, &**element, Ignore);
} }
} }
@ -361,7 +361,7 @@ pub fn write_content<'a>(
let lleltptr = GEPi(bcx, lldest, [i]); let lleltptr = GEPi(bcx, lldest, [i]);
debug!("writing index {:?} with lleltptr={:?}", debug!("writing index {:?} with lleltptr={:?}",
i, bcx.val_to_str(lleltptr)); i, bcx.val_to_str(lleltptr));
bcx = expr::trans_into(bcx, *element, bcx = expr::trans_into(bcx, &**element,
SaveIn(lleltptr)); SaveIn(lleltptr));
fcx.schedule_drop_mem( fcx.schedule_drop_mem(
cleanup::CustomScope(temp_scope), cleanup::CustomScope(temp_scope),
@ -373,13 +373,13 @@ pub fn write_content<'a>(
} }
return bcx; return bcx;
} }
ast::ExprRepeat(element, count_expr) => { ast::ExprRepeat(ref element, ref count_expr) => {
match dest { match dest {
Ignore => { Ignore => {
return expr::trans_into(bcx, element, Ignore); return expr::trans_into(bcx, &**element, Ignore);
} }
SaveIn(lldest) => { SaveIn(lldest) => {
let count = ty::eval_repeat_count(bcx.tcx(), count_expr); let count = ty::eval_repeat_count(bcx.tcx(), &**count_expr);
if count == 0 { if count == 0 {
return bcx; return bcx;
} }
@ -389,7 +389,7 @@ pub fn write_content<'a>(
// this can only happen as a result of OOM. So we just skip out on the // this can only happen as a result of OOM. So we just skip out on the
// cleanup since things would *probably* be broken at that point anyways. // cleanup since things would *probably* be broken at that point anyways.
let elem = unpack_datum!(bcx, expr::trans(bcx, element)); let elem = unpack_datum!(bcx, expr::trans(bcx, &**element));
assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty)); assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty));
let bcx = iter_vec_loop(bcx, lldest, vt, let bcx = iter_vec_loop(bcx, lldest, vt,
@ -442,8 +442,8 @@ pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint {
} }
}, },
ast::ExprVec(ref es) => es.len(), ast::ExprVec(ref es) => es.len(),
ast::ExprRepeat(_, count_expr) => { ast::ExprRepeat(_, ref count_expr) => {
ty::eval_repeat_count(bcx.tcx(), count_expr) ty::eval_repeat_count(bcx.tcx(), &**count_expr)
} }
_ => bcx.tcx().sess.span_bug(content_expr.span, _ => bcx.tcx().sess.span_bug(content_expr.span,
"unexpected vec content") "unexpected vec content")

View File

@ -18,7 +18,7 @@ use middle::lint;
use middle::const_eval; use middle::const_eval;
use middle::def; use middle::def;
use middle::dependency_format; use middle::dependency_format;
use middle::lang_items::{ExchangeHeapLangItem, OpaqueStructLangItem}; use middle::lang_items::OpaqueStructLangItem;
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem}; use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
use middle::freevars; use middle::freevars;
use middle::resolve; use middle::resolve;
@ -42,6 +42,7 @@ use std::cmp;
use std::fmt::Show; use std::fmt::Show;
use std::fmt; use std::fmt;
use std::hash::{Hash, sip, Writer}; use std::hash::{Hash, sip, Writer};
use std::gc::Gc;
use std::iter::AdditiveIterator; use std::iter::AdditiveIterator;
use std::mem; use std::mem;
use std::ops; use std::ops;
@ -348,8 +349,8 @@ pub struct ctxt {
/// These two caches are used by const_eval when decoding external statics /// These two caches are used by const_eval when decoding external statics
/// and variants that are found. /// and variants that are found.
pub extern_const_statics: RefCell<DefIdMap<Option<@ast::Expr>>>, pub extern_const_statics: RefCell<DefIdMap<Option<Gc<ast::Expr>>>>,
pub extern_const_variants: RefCell<DefIdMap<Option<@ast::Expr>>>, pub extern_const_variants: RefCell<DefIdMap<Option<Gc<ast::Expr>>>>,
pub method_map: typeck::MethodMap, pub method_map: typeck::MethodMap,
pub vtable_map: typeck::vtable_map, pub vtable_map: typeck::vtable_map,
@ -3108,21 +3109,21 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
} }
ast::ExprBox(place, _) => { ast::ExprBox(place, _) => {
// Special case `Box<T>` for now: // Special case `Box<T>`/`Gc<T>` for now:
let definition = match tcx.def_map.borrow().find(&place.id) { let definition = match tcx.def_map.borrow().find(&place.id) {
Some(&def) => def, Some(&def) => def,
None => fail!("no def for place"), None => fail!("no def for place"),
}; };
let def_id = definition.def_id(); let def_id = definition.def_id();
match tcx.lang_items.items.get(ExchangeHeapLangItem as uint) { if tcx.lang_items.exchange_heap() == Some(def_id) ||
&Some(item_def_id) if def_id == item_def_id => { tcx.lang_items.managed_heap() == Some(def_id) {
RvalueDatumExpr RvalueDatumExpr
} } else {
&Some(_) | &None => RvalueDpsExpr, RvalueDpsExpr
} }
} }
ast::ExprParen(e) => expr_kind(tcx, e), ast::ExprParen(ref e) => expr_kind(tcx, &**e),
ast::ExprMac(..) => { ast::ExprMac(..) => {
tcx.sess.span_bug( tcx.sess.span_bug(
@ -3181,7 +3182,7 @@ pub fn ty_sort_str(cx: &ctxt, t: t) -> String {
} }
ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)), ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
ty_box(_) => "@-ptr".to_string(), ty_box(_) => "Gc-ptr".to_string(),
ty_uniq(_) => "box".to_string(), ty_uniq(_) => "box".to_string(),
ty_vec(_, _) => "vector".to_string(), ty_vec(_, _) => "vector".to_string(),
ty_ptr(_) => "*-ptr".to_string(), ty_ptr(_) => "*-ptr".to_string(),
@ -3740,7 +3741,7 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo>>> {
}; };
match variant.node.disr_expr { match variant.node.disr_expr {
Some(e) => match const_eval::eval_const_expr_partial(cx, e) { Some(ref e) => match const_eval::eval_const_expr_partial(cx, &**e) {
Ok(const_eval::const_int(val)) => { Ok(const_eval::const_int(val)) => {
discriminant = val as Disr discriminant = val as Disr
} }
@ -3763,7 +3764,7 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo>>> {
}; };
last_discriminant = Some(discriminant); last_discriminant = Some(discriminant);
Rc::new(VariantInfo::from_ast_variant(cx, variant, Rc::new(VariantInfo::from_ast_variant(cx, &*variant,
discriminant)) discriminant))
}).collect()) }).collect())
} }

View File

@ -230,7 +230,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
} }
let tps = path.segments.iter().flat_map(|s| s.types.iter()) let tps = path.segments.iter().flat_map(|s| s.types.iter())
.map(|&a_t| ast_ty_to_ty(this, rscope, a_t)) .map(|a_t| ast_ty_to_ty(this, rscope, &**a_t))
.collect(); .collect();
let mut substs = subst::Substs { let mut substs = subst::Substs {
@ -451,6 +451,53 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
supplied to `Box<T>`"); supplied to `Box<T>`");
Some(ty::mk_err()) Some(ty::mk_err())
} }
def::DefTy(did) | def::DefStruct(did)
if Some(did) == this.tcx().lang_items.gc() => {
if path.segments
.iter()
.flat_map(|s| s.types.iter())
.count() > 1 {
this.tcx()
.sess
.span_err(path.span,
"`Gc` has only one type parameter")
}
for inner_ast_type in path.segments
.iter()
.flat_map(|s| s.types.iter()) {
let mt = ast::MutTy {
ty: *inner_ast_type,
mutbl: ast::MutImmutable,
};
return Some(mk_pointer(this,
rscope,
&mt,
Box,
|typ| {
match ty::get(typ).sty {
ty::ty_str => {
this.tcx()
.sess
.span_err(path.span,
"`Gc<str>` is not a type");
ty::mk_err()
}
ty::ty_vec(_, None) => {
this.tcx()
.sess
.span_err(path.span,
"`Gc<[T]>` is not a type");
ty::mk_err()
}
_ => ty::mk_box(this.tcx(), typ),
}
}))
}
this.tcx().sess.span_bug(path.span,
"not enough type parameters \
supplied to `Gc<T>`")
}
_ => None _ => None
} }
} }
@ -485,12 +532,12 @@ pub fn trait_ref_for_unboxed_function<AC:AstConv,
.inputs .inputs
.iter() .iter()
.map(|input| { .map(|input| {
ast_ty_to_ty(this, rscope, input.ty) ast_ty_to_ty(this, rscope, &*input.ty)
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let input_tuple = ty::mk_tup(this.tcx(), input_types); let input_tuple = ty::mk_tup(this.tcx(), input_types);
let output_type = ast_ty_to_ty(this, let output_type = ast_ty_to_ty(this,
rscope, rscope,
unboxed_function.decl.output); &*unboxed_function.decl.output);
let substs = subst::Substs { let substs = subst::Substs {
self_ty: None, self_ty: None,
tps: vec!(input_tuple, output_type), tps: vec!(input_tuple, output_type),
@ -517,8 +564,8 @@ fn mk_pointer<AC:AstConv,
debug!("mk_pointer(ptr_ty={:?})", ptr_ty); debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
match a_seq_ty.ty.node { match a_seq_ty.ty.node {
ast::TyVec(ty) => { ast::TyVec(ref ty) => {
let mut mt = ast_ty_to_mt(this, rscope, ty); let mut mt = ast_ty_to_mt(this, rscope, &**ty);
if a_seq_ty.mutbl == ast::MutMutable { if a_seq_ty.mutbl == ast::MutMutable {
mt.mutbl = ast::MutMutable; mt.mutbl = ast::MutMutable;
} }
@ -543,7 +590,7 @@ fn mk_pointer<AC:AstConv,
substs substs
} = trait_ref_for_unboxed_function(this, } = trait_ref_for_unboxed_function(this,
rscope, rscope,
*unboxed_function); &**unboxed_function);
return ty::mk_trait(this.tcx(), return ty::mk_trait(this.tcx(),
def_id, def_id,
substs, substs,
@ -603,7 +650,7 @@ fn mk_pointer<AC:AstConv,
_ => {} _ => {}
} }
constr(ast_ty_to_ty(this, rscope, a_seq_ty.ty)) constr(ast_ty_to_ty(this, rscope, &*a_seq_ty.ty))
} }
// Parses the programmer's textual representation of a type into our // Parses the programmer's textual representation of a type into our
@ -643,12 +690,12 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
ast::TyVec(ty) => { ast::TyVec(ty) => {
tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type"); tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
// return /something/ so they can at least get more errors // return /something/ so they can at least get more errors
let vec_ty = ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), None); let vec_ty = ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, &*ty), None);
ty::mk_uniq(tcx, vec_ty) ty::mk_uniq(tcx, vec_ty)
} }
ast::TyPtr(ref mt) => { ast::TyPtr(ref mt) => {
ty::mk_ptr(tcx, ty::mt { ty::mk_ptr(tcx, ty::mt {
ty: ast_ty_to_ty(this, rscope, mt.ty), ty: ast_ty_to_ty(this, rscope, &*mt.ty),
mutbl: mt.mutbl mutbl: mt.mutbl
}) })
} }
@ -660,7 +707,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
} }
ast::TyTup(ref fields) => { ast::TyTup(ref fields) => {
let flds = fields.iter() let flds = fields.iter()
.map(|&t| ast_ty_to_ty(this, rscope, t)) .map(|t| ast_ty_to_ty(this, rscope, &**t))
.collect(); .collect();
ty::mk_tup(tcx, flds) ty::mk_tup(tcx, flds)
} }
@ -670,7 +717,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
"variadic function must have C calling convention"); "variadic function must have C calling convention");
} }
ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.fn_style, ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.fn_style,
bf.abi, bf.decl)) bf.abi, &*bf.decl))
} }
ast::TyClosure(ref f, ref region) => { ast::TyClosure(ref f, ref region) => {
@ -694,7 +741,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
f.onceness, f.onceness,
bounds, bounds,
store, store,
f.decl, &*f.decl,
None); None);
ty::mk_closure(tcx, fn_decl) ty::mk_closure(tcx, fn_decl)
} }
@ -712,7 +759,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
f.onceness, f.onceness,
bounds, bounds,
ty::UniqTraitStore, ty::UniqTraitStore,
f.decl, &*f.decl,
None); None);
ty::mk_closure(tcx, fn_decl) ty::mk_closure(tcx, fn_decl)
} }
@ -783,14 +830,14 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
} }
} }
ast::TyFixedLengthVec(ty, e) => { ast::TyFixedLengthVec(ty, e) => {
match const_eval::eval_const_expr_partial(tcx, e) { match const_eval::eval_const_expr_partial(tcx, &*e) {
Ok(ref r) => { Ok(ref r) => {
match *r { match *r {
const_eval::const_int(i) => const_eval::const_int(i) =>
ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, &*ty),
Some(i as uint)), Some(i as uint)),
const_eval::const_uint(i) => const_eval::const_uint(i) =>
ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, ty), ty::mk_vec(tcx, ast_ty_to_mt(this, rscope, &*ty),
Some(i as uint)), Some(i as uint)),
_ => { _ => {
tcx.sess.span_fatal( tcx.sess.span_fatal(
@ -829,7 +876,7 @@ pub fn ty_of_arg<AC: AstConv, RS: RegionScope>(this: &AC, rscope: &RS, a: &ast::
match a.ty.node { match a.ty.node {
ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(), ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
ast::TyInfer => this.ty_infer(a.ty.span), ast::TyInfer => this.ty_infer(a.ty.span),
_ => ast_ty_to_ty(this, rscope, a.ty), _ => ast_ty_to_ty(this, rscope, &*a.ty),
} }
} }
@ -900,7 +947,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
let output_ty = match decl.output.node { let output_ty = match decl.output.node {
ast::TyInfer => this.ty_infer(decl.output.span), ast::TyInfer => this.ty_infer(decl.output.span),
_ => ast_ty_to_ty(this, &rb, decl.output) _ => ast_ty_to_ty(this, &rb, &*decl.output)
}; };
return ty::BareFnTy { return ty::BareFnTy {
@ -949,7 +996,7 @@ pub fn ty_of_closure<AC:AstConv>(
let output_ty = match decl.output.node { let output_ty = match decl.output.node {
ast::TyInfer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(), ast::TyInfer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(),
ast::TyInfer => this.ty_infer(decl.output.span), ast::TyInfer => this.ty_infer(decl.output.span),
_ => ast_ty_to_ty(this, &rb, decl.output) _ => ast_ty_to_ty(this, &rb, &*decl.output)
}; };
ty::ClosureTy { ty::ClosureTy {

View File

@ -23,6 +23,7 @@ use middle::typeck::infer;
use middle::typeck::require_same_types; use middle::typeck::require_same_types;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::gc::Gc;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
use syntax::parse::token; use syntax::parse::token;
@ -43,10 +44,10 @@ pub fn check_match(fcx: &FnCtxt,
for arm in arms.iter() { for arm in arms.iter() {
let mut pcx = pat_ctxt { let mut pcx = pat_ctxt {
fcx: fcx, fcx: fcx,
map: pat_id_map(&tcx.def_map, *arm.pats.get(0)), map: pat_id_map(&tcx.def_map, &**arm.pats.get(0)),
}; };
for p in arm.pats.iter() { check_pat(&mut pcx, *p, discrim_ty);} for p in arm.pats.iter() { check_pat(&mut pcx, &**p, discrim_ty);}
} }
// The result of the match is the common supertype of all the // The result of the match is the common supertype of all the
@ -64,9 +65,9 @@ pub fn check_match(fcx: &FnCtxt,
let mut guard_err = false; let mut guard_err = false;
let mut guard_bot = false; let mut guard_bot = false;
match arm.guard { match arm.guard {
Some(e) => { Some(ref e) => {
check_expr_has_type(fcx, e, ty::mk_bool()); check_expr_has_type(fcx, &**e, ty::mk_bool());
let e_ty = fcx.expr_ty(e); let e_ty = fcx.expr_ty(&**e);
if ty::type_is_error(e_ty) { if ty::type_is_error(e_ty) {
guard_err = true; guard_err = true;
} }
@ -76,7 +77,7 @@ pub fn check_match(fcx: &FnCtxt,
}, },
None => () None => ()
} }
check_expr(fcx, arm.body); check_expr(fcx, &*arm.body);
let bty = fcx.node_ty(arm.body.id); let bty = fcx.node_ty(arm.body.id);
saw_err = saw_err || ty::type_is_error(bty); saw_err = saw_err || ty::type_is_error(bty);
if guard_err { if guard_err {
@ -111,7 +112,7 @@ pub struct pat_ctxt<'a> {
} }
pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path, pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
subpats: &Option<Vec<@ast::Pat>>, expected: ty::t) { subpats: &Option<Vec<Gc<ast::Pat>>>, expected: ty::t) {
// Typecheck the path. // Typecheck the path.
let fcx = pcx.fcx; let fcx = pcx.fcx;
@ -269,7 +270,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
if !error_happened { if !error_happened {
for pats in subpats.iter() { for pats in subpats.iter() {
for (subpat, arg_ty) in pats.iter().zip(arg_types.iter()) { for (subpat, arg_ty) in pats.iter().zip(arg_types.iter()) {
check_pat(pcx, *subpat, *arg_ty); check_pat(pcx, &**subpat, *arg_ty);
} }
} }
} }
@ -286,7 +287,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
if error_happened { if error_happened {
for pats in subpats.iter() { for pats in subpats.iter() {
for pat in pats.iter() { for pat in pats.iter() {
check_pat(pcx, *pat, ty::mk_err()); check_pat(pcx, &**pat, ty::mk_err());
} }
} }
} }
@ -331,13 +332,13 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
class_id, class_id,
class_field.id, class_field.id,
substitutions); substitutions);
check_pat(pcx, field.pat, field_type); check_pat(pcx, &*field.pat, field_type);
found_fields.insert(index); found_fields.insert(index);
} }
None => { None => {
// Check the pattern anyway, so that attempts to look // Check the pattern anyway, so that attempts to look
// up its type won't fail // up its type won't fail
check_pat(pcx, field.pat, ty::mk_err()); check_pat(pcx, &*field.pat, ty::mk_err());
tcx.sess.span_err(span, tcx.sess.span_err(span,
format!("struct `{}` does not have a field named `{}`", format!("struct `{}` does not have a field named `{}`",
ty::item_path_str(tcx, class_id), ty::item_path_str(tcx, class_id),
@ -441,17 +442,17 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
ast::PatWild | ast::PatWildMulti => { ast::PatWild | ast::PatWildMulti => {
fcx.write_ty(pat.id, expected); fcx.write_ty(pat.id, expected);
} }
ast::PatLit(lt) => { ast::PatLit(ref lt) => {
check_expr_has_type(fcx, lt, expected); check_expr_has_type(fcx, &**lt, expected);
fcx.write_ty(pat.id, fcx.expr_ty(lt)); fcx.write_ty(pat.id, fcx.expr_ty(&**lt));
} }
ast::PatRange(begin, end) => { ast::PatRange(ref begin, ref end) => {
check_expr_has_type(fcx, begin, expected); check_expr_has_type(fcx, &**begin, expected);
check_expr_has_type(fcx, end, expected); check_expr_has_type(fcx, &**end, expected);
let b_ty = let b_ty =
fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(begin)); fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(&**begin));
let e_ty = let e_ty =
fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(end)); fcx.infcx().resolve_type_vars_if_possible(fcx.expr_ty(&**end));
debug!("pat_range beginning type: {:?}", b_ty); debug!("pat_range beginning type: {:?}", b_ty);
debug!("pat_range ending type: {:?}", e_ty); debug!("pat_range ending type: {:?}", e_ty);
if !require_same_types( if !require_same_types(
@ -463,7 +464,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
tcx.sess.span_err(pat.span, tcx.sess.span_err(pat.span,
"only char and numeric types are allowed in range"); "only char and numeric types are allowed in range");
} else { } else {
match valid_range_bounds(fcx.ccx, begin, end) { match valid_range_bounds(fcx.ccx, &**begin, &**end) {
Some(false) => { Some(false) => {
tcx.sess.span_err(begin.span, tcx.sess.span_err(begin.span,
"lower range bound must be less than upper"); "lower range bound must be less than upper");
@ -516,7 +517,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
debug!("(checking match) writing type for pat id {}", pat.id); debug!("(checking match) writing type for pat id {}", pat.id);
match sub { match sub {
Some(p) => check_pat(pcx, p, expected), Some(ref p) => check_pat(pcx, &**p, expected),
_ => () _ => ()
} }
} }
@ -593,13 +594,13 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
match *s { match *s {
ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => { ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
for (i, elt) in elts.iter().enumerate() { for (i, elt) in elts.iter().enumerate() {
check_pat(pcx, *elt, *ex_elts.get(i)); check_pat(pcx, &**elt, *ex_elts.get(i));
} }
fcx.write_ty(pat.id, expected); fcx.write_ty(pat.id, expected);
} }
_ => { _ => {
for elt in elts.iter() { for elt in elts.iter() {
check_pat(pcx, *elt, ty::mk_err()); check_pat(pcx, &**elt, ty::mk_err());
} }
// use terr_tuple_size if both types are tuples // use terr_tuple_size if both types are tuples
let type_error = match *s { let type_error = match *s {
@ -627,11 +628,11 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
} }
} }
} }
ast::PatBox(inner) => { ast::PatBox(ref inner) => {
check_pointer_pat(pcx, Send, inner, pat.id, pat.span, expected); check_pointer_pat(pcx, Send, &**inner, pat.id, pat.span, expected);
} }
ast::PatRegion(inner) => { ast::PatRegion(ref inner) => {
check_pointer_pat(pcx, Borrowed, inner, pat.id, pat.span, expected); check_pointer_pat(pcx, Borrowed, &**inner, pat.id, pat.span, expected);
} }
ast::PatVec(ref before, slice, ref after) => { ast::PatVec(ref before, slice, ref after) => {
let default_region_var = let default_region_var =
@ -639,14 +640,14 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
infer::PatternRegion(pat.span)); infer::PatternRegion(pat.span));
let check_err = || { let check_err = || {
for &elt in before.iter() { for elt in before.iter() {
check_pat(pcx, elt, ty::mk_err()); check_pat(pcx, &**elt, ty::mk_err());
} }
for &elt in slice.iter() { for elt in slice.iter() {
check_pat(pcx, elt, ty::mk_err()); check_pat(pcx, &**elt, ty::mk_err());
} }
for &elt in after.iter() { for elt in after.iter() {
check_pat(pcx, elt, ty::mk_err()); check_pat(pcx, &**elt, ty::mk_err());
} }
// See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs // See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
fcx.infcx().type_error_message_str_with_expected( fcx.infcx().type_error_message_str_with_expected(
@ -697,19 +698,19 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
} }
}; };
for elt in before.iter() { for elt in before.iter() {
check_pat(pcx, *elt, elt_type); check_pat(pcx, &**elt, elt_type);
} }
match slice { match slice {
Some(slice_pat) => { Some(ref slice_pat) => {
let slice_ty = ty::mk_slice(tcx, let slice_ty = ty::mk_slice(tcx,
region_var, region_var,
ty::mt {ty: elt_type, mutbl: mutbl}); ty::mt {ty: elt_type, mutbl: mutbl});
check_pat(pcx, slice_pat, slice_ty); check_pat(pcx, &**slice_pat, slice_ty);
} }
None => () None => ()
} }
for elt in after.iter() { for elt in after.iter() {
check_pat(pcx, *elt, elt_type); check_pat(pcx, &**elt, elt_type);
} }
fcx.write_ty(pat.id, expected); fcx.write_ty(pat.id, expected);
} }
@ -718,7 +719,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
} }
} }
// Helper function to check @, box and & patterns // Helper function to check gc, box and & patterns
pub fn check_pointer_pat(pcx: &pat_ctxt, pub fn check_pointer_pat(pcx: &pat_ctxt,
pointer_kind: PointerKind, pointer_kind: PointerKind,
inner: &ast::Pat, inner: &ast::Pat,

View File

@ -79,8 +79,6 @@ type parameter).
use middle::const_eval; use middle::const_eval;
use middle::def; use middle::def;
use middle::lang_items::{ExchangeHeapLangItem, GcLangItem};
use middle::lang_items::{ManagedHeapLangItem};
use middle::lint::UnreachableCode; use middle::lint::UnreachableCode;
use middle::pat_util::pat_id_map; use middle::pat_util::pat_id_map;
use middle::pat_util; use middle::pat_util;
@ -121,7 +119,7 @@ use std::cell::{Cell, RefCell};
use std::collections::HashMap; use std::collections::HashMap;
use std::mem::replace; use std::mem::replace;
use std::rc::Rc; use std::rc::Rc;
use std::vec::Vec; use std::gc::Gc;
use syntax::abi; use syntax::abi;
use syntax::ast::{Provided, Required}; use syntax::ast::{Provided, Required};
use syntax::ast; use syntax::ast;
@ -382,11 +380,11 @@ impl<'a> Visitor<()> for GatherLocalsVisitor<'a> {
fn visit_local(&mut self, local: &ast::Local, _: ()) { fn visit_local(&mut self, local: &ast::Local, _: ()) {
let o_ty = match local.ty.node { let o_ty = match local.ty.node {
ast::TyInfer => None, ast::TyInfer => None,
_ => Some(self.fcx.to_ty(local.ty)) _ => Some(self.fcx.to_ty(&*local.ty))
}; };
self.assign(local.id, o_ty); self.assign(local.id, o_ty);
debug!("Local variable {} is assigned type {}", debug!("Local variable {} is assigned type {}",
self.fcx.pat_to_str(local.pat), self.fcx.pat_to_str(&*local.pat),
self.fcx.infcx().ty_to_str( self.fcx.infcx().ty_to_str(
self.fcx.inh.locals.borrow().get_copy(&local.id))); self.fcx.inh.locals.borrow().get_copy(&local.id)));
visit::walk_local(self, local, ()); visit::walk_local(self, local, ());
@ -478,7 +476,7 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>,
for (arg_ty, input) in arg_tys.iter().zip(decl.inputs.iter()) { for (arg_ty, input) in arg_tys.iter().zip(decl.inputs.iter()) {
// Create type variables for each argument. // Create type variables for each argument.
pat_util::pat_bindings(&tcx.def_map, pat_util::pat_bindings(&tcx.def_map,
input.pat, &*input.pat,
|_bm, pat_id, _sp, _path| { |_bm, pat_id, _sp, _path| {
visit.assign(pat_id, None); visit.assign(pat_id, None);
}); });
@ -486,9 +484,9 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>,
// Check the pattern. // Check the pattern.
let pcx = pat_ctxt { let pcx = pat_ctxt {
fcx: &fcx, fcx: &fcx,
map: pat_id_map(&tcx.def_map, input.pat), map: pat_id_map(&tcx.def_map, &*input.pat),
}; };
_match::check_pat(&pcx, input.pat, *arg_ty); _match::check_pat(&pcx, &*input.pat, *arg_ty);
} }
visit.visit_block(body, ()); visit.visit_block(body, ());
@ -499,11 +497,11 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>,
// We unify the tail expr's type with the // We unify the tail expr's type with the
// function result type, if there is a tail expr. // function result type, if there is a tail expr.
match body.expr { match body.expr {
Some(tail_expr) => { Some(ref tail_expr) => {
// Special case: we print a special error if there appears // Special case: we print a special error if there appears
// to be do-block/for-loop confusion // to be do-block/for-loop confusion
demand::suptype_with_fn(&fcx, tail_expr.span, false, demand::suptype_with_fn(&fcx, tail_expr.span, false,
fcx.ret_ty, fcx.expr_ty(tail_expr), fcx.ret_ty, fcx.expr_ty(&**tail_expr),
|sp, e, a, s| { |sp, e, a, s| {
fcx.report_mismatched_return_types(sp, e, a, s); fcx.report_mismatched_return_types(sp, e, a, s);
}); });
@ -626,7 +624,7 @@ pub fn check_item_sized(ccx: &CrateCtxt, it: &ast::Item) {
enum_definition.variants.as_slice()); enum_definition.variants.as_slice());
} }
ast::ItemStruct(..) => { ast::ItemStruct(..) => {
check_fields_sized(ccx.tcx, ccx.tcx.map.expect_struct(it.id)); check_fields_sized(ccx.tcx, &*ccx.tcx.map.expect_struct(it.id));
} }
_ => {} _ => {}
} }
@ -639,14 +637,14 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
let _indenter = indenter(); let _indenter = indenter();
match it.node { match it.node {
ast::ItemStatic(_, _, e) => check_const(ccx, it.span, e, it.id), ast::ItemStatic(_, _, ref e) => check_const(ccx, it.span, &**e, it.id),
ast::ItemEnum(ref enum_definition, _) => { ast::ItemEnum(ref enum_definition, _) => {
check_enum_variants(ccx, check_enum_variants(ccx,
it.span, it.span,
enum_definition.variants.as_slice(), enum_definition.variants.as_slice(),
it.id); it.id);
} }
ast::ItemFn(decl, _, _, _, body) => { ast::ItemFn(ref decl, _, _, _, ref body) => {
let fn_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id)); let fn_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
let param_env = ty::construct_parameter_environment( let param_env = ty::construct_parameter_environment(
@ -658,14 +656,14 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
fn_tpt.generics.region_param_defs.as_slice(), fn_tpt.generics.region_param_defs.as_slice(),
body.id); body.id);
check_bare_fn(ccx, decl, body, it.id, fn_tpt.ty, param_env); check_bare_fn(ccx, &**decl, &**body, it.id, fn_tpt.ty, param_env);
} }
ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => { ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id); debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
let impl_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id)); let impl_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
for m in ms.iter() { for m in ms.iter() {
check_method_body(ccx, &impl_tpt.generics, None, *m); check_method_body(ccx, &impl_tpt.generics, None, &**m);
} }
match *opt_trait_ref { match *opt_trait_ref {
@ -694,7 +692,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
} }
Provided(m) => { Provided(m) => {
check_method_body(ccx, &trait_def.generics, check_method_body(ccx, &trait_def.generics,
Some(trait_def.trait_ref.clone()), m); Some(trait_def.trait_ref.clone()), &*m);
} }
} }
} }
@ -709,7 +707,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
ast::ItemForeignMod(ref m) => { ast::ItemForeignMod(ref m) => {
if m.abi == abi::RustIntrinsic { if m.abi == abi::RustIntrinsic {
for item in m.items.iter() { for item in m.items.iter() {
check_intrinsic_type(ccx, *item); check_intrinsic_type(ccx, &**item);
} }
} else { } else {
for item in m.items.iter() { for item in m.items.iter() {
@ -770,7 +768,7 @@ fn check_method_body(ccx: &CrateCtxt,
let fty = ty::node_id_to_type(ccx.tcx, method.id); let fty = ty::node_id_to_type(ccx.tcx, method.id);
check_bare_fn(ccx, method.decl, method.body, method.id, fty, param_env); check_bare_fn(ccx, &*method.decl, &*method.body, method.id, fty, param_env);
} }
fn check_impl_methods_against_trait(ccx: &CrateCtxt, fn check_impl_methods_against_trait(ccx: &CrateCtxt,
@ -778,7 +776,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
impl_generics: &ty::Generics, impl_generics: &ty::Generics,
ast_trait_ref: &ast::TraitRef, ast_trait_ref: &ast::TraitRef,
impl_trait_ref: &ty::TraitRef, impl_trait_ref: &ty::TraitRef,
impl_methods: &[@ast::Method]) { impl_methods: &[Gc<ast::Method>]) {
// Locate trait methods // Locate trait methods
let tcx = ccx.tcx; let tcx = ccx.tcx;
let trait_methods = ty::trait_methods(tcx, impl_trait_ref.def_id); let trait_methods = ty::trait_methods(tcx, impl_trait_ref.def_id);
@ -1356,9 +1354,9 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
/// Attempts to resolve a call expression as an overloaded call. /// Attempts to resolve a call expression as an overloaded call.
fn try_overloaded_call(fcx: &FnCtxt, fn try_overloaded_call(fcx: &FnCtxt,
call_expression: &ast::Expr, call_expression: &ast::Expr,
callee: @ast::Expr, callee: Gc<ast::Expr>,
callee_type: ty::t, callee_type: ty::t,
args: &[@ast::Expr]) args: &[Gc<ast::Expr>])
-> bool { -> bool {
// Try `FnOnce`, then `FnMut`, then `Fn`. // Try `FnOnce`, then `FnMut`, then `Fn`.
for &(maybe_function_trait, method_name) in [ for &(maybe_function_trait, method_name) in [
@ -1454,7 +1452,7 @@ fn check_method_argument_types(fcx: &FnCtxt,
sp: Span, sp: Span,
method_fn_ty: ty::t, method_fn_ty: ty::t,
callee_expr: &ast::Expr, callee_expr: &ast::Expr,
args: &[@ast::Expr], args: &[Gc<ast::Expr>],
deref_args: DerefArgs, deref_args: DerefArgs,
tuple_arguments: TupleArgumentsFlag) tuple_arguments: TupleArgumentsFlag)
-> ty::t { -> ty::t {
@ -1501,7 +1499,7 @@ fn check_argument_types(fcx: &FnCtxt,
sp: Span, sp: Span,
fn_inputs: &[ty::t], fn_inputs: &[ty::t],
callee_expr: &ast::Expr, callee_expr: &ast::Expr,
args: &[@ast::Expr], args: &[Gc<ast::Expr>],
deref_args: DerefArgs, deref_args: DerefArgs,
variadic: bool, variadic: bool,
tuple_arguments: TupleArgumentsFlag) { tuple_arguments: TupleArgumentsFlag) {
@ -1654,7 +1652,7 @@ fn check_argument_types(fcx: &FnCtxt,
DontDerefArgs => {} DontDerefArgs => {}
} }
check_expr_coercable_to_type(fcx, *arg, formal_ty); check_expr_coercable_to_type(fcx, &**arg, formal_ty);
} }
} }
@ -1664,11 +1662,12 @@ fn check_argument_types(fcx: &FnCtxt,
// arguments which we skipped above. // arguments which we skipped above.
if variadic { if variadic {
for arg in args.iter().skip(expected_arg_count) { for arg in args.iter().skip(expected_arg_count) {
check_expr(fcx, *arg); check_expr(fcx, &**arg);
// There are a few types which get autopromoted when passed via varargs // There are a few types which get autopromoted when passed via varargs
// in C but we just error out instead and require explicit casts. // in C but we just error out instead and require explicit casts.
let arg_ty = structurally_resolved_type(fcx, arg.span, fcx.expr_ty(*arg)); let arg_ty = structurally_resolved_type(fcx, arg.span,
fcx.expr_ty(&**arg));
match ty::get(arg_ty).sty { match ty::get(arg_ty).sty {
ty::ty_float(ast::TyF32) => { ty::ty_float(ast::TyF32) => {
fcx.type_error_message(arg.span, fcx.type_error_message(arg.span,
@ -2040,7 +2039,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fn check_call(fcx: &FnCtxt, fn check_call(fcx: &FnCtxt,
call_expr: &ast::Expr, call_expr: &ast::Expr,
f: &ast::Expr, f: &ast::Expr,
args: &[@ast::Expr]) { args: &[Gc<ast::Expr>]) {
// Store the type of `f` as the type of the callee // Store the type of `f` as the type of the callee
let fn_ty = fcx.expr_ty(f); let fn_ty = fcx.expr_ty(f);
@ -2091,21 +2090,21 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fn check_method_call(fcx: &FnCtxt, fn check_method_call(fcx: &FnCtxt,
expr: &ast::Expr, expr: &ast::Expr,
method_name: ast::SpannedIdent, method_name: ast::SpannedIdent,
args: &[@ast::Expr], args: &[Gc<ast::Expr>],
tps: &[ast::P<ast::Ty>]) { tps: &[ast::P<ast::Ty>]) {
let rcvr = args[0]; let rcvr = args[0].clone();
// We can't know if we need &mut self before we look up the method, // We can't know if we need &mut self before we look up the method,
// so treat the receiver as mutable just in case - only explicit // so treat the receiver as mutable just in case - only explicit
// overloaded dereferences care about the distinction. // overloaded dereferences care about the distinction.
check_expr_with_lvalue_pref(fcx, rcvr, PreferMutLvalue); check_expr_with_lvalue_pref(fcx, &*rcvr, PreferMutLvalue);
// no need to check for bot/err -- callee does that // no need to check for bot/err -- callee does that
let expr_t = structurally_resolved_type(fcx, let expr_t = structurally_resolved_type(fcx,
expr.span, expr.span,
fcx.expr_ty(rcvr)); fcx.expr_ty(&*rcvr));
let tps = tps.iter().map(|&ast_ty| fcx.to_ty(ast_ty)).collect::<Vec<_>>(); let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
let fn_ty = match method::lookup(fcx, expr, rcvr, let fn_ty = match method::lookup(fcx, expr, &*rcvr,
method_name.node.name, method_name.node.name,
expr_t, tps.as_slice(), expr_t, tps.as_slice(),
DontDerefArgs, DontDerefArgs,
@ -2136,7 +2135,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
// Check for potential static matches (missing self parameters) // Check for potential static matches (missing self parameters)
method::lookup(fcx, method::lookup(fcx,
expr, expr,
rcvr, &*rcvr,
method_name.node.name, method_name.node.name,
expr_t, expr_t,
tps.as_slice(), tps.as_slice(),
@ -2166,18 +2165,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fn check_then_else(fcx: &FnCtxt, fn check_then_else(fcx: &FnCtxt,
cond_expr: &ast::Expr, cond_expr: &ast::Expr,
then_blk: &ast::Block, then_blk: &ast::Block,
opt_else_expr: Option<@ast::Expr>, opt_else_expr: Option<Gc<ast::Expr>>,
id: ast::NodeId, id: ast::NodeId,
sp: Span, sp: Span,
expected: Option<ty::t>) { expected: Option<ty::t>) {
check_expr_has_type(fcx, cond_expr, ty::mk_bool()); check_expr_has_type(fcx, cond_expr, ty::mk_bool());
let branches_ty = match opt_else_expr { let branches_ty = match opt_else_expr {
Some(else_expr) => { Some(ref else_expr) => {
check_block_with_expected(fcx, then_blk, expected); check_block_with_expected(fcx, then_blk, expected);
let then_ty = fcx.node_ty(then_blk.id); let then_ty = fcx.node_ty(then_blk.id);
check_expr_with_opt_hint(fcx, else_expr, expected); check_expr_with_opt_hint(fcx, &**else_expr, expected);
let else_ty = fcx.expr_ty(else_expr); let else_ty = fcx.expr_ty(&**else_expr);
infer::common_supertype(fcx.infcx(), infer::common_supertype(fcx.infcx(),
infer::IfExpression(sp), infer::IfExpression(sp),
true, true,
@ -2207,7 +2206,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
self_t: ty::t, self_t: ty::t,
opname: ast::Name, opname: ast::Name,
trait_did: Option<ast::DefId>, trait_did: Option<ast::DefId>,
args: &[@ast::Expr], args: &[Gc<ast::Expr>],
autoderef_receiver: AutoderefReceiverFlag, autoderef_receiver: AutoderefReceiverFlag,
unbound_method: ||) -> ty::t { unbound_method: ||) -> ty::t {
let method = match trait_did { let method = match trait_did {
@ -2253,8 +2252,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fn check_binop(fcx: &FnCtxt, fn check_binop(fcx: &FnCtxt,
expr: &ast::Expr, expr: &ast::Expr,
op: ast::BinOp, op: ast::BinOp,
lhs: @ast::Expr, lhs: Gc<ast::Expr>,
rhs: @ast::Expr, rhs: Gc<ast::Expr>,
is_binop_assignment: IsBinopAssignment) { is_binop_assignment: IsBinopAssignment) {
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
@ -2262,16 +2261,16 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
BinopAssignment => PreferMutLvalue, BinopAssignment => PreferMutLvalue,
SimpleBinop => NoPreference SimpleBinop => NoPreference
}; };
check_expr_with_lvalue_pref(fcx, lhs, lvalue_pref); check_expr_with_lvalue_pref(fcx, &*lhs, lvalue_pref);
// Callee does bot / err checking // Callee does bot / err checking
let lhs_t = structurally_resolved_type(fcx, lhs.span, let lhs_t = structurally_resolved_type(fcx, lhs.span,
fcx.expr_ty(lhs)); fcx.expr_ty(&*lhs));
if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) { if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
// Shift is a special case: rhs can be any integral type // Shift is a special case: rhs can be any integral type
check_expr(fcx, rhs); check_expr(fcx, &*rhs);
let rhs_t = fcx.expr_ty(rhs); let rhs_t = fcx.expr_ty(&*rhs);
require_integral(fcx, rhs.span, rhs_t); require_integral(fcx, rhs.span, rhs_t);
fcx.write_ty(expr.id, lhs_t); fcx.write_ty(expr.id, lhs_t);
return; return;
@ -2280,7 +2279,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
if ty::is_binopable(tcx, lhs_t, op) { if ty::is_binopable(tcx, lhs_t, op) {
let tvar = fcx.infcx().next_ty_var(); let tvar = fcx.infcx().next_ty_var();
demand::suptype(fcx, expr.span, tvar, lhs_t); demand::suptype(fcx, expr.span, tvar, lhs_t);
check_expr_has_type(fcx, rhs, tvar); check_expr_has_type(fcx, &*rhs, tvar);
let result_t = match op { let result_t = match op {
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe | ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe |
@ -2345,7 +2344,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
}, },
lhs_t, lhs_t,
None); None);
check_expr(fcx, rhs); check_expr(fcx, &*rhs);
ty::mk_err() ty::mk_err()
}; };
@ -2357,10 +2356,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fn check_user_binop(fcx: &FnCtxt, fn check_user_binop(fcx: &FnCtxt,
ex: &ast::Expr, ex: &ast::Expr,
lhs_expr: @ast::Expr, lhs_expr: Gc<ast::Expr>,
lhs_resolved_t: ty::t, lhs_resolved_t: ty::t,
op: ast::BinOp, op: ast::BinOp,
rhs: @ast::Expr) -> ty::t { rhs: Gc<ast::Expr>) -> ty::t {
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
let lang = &tcx.lang_items; let lang = &tcx.lang_items;
let (name, trait_did) = match op { let (name, trait_did) = match op {
@ -2381,7 +2380,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ast::BiEq => ("eq", lang.eq_trait()), ast::BiEq => ("eq", lang.eq_trait()),
ast::BiNe => ("ne", lang.eq_trait()), ast::BiNe => ("ne", lang.eq_trait()),
ast::BiAnd | ast::BiOr => { ast::BiAnd | ast::BiOr => {
check_expr(fcx, rhs); check_expr(fcx, &*rhs);
return ty::mk_err(); return ty::mk_err();
} }
}; };
@ -2400,7 +2399,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
mname: &str, mname: &str,
trait_did: Option<ast::DefId>, trait_did: Option<ast::DefId>,
ex: &ast::Expr, ex: &ast::Expr,
rhs_expr: @ast::Expr, rhs_expr: Gc<ast::Expr>,
rhs_t: ty::t) -> ty::t { rhs_t: ty::t) -> ty::t {
lookup_op_method(fcx, ex, rhs_t, token::intern(mname), lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
trait_did, [rhs_expr], DontAutoderefReceiver, || { trait_did, [rhs_expr], DontAutoderefReceiver, || {
@ -2513,7 +2512,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
}; };
check_fn(fcx.ccx, inherited_style, &fty_sig, check_fn(fcx.ccx, inherited_style, &fty_sig,
decl, id, body, fcx.inh); &*decl, id, &*body, fcx.inh);
} }
@ -2549,7 +2548,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
None => {} None => {}
} }
let tps: Vec<ty::t> = tys.iter().map(|&ty| fcx.to_ty(ty)).collect(); let tps: Vec<ty::t> = tys.iter().map(|ty| fcx.to_ty(&**ty)).collect();
match method::lookup(fcx, match method::lookup(fcx,
expr, expr,
base, base,
@ -2647,7 +2646,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
// an error, so we can continue typechecking // an error, so we can continue typechecking
check_expr_coercable_to_type( check_expr_coercable_to_type(
fcx, fcx,
field.expr, &*field.expr,
expected_field_type); expected_field_type);
} }
@ -2688,7 +2687,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
span: codemap::Span, span: codemap::Span,
class_id: ast::DefId, class_id: ast::DefId,
fields: &[ast::Field], fields: &[ast::Field],
base_expr: Option<@ast::Expr>) { base_expr: Option<Gc<ast::Expr>>) {
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
// Look up the number of type parameters and the raw type, and // Look up the number of type parameters and the raw type, and
@ -2728,7 +2727,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
match base_expr { match base_expr {
None => {} None => {}
Some(base_expr) => { Some(base_expr) => {
check_expr_has_type(fcx, base_expr, struct_type); check_expr_has_type(fcx, &*base_expr, struct_type);
if ty::type_is_bot(fcx.node_ty(base_expr.id)) { if ty::type_is_bot(fcx.node_ty(base_expr.id)) {
struct_type = ty::mk_bot(); struct_type = ty::mk_bot();
} }
@ -2793,8 +2792,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
let mut any_bot = false; let mut any_bot = false;
let t: ty::t = fcx.infcx().next_ty_var(); let t: ty::t = fcx.infcx().next_ty_var();
for e in args.iter() { for e in args.iter() {
check_expr_has_type(fcx, *e, t); check_expr_has_type(fcx, &**e, t);
let arg_t = fcx.expr_ty(*e); let arg_t = fcx.expr_ty(&**e);
if ty::type_is_error(arg_t) { if ty::type_is_error(arg_t) {
any_error = true; any_error = true;
} }
@ -2807,29 +2806,29 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
} else if any_bot { } else if any_bot {
ty::mk_bot() ty::mk_bot()
} else { } else {
ast_expr_vstore_to_ty(fcx, ev, vst, || ast_expr_vstore_to_ty(fcx, &*ev, vst, ||
ty::mt{ ty: ty::mk_vec(tcx, ty::mt{ ty: ty::mk_vec(tcx,
ty::mt {ty: t, mutbl: mutability}, ty::mt {ty: t, mutbl: mutability},
None), None),
mutbl: mutability }) mutbl: mutability })
} }
} }
ast::ExprRepeat(element, count_expr) => { ast::ExprRepeat(ref element, ref count_expr) => {
check_expr_with_hint(fcx, count_expr, ty::mk_uint()); check_expr_with_hint(fcx, &**count_expr, ty::mk_uint());
let _ = ty::eval_repeat_count(fcx, count_expr); let _ = ty::eval_repeat_count(fcx, &**count_expr);
let mutability = match vst { let mutability = match vst {
ast::ExprVstoreMutSlice => ast::MutMutable, ast::ExprVstoreMutSlice => ast::MutMutable,
_ => ast::MutImmutable, _ => ast::MutImmutable,
}; };
let t = fcx.infcx().next_ty_var(); let t = fcx.infcx().next_ty_var();
check_expr_has_type(fcx, element, t); check_expr_has_type(fcx, &**element, t);
let arg_t = fcx.expr_ty(element); let arg_t = fcx.expr_ty(&**element);
if ty::type_is_error(arg_t) { if ty::type_is_error(arg_t) {
ty::mk_err() ty::mk_err()
} else if ty::type_is_bot(arg_t) { } else if ty::type_is_bot(arg_t) {
ty::mk_bot() ty::mk_bot()
} else { } else {
ast_expr_vstore_to_ty(fcx, ev, vst, || ast_expr_vstore_to_ty(fcx, &*ev, vst, ||
ty::mt{ ty: ty::mk_vec(tcx, ty::mt{ ty: ty::mk_vec(tcx,
ty::mt {ty: t, mutbl: mutability}, ty::mt {ty: t, mutbl: mutability},
None), None),
@ -2851,9 +2850,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_ty(id, typ); fcx.write_ty(id, typ);
} }
ast::ExprBox(place, subexpr) => { ast::ExprBox(ref place, ref subexpr) => {
check_expr(fcx, place); check_expr(fcx, &**place);
check_expr(fcx, subexpr); check_expr(fcx, &**subexpr);
let mut checked = false; let mut checked = false;
match place.node { match place.node {
@ -2862,52 +2861,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
// places: the exchange heap and the managed heap. // places: the exchange heap and the managed heap.
let definition = lookup_def(fcx, path.span, place.id); let definition = lookup_def(fcx, path.span, place.id);
let def_id = definition.def_id(); let def_id = definition.def_id();
match tcx.lang_items if tcx.lang_items.exchange_heap() == Some(def_id) {
.items fcx.write_ty(id, ty::mk_uniq(tcx,
.get(ExchangeHeapLangItem as uint) { fcx.expr_ty(&**subexpr)));
&Some(item_def_id) if def_id == item_def_id => { checked = true
fcx.write_ty(id, ty::mk_uniq(tcx, } else if tcx.lang_items.managed_heap() == Some(def_id) {
fcx.expr_ty(subexpr))); fcx.write_ty(id, ty::mk_box(tcx,
checked = true fcx.expr_ty(&**subexpr)));
} checked = true
&Some(_) | &None => {}
}
if !checked {
match tcx.lang_items
.items
.get(ManagedHeapLangItem as uint) {
&Some(item_def_id) if def_id == item_def_id => {
// Assign the magic `Gc<T>` struct.
let gc_struct_id =
match tcx.lang_items
.require(GcLangItem) {
Ok(id) => id,
Err(msg) => {
tcx.sess.span_err(expr.span,
msg.as_slice());
ast::DefId {
krate: ast::CRATE_NODE_ID,
node: ast::DUMMY_NODE_ID,
}
}
};
let regions =
subst::NonerasedRegions(Vec::new());
let sty = ty::mk_struct(tcx,
gc_struct_id,
subst::Substs {
self_ty: None,
tps: vec!(
fcx.expr_ty(
subexpr)
),
regions: regions,
});
fcx.write_ty(id, sty);
checked = true
}
&Some(_) | &None => {}
}
} }
} }
_ => {} _ => {}
@ -2921,15 +2882,15 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
} }
} }
ast::ExprLit(lit) => { ast::ExprLit(ref lit) => {
let typ = check_lit(fcx, lit); let typ = check_lit(fcx, &**lit);
fcx.write_ty(id, typ); fcx.write_ty(id, typ);
} }
ast::ExprBinary(op, lhs, rhs) => { ast::ExprBinary(op, ref lhs, ref rhs) => {
check_binop(fcx, expr, op, lhs, rhs, SimpleBinop); check_binop(fcx, expr, op, lhs.clone(), rhs.clone(), SimpleBinop);
let lhs_ty = fcx.expr_ty(lhs); let lhs_ty = fcx.expr_ty(&**lhs);
let rhs_ty = fcx.expr_ty(rhs); let rhs_ty = fcx.expr_ty(&**rhs);
if ty::type_is_error(lhs_ty) || if ty::type_is_error(lhs_ty) ||
ty::type_is_error(rhs_ty) { ty::type_is_error(rhs_ty) {
fcx.write_error(id); fcx.write_error(id);
@ -2939,15 +2900,15 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_bot(id); fcx.write_bot(id);
} }
} }
ast::ExprAssignOp(op, lhs, rhs) => { ast::ExprAssignOp(op, ref lhs, ref rhs) => {
check_binop(fcx, expr, op, lhs, rhs, BinopAssignment); check_binop(fcx, expr, op, lhs.clone(), rhs.clone(), BinopAssignment);
let lhs_t = fcx.expr_ty(lhs); let lhs_t = fcx.expr_ty(&**lhs);
let result_t = fcx.expr_ty(expr); let result_t = fcx.expr_ty(expr);
demand::suptype(fcx, expr.span, result_t, lhs_t); demand::suptype(fcx, expr.span, result_t, lhs_t);
let tcx = fcx.tcx(); let tcx = fcx.tcx();
if !ty::expr_is_lval(tcx, lhs) { if !ty::expr_is_lval(tcx, &**lhs) {
tcx.sess.span_err(lhs.span, "illegal left-hand side expression"); tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
} }
@ -2959,7 +2920,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_nil(expr.id); fcx.write_nil(expr.id);
} }
} }
ast::ExprUnary(unop, oprnd) => { ast::ExprUnary(unop, ref oprnd) => {
let exp_inner = unpack_expected(fcx, expected, |sty| { let exp_inner = unpack_expected(fcx, expected, |sty| {
match unop { match unop {
ast::UnBox | ast::UnUniq => match *sty { ast::UnBox | ast::UnUniq => match *sty {
@ -2974,8 +2935,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ast::UnDeref => lvalue_pref, ast::UnDeref => lvalue_pref,
_ => NoPreference _ => NoPreference
}; };
check_expr_with_opt_hint_and_lvalue_pref(fcx, oprnd, exp_inner, lvalue_pref); check_expr_with_opt_hint_and_lvalue_pref(fcx, &**oprnd, exp_inner, lvalue_pref);
let mut oprnd_t = fcx.expr_ty(oprnd); let mut oprnd_t = fcx.expr_ty(&**oprnd);
if !ty::type_is_error(oprnd_t) && !ty::type_is_bot(oprnd_t) { if !ty::type_is_error(oprnd_t) && !ty::type_is_bot(oprnd_t) {
match unop { match unop {
ast::UnBox => { ast::UnBox => {
@ -2990,7 +2951,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
Some(mt) => mt.ty, Some(mt) => mt.ty,
None => match try_overloaded_deref(fcx, expr.span, None => match try_overloaded_deref(fcx, expr.span,
Some(MethodCall::expr(expr.id)), Some(MethodCall::expr(expr.id)),
Some(&*oprnd), oprnd_t, lvalue_pref) { Some(&**oprnd), oprnd_t, lvalue_pref) {
Some(mt) => mt.ty, Some(mt) => mt.ty,
None => { None => {
let is_newtype = match ty::get(oprnd_t).sty { let is_newtype = match ty::get(oprnd_t).sty {
@ -3025,7 +2986,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ty::get(oprnd_t).sty == ty::ty_bool) { ty::get(oprnd_t).sty == ty::ty_bool) {
oprnd_t = check_user_unop(fcx, "!", "not", oprnd_t = check_user_unop(fcx, "!", "not",
tcx.lang_items.not_trait(), tcx.lang_items.not_trait(),
expr, oprnd, oprnd_t); expr, oprnd.clone(), oprnd_t);
} }
} }
ast::UnNeg => { ast::UnNeg => {
@ -3035,14 +2996,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ty::type_is_fp(oprnd_t)) { ty::type_is_fp(oprnd_t)) {
oprnd_t = check_user_unop(fcx, "-", "neg", oprnd_t = check_user_unop(fcx, "-", "neg",
tcx.lang_items.neg_trait(), tcx.lang_items.neg_trait(),
expr, oprnd, oprnd_t); expr, oprnd.clone(), oprnd_t);
} }
} }
} }
} }
fcx.write_ty(id, oprnd_t); fcx.write_ty(id, oprnd_t);
} }
ast::ExprAddrOf(mutbl, oprnd) => { ast::ExprAddrOf(mutbl, ref oprnd) => {
let hint = unpack_expected( let hint = unpack_expected(
fcx, expected, fcx, expected,
|sty| match *sty { ty::ty_rptr(_, ref mt) => Some(mt.ty), |sty| match *sty { ty::ty_rptr(_, ref mt) => Some(mt.ty),
@ -3051,7 +3012,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ast::MutMutable => PreferMutLvalue, ast::MutMutable => PreferMutLvalue,
ast::MutImmutable => NoPreference ast::MutImmutable => NoPreference
}; };
check_expr_with_opt_hint_and_lvalue_pref(fcx, oprnd, hint, lvalue_pref); check_expr_with_opt_hint_and_lvalue_pref(fcx, &**oprnd, hint, lvalue_pref);
// Note: at this point, we cannot say what the best lifetime // Note: at this point, we cannot say what the best lifetime
// is to use for resulting pointer. We want to use the // is to use for resulting pointer. We want to use the
@ -3069,7 +3030,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
let region = fcx.infcx().next_region_var( let region = fcx.infcx().next_region_var(
infer::AddrOfRegion(expr.span)); infer::AddrOfRegion(expr.span));
let tm = ty::mt { ty: fcx.expr_ty(oprnd), mutbl: mutbl }; let tm = ty::mt { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
let oprnd_t = if ty::type_is_error(tm.ty) { let oprnd_t = if ty::type_is_error(tm.ty) {
ty::mk_err() ty::mk_err()
} else if ty::type_is_bot(tm.ty) { } else if ty::type_is_bot(tm.ty) {
@ -3088,20 +3049,20 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id); instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
} }
ast::ExprInlineAsm(ref ia) => { ast::ExprInlineAsm(ref ia) => {
for &(_, input) in ia.inputs.iter() { for &(_, ref input) in ia.inputs.iter() {
check_expr(fcx, input); check_expr(fcx, &**input);
} }
for &(_, out) in ia.outputs.iter() { for &(_, ref out) in ia.outputs.iter() {
check_expr(fcx, out); check_expr(fcx, &**out);
} }
fcx.write_nil(id); fcx.write_nil(id);
} }
ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"), ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
ast::ExprBreak(_) => { fcx.write_bot(id); } ast::ExprBreak(_) => { fcx.write_bot(id); }
ast::ExprAgain(_) => { fcx.write_bot(id); } ast::ExprAgain(_) => { fcx.write_bot(id); }
ast::ExprRet(expr_opt) => { ast::ExprRet(ref expr_opt) => {
let ret_ty = fcx.ret_ty; let ret_ty = fcx.ret_ty;
match expr_opt { match *expr_opt {
None => match fcx.mk_eqty(false, infer::Misc(expr.span), None => match fcx.mk_eqty(false, infer::Misc(expr.span),
ret_ty, ty::mk_nil()) { ret_ty, ty::mk_nil()) {
Ok(_) => { /* fall through */ } Ok(_) => { /* fall through */ }
@ -3111,27 +3072,27 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
"`return;` in function returning non-nil"); "`return;` in function returning non-nil");
} }
}, },
Some(e) => { Some(ref e) => {
check_expr_has_type(fcx, e, ret_ty); check_expr_has_type(fcx, &**e, ret_ty);
} }
} }
fcx.write_bot(id); fcx.write_bot(id);
} }
ast::ExprParen(a) => { ast::ExprParen(ref a) => {
check_expr_with_opt_hint_and_lvalue_pref(fcx, a, expected, lvalue_pref); check_expr_with_opt_hint_and_lvalue_pref(fcx, &**a, expected, lvalue_pref);
fcx.write_ty(id, fcx.expr_ty(a)); fcx.write_ty(id, fcx.expr_ty(&**a));
} }
ast::ExprAssign(lhs, rhs) => { ast::ExprAssign(ref lhs, ref rhs) => {
check_expr_with_lvalue_pref(fcx, lhs, PreferMutLvalue); check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
let tcx = fcx.tcx(); let tcx = fcx.tcx();
if !ty::expr_is_lval(tcx, lhs) { if !ty::expr_is_lval(tcx, &**lhs) {
tcx.sess.span_err(lhs.span, "illegal left-hand side expression"); tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
} }
let lhs_ty = fcx.expr_ty(lhs); let lhs_ty = fcx.expr_ty(&**lhs);
check_expr_has_type(fcx, rhs, lhs_ty); check_expr_has_type(fcx, &**rhs, lhs_ty);
let rhs_ty = fcx.expr_ty(rhs); let rhs_ty = fcx.expr_ty(&**rhs);
if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) { if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) {
fcx.write_error(id); fcx.write_error(id);
@ -3141,14 +3102,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_nil(id); fcx.write_nil(id);
} }
} }
ast::ExprIf(cond, then_blk, opt_else_expr) => { ast::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
check_then_else(fcx, cond, then_blk, opt_else_expr, check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.clone(),
id, expr.span, expected); id, expr.span, expected);
} }
ast::ExprWhile(cond, body) => { ast::ExprWhile(ref cond, ref body) => {
check_expr_has_type(fcx, cond, ty::mk_bool()); check_expr_has_type(fcx, &**cond, ty::mk_bool());
check_block_no_value(fcx, body); check_block_no_value(fcx, &**body);
let cond_ty = fcx.expr_ty(cond); let cond_ty = fcx.expr_ty(&**cond);
let body_ty = fcx.node_ty(body.id); let body_ty = fcx.node_ty(body.id);
if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) { if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) {
fcx.write_error(id); fcx.write_error(id);
@ -3162,19 +3123,19 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
} }
ast::ExprForLoop(..) => ast::ExprForLoop(..) =>
fail!("non-desugared expr_for_loop"), fail!("non-desugared expr_for_loop"),
ast::ExprLoop(body, _) => { ast::ExprLoop(ref body, _) => {
check_block_no_value(fcx, (body)); check_block_no_value(fcx, &**body);
if !may_break(tcx, expr.id, body) { if !may_break(tcx, expr.id, body.clone()) {
fcx.write_bot(id); fcx.write_bot(id);
} }
else { else {
fcx.write_nil(id); fcx.write_nil(id);
} }
} }
ast::ExprMatch(discrim, ref arms) => { ast::ExprMatch(ref discrim, ref arms) => {
_match::check_match(fcx, expr, discrim, arms.as_slice()); _match::check_match(fcx, expr, &**discrim, arms.as_slice());
} }
ast::ExprFnBlock(decl, body) => { ast::ExprFnBlock(ref decl, ref body) => {
let region = astconv::opt_ast_region_to_region(fcx, let region = astconv::opt_ast_region_to_region(fcx,
fcx.infcx(), fcx.infcx(),
expr.span, expr.span,
@ -3182,34 +3143,34 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
check_expr_fn(fcx, check_expr_fn(fcx,
expr, expr,
ty::RegionTraitStore(region, ast::MutMutable), ty::RegionTraitStore(region, ast::MutMutable),
decl, &**decl,
body, body.clone(),
expected); expected);
} }
ast::ExprProc(decl, body) => { ast::ExprProc(ref decl, ref body) => {
check_expr_fn(fcx, check_expr_fn(fcx,
expr, expr,
ty::UniqTraitStore, ty::UniqTraitStore,
decl, &**decl,
body, body.clone(),
expected); expected);
} }
ast::ExprBlock(b) => { ast::ExprBlock(ref b) => {
check_block_with_expected(fcx, b, expected); check_block_with_expected(fcx, &**b, expected);
fcx.write_ty(id, fcx.node_ty(b.id)); fcx.write_ty(id, fcx.node_ty(b.id));
} }
ast::ExprCall(f, ref args) => { ast::ExprCall(ref f, ref args) => {
// Index expressions need to be handled separately, to inform them // Index expressions need to be handled separately, to inform them
// that they appear in call position. // that they appear in call position.
check_expr(fcx, f); check_expr(fcx, &**f);
let f_ty = fcx.expr_ty(f); let f_ty = fcx.expr_ty(&**f);
if !try_overloaded_call(fcx, expr, f, f_ty, args.as_slice()) { if !try_overloaded_call(fcx, expr, f.clone(), f_ty, args.as_slice()) {
check_call(fcx, expr, f, args.as_slice()); check_call(fcx, expr, &**f, args.as_slice());
let (args_bot, args_err) = args.iter().fold((false, false), let (args_bot, args_err) = args.iter().fold((false, false),
|(rest_bot, rest_err), a| { |(rest_bot, rest_err), a| {
// is this not working? // is this not working?
let a_ty = fcx.expr_ty(*a); let a_ty = fcx.expr_ty(&**a);
(rest_bot || ty::type_is_bot(a_ty), (rest_bot || ty::type_is_bot(a_ty),
rest_err || ty::type_is_error(a_ty))}); rest_err || ty::type_is_error(a_ty))});
if ty::type_is_error(f_ty) || args_err { if ty::type_is_error(f_ty) || args_err {
@ -3222,7 +3183,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
} }
ast::ExprMethodCall(ident, ref tps, ref args) => { ast::ExprMethodCall(ident, ref tps, ref args) => {
check_method_call(fcx, expr, ident, args.as_slice(), tps.as_slice()); check_method_call(fcx, expr, ident, args.as_slice(), tps.as_slice());
let mut arg_tys = args.iter().map(|a| fcx.expr_ty(*a)); let mut arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
let (args_bot, args_err) = arg_tys.fold((false, false), let (args_bot, args_err) = arg_tys.fold((false, false),
|(rest_bot, rest_err), a| { |(rest_bot, rest_err), a| {
(rest_bot || ty::type_is_bot(a), (rest_bot || ty::type_is_bot(a),
@ -3233,10 +3194,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_bot(id); fcx.write_bot(id);
} }
} }
ast::ExprCast(e, t) => { ast::ExprCast(ref e, ref t) => {
check_expr(fcx, e); check_expr(fcx, &**e);
let t_1 = fcx.to_ty(t); let t_1 = fcx.to_ty(&**t);
let t_e = fcx.expr_ty(e); let t_e = fcx.expr_ty(&**e);
debug!("t_1={}", fcx.infcx().ty_to_str(t_1)); debug!("t_1={}", fcx.infcx().ty_to_str(t_1));
debug!("t_e={}", fcx.infcx().ty_to_str(t_e)); debug!("t_e={}", fcx.infcx().ty_to_str(t_e));
@ -3335,7 +3296,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
/* this case is allowed */ /* this case is allowed */
} }
_ => { _ => {
demand::coerce(fcx, e.span, t_1, e); demand::coerce(fcx, e.span, t_1, &**e);
} }
} }
} else if !(type_is_scalar(fcx,expr.span,t_e) } else if !(type_is_scalar(fcx,expr.span,t_e)
@ -3359,18 +3320,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ast::ExprVec(ref args) => { ast::ExprVec(ref args) => {
let t: ty::t = fcx.infcx().next_ty_var(); let t: ty::t = fcx.infcx().next_ty_var();
for e in args.iter() { for e in args.iter() {
check_expr_has_type(fcx, *e, t); check_expr_has_type(fcx, &**e, t);
} }
let typ = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: ast::MutImmutable}, let typ = ty::mk_vec(tcx, ty::mt {ty: t, mutbl: ast::MutImmutable},
Some(args.len())); Some(args.len()));
fcx.write_ty(id, typ); fcx.write_ty(id, typ);
} }
ast::ExprRepeat(element, count_expr) => { ast::ExprRepeat(ref element, ref count_expr) => {
check_expr_with_hint(fcx, count_expr, ty::mk_uint()); check_expr_with_hint(fcx, &**count_expr, ty::mk_uint());
let count = ty::eval_repeat_count(fcx, count_expr); let count = ty::eval_repeat_count(fcx, &**count_expr);
let t: ty::t = fcx.infcx().next_ty_var(); let t: ty::t = fcx.infcx().next_ty_var();
check_expr_has_type(fcx, element, t); check_expr_has_type(fcx, &**element, t);
let element_ty = fcx.expr_ty(element); let element_ty = fcx.expr_ty(&**element);
if ty::type_is_error(element_ty) { if ty::type_is_error(element_ty) {
fcx.write_error(id); fcx.write_error(id);
} }
@ -3398,8 +3359,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
Some(ref fs) if i < fs.len() => Some(*fs.get(i)), Some(ref fs) if i < fs.len() => Some(*fs.get(i)),
_ => None _ => None
}; };
check_expr_with_opt_hint(fcx, *e, opt_hint); check_expr_with_opt_hint(fcx, &**e, opt_hint);
let t = fcx.expr_ty(*e); let t = fcx.expr_ty(&**e);
err_field = err_field || ty::type_is_error(t); err_field = err_field || ty::type_is_error(t);
bot_field = bot_field || ty::type_is_bot(t); bot_field = bot_field || ty::type_is_bot(t);
t t
@ -3431,14 +3392,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
} }
} }
} }
ast::ExprField(base, field, ref tys) => { ast::ExprField(ref base, ref field, ref tys) => {
check_field(fcx, expr, lvalue_pref, base, field.name, tys.as_slice()); check_field(fcx, expr, lvalue_pref, &**base, field.name, tys.as_slice());
} }
ast::ExprIndex(base, idx) => { ast::ExprIndex(ref base, ref idx) => {
check_expr_with_lvalue_pref(fcx, base, lvalue_pref); check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
check_expr(fcx, idx); check_expr(fcx, &**idx);
let raw_base_t = fcx.expr_ty(base); let raw_base_t = fcx.expr_ty(&**base);
let idx_t = fcx.expr_ty(idx); let idx_t = fcx.expr_ty(&**idx);
if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) { if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
fcx.write_ty(id, raw_base_t); fcx.write_ty(id, raw_base_t);
} else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) { } else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
@ -3449,7 +3410,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
lvalue_pref, |base_t, _| ty::index(base_t)); lvalue_pref, |base_t, _| ty::index(base_t));
match field_ty { match field_ty {
Some(mt) => { Some(mt) => {
check_expr_has_type(fcx, idx, ty::mk_uint()); check_expr_has_type(fcx, &**idx, ty::mk_uint());
fcx.write_ty(id, mt.ty); fcx.write_ty(id, mt.ty);
fcx.write_autoderef_adjustment(base.id, autoderefs); fcx.write_autoderef_adjustment(base.id, autoderefs);
} }
@ -3462,7 +3423,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
resolved, resolved,
token::intern("index"), token::intern("index"),
tcx.lang_items.index_trait(), tcx.lang_items.index_trait(),
[base, idx], [base.clone(), idx.clone()],
AutoderefReceiver, AutoderefReceiver,
|| { || {
fcx.type_error_message(expr.span, fcx.type_error_message(expr.span,
@ -3526,9 +3487,9 @@ pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local) {
fcx.write_ty(local.id, t); fcx.write_ty(local.id, t);
match local.init { match local.init {
Some(init) => { Some(ref init) => {
check_decl_initializer(fcx, local.id, init); check_decl_initializer(fcx, local.id, &**init);
let init_ty = fcx.expr_ty(init); let init_ty = fcx.expr_ty(&**init);
if ty::type_is_error(init_ty) || ty::type_is_bot(init_ty) { if ty::type_is_error(init_ty) || ty::type_is_bot(init_ty) {
fcx.write_ty(local.id, init_ty); fcx.write_ty(local.id, init_ty);
} }
@ -3538,9 +3499,9 @@ pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local) {
let pcx = pat_ctxt { let pcx = pat_ctxt {
fcx: fcx, fcx: fcx,
map: pat_id_map(&tcx.def_map, local.pat), map: pat_id_map(&tcx.def_map, &*local.pat),
}; };
_match::check_pat(&pcx, local.pat, t); _match::check_pat(&pcx, &*local.pat, t);
let pat_ty = fcx.node_ty(local.pat.id); let pat_ty = fcx.node_ty(local.pat.id);
if ty::type_is_error(pat_ty) || ty::type_is_bot(pat_ty) { if ty::type_is_error(pat_ty) || ty::type_is_bot(pat_ty) {
fcx.write_ty(local.id, pat_ty); fcx.write_ty(local.id, pat_ty);
@ -3556,7 +3517,7 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt) {
node_id = id; node_id = id;
match decl.node { match decl.node {
ast::DeclLocal(ref l) => { ast::DeclLocal(ref l) => {
check_decl_local(fcx, *l); check_decl_local(fcx, &**l);
let l_t = fcx.node_ty(l.id); let l_t = fcx.node_ty(l.id);
saw_bot = saw_bot || ty::type_is_bot(l_t); saw_bot = saw_bot || ty::type_is_bot(l_t);
saw_err = saw_err || ty::type_is_error(l_t); saw_err = saw_err || ty::type_is_error(l_t);
@ -3564,18 +3525,18 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt) {
ast::DeclItem(_) => {/* ignore for now */ } ast::DeclItem(_) => {/* ignore for now */ }
} }
} }
ast::StmtExpr(expr, id) => { ast::StmtExpr(ref expr, id) => {
node_id = id; node_id = id;
// Check with expected type of () // Check with expected type of ()
check_expr_has_type(fcx, expr, ty::mk_nil()); check_expr_has_type(fcx, &**expr, ty::mk_nil());
let expr_ty = fcx.expr_ty(expr); let expr_ty = fcx.expr_ty(&**expr);
saw_bot = saw_bot || ty::type_is_bot(expr_ty); saw_bot = saw_bot || ty::type_is_bot(expr_ty);
saw_err = saw_err || ty::type_is_error(expr_ty); saw_err = saw_err || ty::type_is_error(expr_ty);
} }
ast::StmtSemi(expr, id) => { ast::StmtSemi(ref expr, id) => {
node_id = id; node_id = id;
check_expr(fcx, expr); check_expr(fcx, &**expr);
let expr_ty = fcx.expr_ty(expr); let expr_ty = fcx.expr_ty(&**expr);
saw_bot |= ty::type_is_bot(expr_ty); saw_bot |= ty::type_is_bot(expr_ty);
saw_err |= ty::type_is_error(expr_ty); saw_err |= ty::type_is_error(expr_ty);
} }
@ -3622,8 +3583,8 @@ pub fn check_block_with_expected(fcx: &FnCtxt,
let mut any_bot = false; let mut any_bot = false;
let mut any_err = false; let mut any_err = false;
for s in blk.stmts.iter() { for s in blk.stmts.iter() {
check_stmt(fcx, *s); check_stmt(fcx, &**s);
let s_id = ast_util::stmt_id(*s); let s_id = ast_util::stmt_id(&**s);
let s_ty = fcx.node_ty(s_id); let s_ty = fcx.node_ty(s_id);
if last_was_bot && !warned && match s.node { if last_was_bot && !warned && match s.node {
ast::StmtDecl(decl, _) => { ast::StmtDecl(decl, _) => {
@ -3670,8 +3631,8 @@ pub fn check_block_with_expected(fcx: &FnCtxt,
e.span, e.span,
"unreachable expression".to_string()); "unreachable expression".to_string());
} }
check_expr_with_opt_hint(fcx, e, expected); check_expr_with_opt_hint(fcx, &*e, expected);
let ety = fcx.expr_ty(e); let ety = fcx.expr_ty(&*e);
fcx.write_ty(blk.id, ety); fcx.write_ty(blk.id, ety);
if any_err { if any_err {
fcx.write_error(blk.id); fcx.write_error(blk.id);
@ -3831,7 +3792,7 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
} }
} }
}, },
ast::StructVariantKind(struct_def) => check_fields_sized(ccx.tcx, struct_def), ast::StructVariantKind(struct_def) => check_fields_sized(ccx.tcx, &*struct_def),
_ => {} _ => {}
} }
} }
@ -3891,17 +3852,17 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
match v.node.disr_expr { match v.node.disr_expr {
Some(e) => { Some(e) => {
debug!("disr expr, checking {}", pprust::expr_to_str(e)); debug!("disr expr, checking {}", pprust::expr_to_str(&*e));
let inh = blank_inherited_fields(ccx); let inh = blank_inherited_fields(ccx);
let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id); let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
let declty = ty::mk_int_var(ccx.tcx, fcx.infcx().next_int_var_id()); let declty = ty::mk_int_var(ccx.tcx, fcx.infcx().next_int_var_id());
check_const_with_ty(&fcx, e.span, e, declty); check_const_with_ty(&fcx, e.span, &*e, declty);
// check_expr (from check_const pass) doesn't guarantee // check_expr (from check_const pass) doesn't guarantee
// that the expression is in a form that eval_const_expr can // that the expression is in a form that eval_const_expr can
// handle, so we may still get an internal compiler error // handle, so we may still get an internal compiler error
match const_eval::eval_const_expr_partial(ccx.tcx, e) { match const_eval::eval_const_expr_partial(ccx.tcx, &*e) {
Ok(const_eval::const_int(val)) => current_disr_val = val as Disr, Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr, Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
Ok(_) => { Ok(_) => {
@ -3936,7 +3897,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
} }
disr_vals.push(current_disr_val); disr_vals.push(current_disr_val);
let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, v, let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, &*v,
current_disr_val)); current_disr_val));
prev_disr_val = Some(current_disr_val); prev_disr_val = Some(current_disr_val);
@ -4134,7 +4095,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
let mut pushed = false; let mut pushed = false;
for (i, ty) in pth.segments.iter() for (i, ty) in pth.segments.iter()
.flat_map(|segment| segment.types.iter()) .flat_map(|segment| segment.types.iter())
.map(|&ast_type| fcx.to_ty(ast_type)) .map(|ast_type| fcx.to_ty(&**ast_type))
.enumerate() { .enumerate() {
match self_parameter_index { match self_parameter_index {
Some(index) if index == i => { Some(index) if index == i => {
@ -4302,7 +4263,7 @@ pub fn ast_expr_vstore_to_ty(fcx: &FnCtxt,
pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: ast::P<ast::Block>) -> bool { pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: ast::P<ast::Block>) -> bool {
// First: is there an unlabeled break immediately // First: is there an unlabeled break immediately
// inside the loop? // inside the loop?
(loop_query(b, |e| { (loop_query(&*b, |e| {
match *e { match *e {
ast::ExprBreak(_) => true, ast::ExprBreak(_) => true,
_ => false _ => false

View File

@ -141,6 +141,7 @@ use syntax::visit;
use syntax::visit::Visitor; use syntax::visit::Visitor;
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
// If mem categorization results in an error, it's because the type // If mem categorization results in an error, it's because the type
// check failed (or will fail, when the error is uncovered and // check failed (or will fail, when the error is uncovered and
@ -343,8 +344,8 @@ fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) { fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
// see above // see above
for &p in arm.pats.iter() { for p in arm.pats.iter() {
constrain_bindings_in_pat(p, rcx); constrain_bindings_in_pat(&**p, rcx);
} }
visit::walk_arm(rcx, arm, ()); visit::walk_arm(rcx, arm, ());
@ -352,7 +353,7 @@ fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
fn visit_local(rcx: &mut Rcx, l: &ast::Local) { fn visit_local(rcx: &mut Rcx, l: &ast::Local) {
// see above // see above
constrain_bindings_in_pat(l.pat, rcx); constrain_bindings_in_pat(&*l.pat, rcx);
link_local(rcx, l); link_local(rcx, l);
visit::walk_local(rcx, l, ()); visit::walk_local(rcx, l, ());
} }
@ -441,9 +442,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
} }
match expr.node { match expr.node {
ast::ExprCall(callee, ref args) => { ast::ExprCall(ref callee, ref args) => {
if !has_method_map { if !has_method_map {
constrain_callee(rcx, callee.id, expr, callee); constrain_callee(rcx, callee.id, expr, &**callee);
constrain_call(rcx, constrain_call(rcx,
Some(callee.id), Some(callee.id),
expr, expr,
@ -462,45 +463,47 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprAssign(lhs, _) => { ast::ExprAssign(ref lhs, _) => {
adjust_borrow_kind_for_assignment_lhs(rcx, lhs); adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprAssignOp(_, lhs, rhs) => { ast::ExprAssignOp(_, ref lhs, ref rhs) => {
if has_method_map { if has_method_map {
constrain_call(rcx, None, expr, Some(lhs), [rhs], true); constrain_call(rcx, None, expr, Some(lhs.clone()),
[rhs.clone()], true);
} }
adjust_borrow_kind_for_assignment_lhs(rcx, lhs); adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprIndex(lhs, rhs) | ast::ExprIndex(ref lhs, ref rhs) |
ast::ExprBinary(_, lhs, rhs) if has_method_map => { ast::ExprBinary(_, ref lhs, ref rhs) if has_method_map => {
// As `expr_method_call`, but the call is via an // As `expr_method_call`, but the call is via an
// overloaded op. Note that we (sadly) currently use an // overloaded op. Note that we (sadly) currently use an
// implicit "by ref" sort of passing style here. This // implicit "by ref" sort of passing style here. This
// should be converted to an adjustment! // should be converted to an adjustment!
constrain_call(rcx, None, expr, Some(lhs), [rhs], true); constrain_call(rcx, None, expr, Some(lhs.clone()),
[rhs.clone()], true);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprUnary(_, lhs) if has_method_map => { ast::ExprUnary(_, ref lhs) if has_method_map => {
// As above. // As above.
constrain_call(rcx, None, expr, Some(lhs), [], true); constrain_call(rcx, None, expr, Some(lhs.clone()), [], true);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprUnary(ast::UnDeref, base) => { ast::ExprUnary(ast::UnDeref, ref base) => {
// For *a, the lifetime of a must enclose the deref // For *a, the lifetime of a must enclose the deref
let method_call = MethodCall::expr(expr.id); let method_call = MethodCall::expr(expr.id);
let base_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) { let base_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) {
Some(method) => { Some(method) => {
constrain_call(rcx, None, expr, Some(base), [], true); constrain_call(rcx, None, expr, Some(base.clone()), [], true);
ty::ty_fn_ret(method.ty) ty::ty_fn_ret(method.ty)
} }
None => rcx.resolve_node_type(base.id) None => rcx.resolve_node_type(base.id)
@ -516,15 +519,15 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprIndex(vec_expr, _) => { ast::ExprIndex(ref vec_expr, _) => {
// For a[b], the lifetime of a must enclose the deref // For a[b], the lifetime of a must enclose the deref
let vec_type = rcx.resolve_expr_type_adjusted(vec_expr); let vec_type = rcx.resolve_expr_type_adjusted(&**vec_expr);
constrain_index(rcx, expr, vec_type); constrain_index(rcx, expr, vec_type);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprCast(source, _) => { ast::ExprCast(ref source, _) => {
// Determine if we are casting `source` to a trait // Determine if we are casting `source` to a trait
// instance. If so, we have to be sure that the type of // instance. If so, we have to be sure that the type of
// the source obeys the trait's region bound. // the source obeys the trait's region bound.
@ -543,7 +546,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
ty::ty_trait(box ty::TyTrait { ty::ty_trait(box ty::TyTrait {
store: ty::RegionTraitStore(trait_region, _), .. store: ty::RegionTraitStore(trait_region, _), ..
}) => { }) => {
let source_ty = rcx.resolve_expr_type_adjusted(source); let source_ty = rcx.resolve_expr_type_adjusted(&**source);
constrain_regions_in_type( constrain_regions_in_type(
rcx, rcx,
trait_region, trait_region,
@ -556,8 +559,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprAddrOf(m, base) => { ast::ExprAddrOf(m, ref base) => {
link_addr_of(rcx, expr, m, base); link_addr_of(rcx, expr, m, &**base);
// Require that when you write a `&expr` expression, the // Require that when you write a `&expr` expression, the
// resulting pointer has a lifetime that encompasses the // resulting pointer has a lifetime that encompasses the
@ -572,8 +575,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
ast::ExprMatch(discr, ref arms) => { ast::ExprMatch(ref discr, ref arms) => {
link_match(rcx, discr, arms.as_slice()); link_match(rcx, &**discr, arms.as_slice());
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
} }
@ -582,18 +585,18 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
check_expr_fn_block(rcx, expr, &**body); check_expr_fn_block(rcx, expr, &**body);
} }
ast::ExprLoop(body, _) => { ast::ExprLoop(ref body, _) => {
let repeating_scope = rcx.set_repeating_scope(body.id); let repeating_scope = rcx.set_repeating_scope(body.id);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr, ());
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
ast::ExprWhile(cond, body) => { ast::ExprWhile(ref cond, ref body) => {
let repeating_scope = rcx.set_repeating_scope(cond.id); let repeating_scope = rcx.set_repeating_scope(cond.id);
rcx.visit_expr(cond, ()); rcx.visit_expr(&**cond, ());
rcx.set_repeating_scope(body.id); rcx.set_repeating_scope(body.id);
rcx.visit_block(body, ()); rcx.visit_block(&**body, ());
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
@ -785,8 +788,8 @@ fn constrain_call(rcx: &mut Rcx,
// operator // operator
fn_expr_id: Option<ast::NodeId>, fn_expr_id: Option<ast::NodeId>,
call_expr: &ast::Expr, call_expr: &ast::Expr,
receiver: Option<@ast::Expr>, receiver: Option<Gc<ast::Expr>>,
arg_exprs: &[@ast::Expr], arg_exprs: &[Gc<ast::Expr>],
implicitly_ref_args: bool) { implicitly_ref_args: bool) {
//! Invoked on every call site (i.e., normal calls, method calls, //! Invoked on every call site (i.e., normal calls, method calls,
//! and overloaded operators). Constrains the regions which appear //! and overloaded operators). Constrains the regions which appear
@ -820,7 +823,7 @@ fn constrain_call(rcx: &mut Rcx,
let callee_scope = call_expr.id; let callee_scope = call_expr.id;
let callee_region = ty::ReScope(callee_scope); let callee_region = ty::ReScope(callee_scope);
for &arg_expr in arg_exprs.iter() { for arg_expr in arg_exprs.iter() {
debug!("Argument"); debug!("Argument");
// ensure that any regions appearing in the argument type are // ensure that any regions appearing in the argument type are
@ -834,17 +837,17 @@ fn constrain_call(rcx: &mut Rcx,
// result. modes are going away and the "DerefArgs" code // result. modes are going away and the "DerefArgs" code
// should be ported to use adjustments // should be ported to use adjustments
if implicitly_ref_args { if implicitly_ref_args {
link_by_ref(rcx, arg_expr, callee_scope); link_by_ref(rcx, &**arg_expr, callee_scope);
} }
} }
// as loop above, but for receiver // as loop above, but for receiver
for &r in receiver.iter() { for r in receiver.iter() {
debug!("Receiver"); debug!("Receiver");
constrain_regions_in_type_of_node( constrain_regions_in_type_of_node(
rcx, r.id, callee_region, infer::CallRcvr(r.span)); rcx, r.id, callee_region, infer::CallRcvr(r.span));
if implicitly_ref_args { if implicitly_ref_args {
link_by_ref(rcx, r, callee_scope); link_by_ref(rcx, &**r, callee_scope);
} }
} }
@ -1054,11 +1057,11 @@ fn link_local(rcx: &Rcx, local: &ast::Local) {
debug!("regionck::for_local()"); debug!("regionck::for_local()");
let init_expr = match local.init { let init_expr = match local.init {
None => { return; } None => { return; }
Some(expr) => expr, Some(ref expr) => expr,
}; };
let mc = mc::MemCategorizationContext::new(rcx); let mc = mc::MemCategorizationContext::new(rcx);
let discr_cmt = ignore_err!(mc.cat_expr(init_expr)); let discr_cmt = ignore_err!(mc.cat_expr(&**init_expr));
link_pattern(rcx, mc, discr_cmt, local.pat); link_pattern(rcx, mc, discr_cmt, &*local.pat);
} }
fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
@ -1073,8 +1076,8 @@ fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
let discr_cmt = ignore_err!(mc.cat_expr(discr)); let discr_cmt = ignore_err!(mc.cat_expr(discr));
debug!("discr_cmt={}", discr_cmt.repr(rcx.tcx())); debug!("discr_cmt={}", discr_cmt.repr(rcx.tcx()));
for arm in arms.iter() { for arm in arms.iter() {
for &root_pat in arm.pats.iter() { for root_pat in arm.pats.iter() {
link_pattern(rcx, mc, discr_cmt.clone(), root_pat); link_pattern(rcx, mc, discr_cmt.clone(), &**root_pat);
} }
} }
} }
@ -1098,8 +1101,8 @@ fn link_pattern(rcx: &Rcx,
} }
// `[_, ..slice, _]` pattern // `[_, ..slice, _]` pattern
ast::PatVec(_, Some(slice_pat), _) => { ast::PatVec(_, Some(ref slice_pat), _) => {
match mc.cat_slice_pattern(sub_cmt, slice_pat) { match mc.cat_slice_pattern(sub_cmt, &**slice_pat) {
Ok((slice_cmt, slice_mutbl, slice_r)) => { Ok((slice_cmt, slice_mutbl, slice_r)) => {
link_region(rcx, sub_pat.span, slice_r, link_region(rcx, sub_pat.span, slice_r,
ty::BorrowKind::from_mutbl(slice_mutbl), ty::BorrowKind::from_mutbl(slice_mutbl),

View File

@ -666,10 +666,10 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
None => {} None => {}
} }
} }
ast::ExprCast(src, _) => { ast::ExprCast(ref src, _) => {
debug!("vtable resolution on expr {}", ex.repr(fcx.tcx())); debug!("vtable resolution on expr {}", ex.repr(fcx.tcx()));
let target_ty = fcx.expr_ty(ex); let target_ty = fcx.expr_ty(ex);
resolve_object_cast(src, target_ty); resolve_object_cast(&**src, target_ty);
} }
_ => () _ => ()
} }

View File

@ -53,10 +53,10 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
let mut wbcx = WritebackCx::new(fcx); let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_block(blk, ()); wbcx.visit_block(blk, ());
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
wbcx.visit_pat(arg.pat, ()); wbcx.visit_pat(&*arg.pat, ());
// Privacy needs the type for the whole pattern, not just each binding // Privacy needs the type for the whole pattern, not just each binding
if !pat_util::pat_is_binding(&fcx.tcx().def_map, arg.pat) { if !pat_util::pat_is_binding(&fcx.tcx().def_map, &*arg.pat) {
wbcx.visit_node_id(ResolvingPattern(arg.pat.span), wbcx.visit_node_id(ResolvingPattern(arg.pat.span),
arg.pat.id); arg.pat.id);
} }

View File

@ -129,6 +129,14 @@ fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
_ => {} _ => {}
} }
} }
ty_box(..) => {
match tcx.lang_items.gc() {
Some(did) if did.krate == ast::LOCAL_CRATE => {
found_nominal = true;
}
_ => {}
}
}
_ => { } _ => { }
} }
@ -203,8 +211,8 @@ impl<'a> visit::Visitor<()> for PrivilegedScopeVisitor<'a> {
// Then visit the module items. // Then visit the module items.
visit::walk_mod(self, module_, ()); visit::walk_mod(self, module_, ());
} }
ItemImpl(_, None, ast_ty, _) => { ItemImpl(_, None, ref ast_ty, _) => {
if !self.cc.ast_type_is_defined_in_local_crate(ast_ty) { if !self.cc.ast_type_is_defined_in_local_crate(&**ast_ty) {
// This is an error. // This is an error.
let session = &self.cc.crate_context.tcx.sess; let session = &self.cc.crate_context.tcx.sess;
session.span_err(item.span, session.span_err(item.span,

View File

@ -50,6 +50,8 @@ use util::ppaux::Repr;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
use syntax::abi; use syntax::abi;
use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound}; use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound};
use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound}; use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
@ -117,10 +119,10 @@ impl<'a> AstConv for CrateCtxt<'a> {
} }
match self.tcx.map.find(id.node) { match self.tcx.map.find(id.node) {
Some(ast_map::NodeItem(item)) => ty_of_item(self, item), Some(ast_map::NodeItem(item)) => ty_of_item(self, &*item),
Some(ast_map::NodeForeignItem(foreign_item)) => { Some(ast_map::NodeForeignItem(foreign_item)) => {
let abi = self.tcx.map.get_foreign_abi(id.node); let abi = self.tcx.map.get_foreign_abi(id.node);
ty_of_foreign_item(self, foreign_item, abi) ty_of_foreign_item(self, &*foreign_item, abi)
} }
x => { x => {
self.tcx.sess.bug(format!("unexpected sort of node \ self.tcx.sess.bug(format!("unexpected sort of node \
@ -156,7 +158,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
let result_ty = match variant.node.kind { let result_ty = match variant.node.kind {
ast::TupleVariantKind(ref args) if args.len() > 0 => { ast::TupleVariantKind(ref args) if args.len() > 0 => {
let rs = ExplicitRscope; let rs = ExplicitRscope;
let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, va.ty)).collect(); let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, &*va.ty)).collect();
ty::mk_ctor_fn(tcx, scope, input_tys.as_slice(), enum_ty) ty::mk_ctor_fn(tcx, scope, input_tys.as_slice(), enum_ty)
} }
@ -170,7 +172,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
ty: enum_ty ty: enum_ty
}; };
convert_struct(ccx, struct_def, tpt, variant.node.id); convert_struct(ccx, &*struct_def, tpt, variant.node.id);
let input_tys: Vec<_> = struct_def.fields.iter().map( let input_tys: Vec<_> = struct_def.fields.iter().map(
|f| ty::node_id_to_type(ccx.tcx, f.node.id)).collect(); |f| ty::node_id_to_type(ccx.tcx, f.node.id)).collect();
@ -205,14 +207,14 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
ty_method_of_trait_method( ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics, ccx, trait_id, &trait_ty_generics,
&m.id, &m.ident, &m.explicit_self, &m.id, &m.ident, &m.explicit_self,
&m.generics, &m.fn_style, m.decl) &m.generics, &m.fn_style, &*m.decl)
} }
&ast::Provided(ref m) => { &ast::Provided(ref m) => {
ty_method_of_trait_method( ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics, ccx, trait_id, &trait_ty_generics,
&m.id, &m.ident, &m.explicit_self, &m.id, &m.ident, &m.explicit_self,
&m.generics, &m.fn_style, m.decl) &m.generics, &m.fn_style, &*m.decl)
} }
}); });
@ -454,7 +456,7 @@ pub fn convert_field(ccx: &CrateCtxt,
struct_generics: &ty::Generics, struct_generics: &ty::Generics,
v: &ast::StructField, v: &ast::StructField,
origin: ast::DefId) -> ty::field_ty { origin: ast::DefId) -> ty::field_ty {
let tt = ccx.to_ty(&ExplicitRscope, v.node.ty); let tt = ccx.to_ty(&ExplicitRscope, &*v.node.ty);
write_ty_to_tcx(ccx.tcx, v.node.id, tt); write_ty_to_tcx(ccx.tcx, v.node.id, tt);
/* add the field to the tcache */ /* add the field to the tcache */
ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id), ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id),
@ -485,7 +487,7 @@ pub fn convert_field(ccx: &CrateCtxt,
fn convert_methods(ccx: &CrateCtxt, fn convert_methods(ccx: &CrateCtxt,
container: MethodContainer, container: MethodContainer,
ms: &[@ast::Method], ms: &[Gc<ast::Method>],
untransformed_rcvr_ty: ty::t, untransformed_rcvr_ty: ty::t,
rcvr_ty_generics: &ty::Generics, rcvr_ty_generics: &ty::Generics,
rcvr_ast_generics: &ast::Generics, rcvr_ast_generics: &ast::Generics,
@ -503,7 +505,7 @@ fn convert_methods(ccx: &CrateCtxt,
num_rcvr_ty_params); num_rcvr_ty_params);
let mty = Rc::new(ty_of_method(ccx, let mty = Rc::new(ty_of_method(ccx,
container, container,
*m, &**m,
untransformed_rcvr_ty, untransformed_rcvr_ty,
rcvr_ast_generics, rcvr_ast_generics,
rcvr_visibility)); rcvr_visibility));
@ -542,7 +544,7 @@ fn convert_methods(ccx: &CrateCtxt,
{ {
let fty = astconv::ty_of_method(ccx, m.id, m.fn_style, let fty = astconv::ty_of_method(ccx, m.id, m.fn_style,
untransformed_rcvr_ty, untransformed_rcvr_ty,
m.explicit_self, m.decl); m.explicit_self, &*m.decl);
// if the method specifies a visibility, use that, otherwise // if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl // inherit the visibility from the impl (so `foo` in `pub impl
@ -608,7 +610,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
}, },
ast::ItemImpl(ref generics, ref opt_trait_ref, selfty, ref ms) => { ast::ItemImpl(ref generics, ref opt_trait_ref, selfty, ref ms) => {
let ty_generics = ty_generics_for_type(ccx, generics); let ty_generics = ty_generics_for_type(ccx, generics);
let selfty = ccx.to_ty(&ExplicitRscope, selfty); let selfty = ccx.to_ty(&ExplicitRscope, &*selfty);
write_ty_to_tcx(tcx, it.id, selfty); write_ty_to_tcx(tcx, it.id, selfty);
tcx.tcache.borrow_mut().insert(local_def(it.id), tcx.tcache.borrow_mut().insert(local_def(it.id),
@ -671,13 +673,13 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
// Write the super-struct type, if it exists. // Write the super-struct type, if it exists.
match struct_def.super_struct { match struct_def.super_struct {
Some(ty) => { Some(ty) => {
let supserty = ccx.to_ty(&ExplicitRscope, ty); let supserty = ccx.to_ty(&ExplicitRscope, &*ty);
write_ty_to_tcx(tcx, it.id, supserty); write_ty_to_tcx(tcx, it.id, supserty);
}, },
_ => {}, _ => {},
} }
convert_struct(ccx, struct_def, tpt, it.id); convert_struct(ccx, &*struct_def, tpt, it.id);
}, },
ast::ItemTy(_, ref generics) => { ast::ItemTy(_, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "type"); ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
@ -855,7 +857,7 @@ fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc<ty::TraitDef> {
} }
match ccx.tcx.map.get(trait_id.node) { match ccx.tcx.map.get(trait_id.node) {
ast_map::NodeItem(item) => trait_def_of_item(ccx, item), ast_map::NodeItem(item) => trait_def_of_item(ccx, &*item),
_ => { _ => {
ccx.tcx.sess.bug(format!("get_trait_def({}): not an item", ccx.tcx.sess.bug(format!("get_trait_def({}): not an item",
trait_id.node).as_slice()) trait_id.node).as_slice())
@ -910,7 +912,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
} }
match it.node { match it.node {
ast::ItemStatic(t, _, _) => { ast::ItemStatic(t, _, _) => {
let typ = ccx.to_ty(&ExplicitRscope, t); let typ = ccx.to_ty(&ExplicitRscope, &*t);
let tpt = no_params(typ); let tpt = no_params(typ);
tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone()); tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
@ -922,7 +924,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
it.id, it.id,
fn_style, fn_style,
abi, abi,
decl); &*decl);
let tpt = ty_param_bounds_and_ty { let tpt = ty_param_bounds_and_ty {
generics: ty_generics, generics: ty_generics,
ty: ty::mk_bare_fn(ccx.tcx, tofd) ty: ty::mk_bare_fn(ccx.tcx, tofd)
@ -942,7 +944,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
} }
let tpt = { let tpt = {
let ty = ccx.to_ty(&ExplicitRscope, t); let ty = ccx.to_ty(&ExplicitRscope, &*t);
ty_param_bounds_and_ty { ty_param_bounds_and_ty {
generics: ty_generics_for_type(ccx, generics), generics: ty_generics_for_type(ccx, generics),
ty: ty ty: ty
@ -992,7 +994,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
match it.node { match it.node {
ast::ForeignItemFn(fn_decl, ref generics) => { ast::ForeignItemFn(fn_decl, ref generics) => {
ty_of_foreign_fn_decl(ccx, ty_of_foreign_fn_decl(ccx,
fn_decl, &*fn_decl,
local_def(it.id), local_def(it.id),
generics, generics,
abi) abi)
@ -1003,7 +1005,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
type_param_defs: Rc::new(Vec::new()), type_param_defs: Rc::new(Vec::new()),
region_param_defs: Rc::new(Vec::new()), region_param_defs: Rc::new(Vec::new()),
}, },
ty: ast_ty_to_ty(ccx, &ExplicitRscope, t) ty: ast_ty_to_ty(ccx, &ExplicitRscope, &*t)
} }
} }
} }
@ -1047,7 +1049,7 @@ fn ty_generics(ccx: &CrateCtxt,
param.ident, param.ident,
param.span)); param.span));
let default = param.default.map(|path| { let default = param.default.map(|path| {
let ty = ast_ty_to_ty(ccx, &ExplicitRscope, path); let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &*path);
let cur_idx = param_ty.idx; let cur_idx = param_ty.idx;
ty::walk_ty(ty, |t| { ty::walk_ty(ty, |t| {
@ -1201,7 +1203,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
.map(|a| ty_of_arg(ccx, &rb, a, None)) .map(|a| ty_of_arg(ccx, &rb, a, None))
.collect(); .collect();
let output_ty = ast_ty_to_ty(ccx, &rb, decl.output); let output_ty = ast_ty_to_ty(ccx, &rb, &*decl.output);
let t_fn = ty::mk_bare_fn( let t_fn = ty::mk_bare_fn(
ccx.tcx, ccx.tcx,

View File

@ -1140,7 +1140,7 @@ impl<'a> Rebuilder<'a> {
} }
ref other => other.clone() ref other => other.clone()
}; };
@ast::Ty { id: from.id, node: new_node, span: from.span } box(GC) ast::Ty { id: from.id, node: new_node, span: from.span }
} }
let new_ty_node = match to.node { let new_ty_node = match to.node {
@ -1155,7 +1155,7 @@ impl<'a> Rebuilder<'a> {
} }
_ => fail!("expect ast::TyRptr or ast::TyPath") _ => fail!("expect ast::TyRptr or ast::TyPath")
}; };
let new_ty = @ast::Ty { let new_ty = box(GC) ast::Ty {
id: to.id, id: to.id,
node: new_ty_node, node: new_ty_node,
span: to.span span: to.span

View File

@ -479,13 +479,13 @@ impl<'a> Visitor<()> for ConstraintContext<'a> {
// `ty::VariantInfo::from_ast_variant()` ourselves // `ty::VariantInfo::from_ast_variant()` ourselves
// here, mainly so as to mask the differences between // here, mainly so as to mask the differences between
// struct-like enums and so forth. // struct-like enums and so forth.
for &ast_variant in enum_definition.variants.iter() { for ast_variant in enum_definition.variants.iter() {
let variant = let variant =
ty::VariantInfo::from_ast_variant(tcx, ty::VariantInfo::from_ast_variant(tcx,
ast_variant, &**ast_variant,
/*discriminant*/ 0); /*discriminant*/ 0);
for &arg_ty in variant.args.iter() { for arg_ty in variant.args.iter() {
self.add_constraints_from_ty(arg_ty, self.covariant); self.add_constraints_from_ty(*arg_ty, self.covariant);
} }
} }
} }

View File

@ -102,6 +102,6 @@ pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
p: p, p: p,
flag: false, flag: false,
}; };
visit::walk_block(&mut v, b, ()); visit::walk_block(&mut v, &*b, ());
return v.flag; return v.flag;
} }

View File

@ -25,7 +25,7 @@ use middle::ty;
use middle::typeck; use middle::typeck;
use std::rc::Rc; use std::rc::Rc;
use std::string::String; use std::gc::Gc;
use syntax::abi; use syntax::abi;
use syntax::ast_map; use syntax::ast_map;
use syntax::codemap::{Span, Pos}; use syntax::codemap::{Span, Pos};
@ -510,7 +510,7 @@ impl<T:Repr> Repr for Rc<T> {
} }
} }
impl<T:Repr> Repr for @T { impl<T:Repr + 'static> Repr for Gc<T> {
fn repr(&self, tcx: &ctxt) -> String { fn repr(&self, tcx: &ctxt) -> String {
(&**self).repr(tcx) (&**self).repr(tcx)
} }

View File

@ -31,6 +31,7 @@ use rustc::middle::ty;
use std::rc::Rc; use std::rc::Rc;
use std::u32; use std::u32;
use std::gc::Gc;
use core; use core;
use doctree; use doctree;
@ -52,7 +53,7 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for Vec<T> {
} }
} }
impl<T: Clean<U>, U> Clean<U> for @T { impl<T: Clean<U>, U> Clean<U> for Gc<T> {
fn clean(&self) -> U { fn clean(&self) -> U {
(**self).clean() (**self).clean()
} }
@ -428,12 +429,12 @@ impl attr::AttrMetaMethods for Attribute {
_ => None, _ => None,
} }
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@ast::MetaItem]> { None } fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
} }
impl<'a> attr::AttrMetaMethods for &'a Attribute { impl<'a> attr::AttrMetaMethods for &'a Attribute {
fn name(&self) -> InternedString { (**self).name() } fn name(&self) -> InternedString { (**self).name() }
fn value_str(&self) -> Option<InternedString> { (**self).value_str() } fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@ast::MetaItem]> { None } fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
} }
#[deriving(Clone, Encodable, Decodable)] #[deriving(Clone, Encodable, Decodable)]
@ -864,7 +865,7 @@ pub struct Argument {
impl Clean<Argument> for ast::Arg { impl Clean<Argument> for ast::Arg {
fn clean(&self) -> Argument { fn clean(&self) -> Argument {
Argument { Argument {
name: name_from_pat(self.pat), name: name_from_pat(&*self.pat),
type_: (self.ty.clean()), type_: (self.ty.clean()),
id: self.id id: self.id
} }
@ -1745,7 +1746,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
remaining, remaining,
b.clone()); b.clone());
let path = syntax::codemap::dummy_spanned(path); let path = syntax::codemap::dummy_spanned(path);
ret.push(convert(&ast::ViewItemUse(@path))); ret.push(convert(&ast::ViewItemUse(box(GC) path)));
} }
} }
ast::ViewPathSimple(_, _, id) => { ast::ViewPathSimple(_, _, id) => {
@ -1913,8 +1914,8 @@ fn name_from_pat(p: &ast::Pat) -> String {
PatStruct(..) => fail!("tried to get argument name from pat_struct, \ PatStruct(..) => fail!("tried to get argument name from pat_struct, \
which is not allowed in function arguments"), which is not allowed in function arguments"),
PatTup(..) => "(tuple arg NYI)".to_string(), PatTup(..) => "(tuple arg NYI)".to_string(),
PatBox(p) => name_from_pat(p), PatBox(p) => name_from_pat(&*p),
PatRegion(p) => name_from_pat(p), PatRegion(p) => name_from_pat(&*p),
PatLit(..) => { PatLit(..) => {
warn!("tried to get argument name from PatLit, \ warn!("tried to get argument name from PatLit, \
which is silly in function arguments"); which is silly in function arguments");

View File

@ -95,7 +95,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
let mut cfg = build_configuration(&sess); let mut cfg = build_configuration(&sess);
for cfg_ in cfgs.move_iter() { for cfg_ in cfgs.move_iter() {
let cfg_ = token::intern_and_get_ident(cfg_.as_slice()); let cfg_ = token::intern_and_get_ident(cfg_.as_slice());
cfg.push(@dummy_spanned(ast::MetaWord(cfg_))); cfg.push(box(GC) dummy_spanned(ast::MetaWord(cfg_)));
} }
let krate = phase_1_parse_input(&sess, cfg, &input); let krate = phase_1_parse_input(&sess, cfg, &input);
@ -128,11 +128,11 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
pub fn run_core(libs: HashSet<Path>, cfgs: Vec<String>, path: &Path) pub fn run_core(libs: HashSet<Path>, cfgs: Vec<String>, path: &Path)
-> (clean::Crate, CrateAnalysis) { -> (clean::Crate, CrateAnalysis) {
let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs); let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs);
let ctxt = @ctxt; let ctxt = box(GC) ctxt;
super::ctxtkey.replace(Some(ctxt)); super::ctxtkey.replace(Some(ctxt));
let krate = { let krate = {
let mut v = RustdocVisitor::new(ctxt, Some(&analysis)); let mut v = RustdocVisitor::new(&*ctxt, Some(&analysis));
v.visit(&ctxt.krate); v.visit(&ctxt.krate);
v.clean() v.clean()
}; };

View File

@ -16,6 +16,8 @@ use syntax::codemap::Span;
use syntax::ast; use syntax::ast;
use syntax::ast::{Ident, NodeId}; use syntax::ast::{Ident, NodeId};
use std::gc::Gc;
pub struct Module { pub struct Module {
pub name: Option<Ident>, pub name: Option<Ident>,
pub attrs: Vec<ast::Attribute>, pub attrs: Vec<ast::Attribute>,
@ -133,7 +135,7 @@ pub struct Typedef {
pub struct Static { pub struct Static {
pub type_: ast::P<ast::Ty>, pub type_: ast::P<ast::Ty>,
pub mutability: ast::Mutability, pub mutability: ast::Mutability,
pub expr: @ast::Expr, pub expr: Gc<ast::Expr>,
pub name: Ident, pub name: Ident,
pub attrs: Vec<ast::Attribute>, pub attrs: Vec<ast::Attribute>,
pub vis: ast::Visibility, pub vis: ast::Visibility,
@ -156,7 +158,7 @@ pub struct Impl {
pub generics: ast::Generics, pub generics: ast::Generics,
pub trait_: Option<ast::TraitRef>, pub trait_: Option<ast::TraitRef>,
pub for_: ast::P<ast::Ty>, pub for_: ast::P<ast::Ty>,
pub methods: Vec<@ast::Method>, pub methods: Vec<Gc<ast::Method>>,
pub attrs: Vec<ast::Attribute>, pub attrs: Vec<ast::Attribute>,
pub where: Span, pub where: Span,
pub vis: ast::Visibility, pub vis: ast::Visibility,

View File

@ -37,6 +37,7 @@ extern crate log;
use std::io; use std::io;
use std::io::{File, MemWriter}; use std::io::{File, MemWriter};
use std::str; use std::str;
use std::gc::Gc;
use serialize::{json, Decodable, Encodable}; use serialize::{json, Decodable, Encodable};
// reexported from `clean` so it can be easily updated with the mod itself // reexported from `clean` so it can be easily updated with the mod itself
@ -85,7 +86,7 @@ static DEFAULT_PASSES: &'static [&'static str] = &[
"unindent-comments", "unindent-comments",
]; ];
local_data_key!(pub ctxtkey: @core::DocContext) local_data_key!(pub ctxtkey: Gc<core::DocContext>)
local_data_key!(pub analysiskey: core::CrateAnalysis) local_data_key!(pub analysiskey: core::CrateAnalysis)
type Output = (clean::Crate, Vec<plugins::PluginJson> ); type Output = (clean::Crate, Vec<plugins::PluginJson> );

View File

@ -64,13 +64,13 @@ pub fn run(input: &str,
let mut cfg = config::build_configuration(&sess); let mut cfg = config::build_configuration(&sess);
cfg.extend(cfgs.move_iter().map(|cfg_| { cfg.extend(cfgs.move_iter().map(|cfg_| {
let cfg_ = token::intern_and_get_ident(cfg_.as_slice()); let cfg_ = token::intern_and_get_ident(cfg_.as_slice());
@dummy_spanned(ast::MetaWord(cfg_)) box(GC) dummy_spanned(ast::MetaWord(cfg_))
})); }));
let krate = driver::phase_1_parse_input(&sess, cfg, &input); let krate = driver::phase_1_parse_input(&sess, cfg, &input);
let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate, let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
&from_str("rustdoc-test").unwrap()); &from_str("rustdoc-test").unwrap());
let ctx = @core::DocContext { let ctx = box(GC) core::DocContext {
krate: krate, krate: krate,
maybe_typed: core::NotTyped(sess), maybe_typed: core::NotTyped(sess),
src: input_path, src: input_path,
@ -82,7 +82,7 @@ pub fn run(input: &str,
}; };
super::ctxtkey.replace(Some(ctx)); super::ctxtkey.replace(Some(ctx));
let mut v = RustdocVisitor::new(ctx, None); let mut v = RustdocVisitor::new(&*ctx, None);
v.visit(&ctx.krate); v.visit(&ctx.krate);
let krate = v.clean(); let krate = v.clean();
let (krate, _) = passes::unindent_comments(krate); let (krate, _) = passes::unindent_comments(krate);

View File

@ -18,6 +18,8 @@ use syntax::ast_map;
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span; use syntax::codemap::Span;
use std::gc::Gc;
use core; use core;
use doctree::*; use doctree::*;
@ -54,10 +56,10 @@ impl<'a> RustdocVisitor<'a> {
self.module.is_crate = true; self.module.is_crate = true;
} }
pub fn visit_struct_def(&mut self, item: &ast::Item, sd: @ast::StructDef, pub fn visit_struct_def(&mut self, item: &ast::Item, sd: Gc<ast::StructDef>,
generics: &ast::Generics) -> Struct { generics: &ast::Generics) -> Struct {
debug!("Visiting struct"); debug!("Visiting struct");
let struct_type = struct_type_from_def(sd); let struct_type = struct_type_from_def(&*sd);
Struct { Struct {
id: item.id, id: item.id,
struct_type: struct_type, struct_type: struct_type,
@ -125,7 +127,7 @@ impl<'a> RustdocVisitor<'a> {
om.vis = vis; om.vis = vis;
om.id = id; om.id = id;
for i in m.items.iter() { for i in m.items.iter() {
self.visit_item(*i, &mut om); self.visit_item(&**i, &mut om);
} }
om om
} }
@ -159,9 +161,9 @@ impl<'a> RustdocVisitor<'a> {
om.view_items.push(item); om.view_items.push(item);
} }
fn visit_view_path(&mut self, path: @ast::ViewPath, fn visit_view_path(&mut self, path: Gc<ast::ViewPath>,
om: &mut Module, om: &mut Module,
please_inline: bool) -> Option<@ast::ViewPath> { please_inline: bool) -> Option<Gc<ast::ViewPath>> {
match path.node { match path.node {
ast::ViewPathSimple(_, _, id) => { ast::ViewPathSimple(_, _, id) => {
if self.resolve_id(id, false, om, please_inline) { return None } if self.resolve_id(id, false, om, please_inline) { return None }
@ -175,7 +177,7 @@ impl<'a> RustdocVisitor<'a> {
} }
if mine.len() == 0 { return None } if mine.len() == 0 { return None }
return Some(@::syntax::codemap::Spanned { return Some(box(GC) ::syntax::codemap::Spanned {
node: ast::ViewPathList(p.clone(), mine, b.clone()), node: ast::ViewPathList(p.clone(), mine, b.clone()),
span: path.span, span: path.span,
}) })
@ -213,13 +215,13 @@ impl<'a> RustdocVisitor<'a> {
self.visit_view_item(vi, om); self.visit_view_item(vi, om);
} }
for i in m.items.iter() { for i in m.items.iter() {
self.visit_item(*i, om); self.visit_item(&**i, om);
} }
} }
_ => { fail!("glob not mapped to a module"); } _ => { fail!("glob not mapped to a module"); }
} }
} else { } else {
self.visit_item(it, om); self.visit_item(&*it, om);
} }
true true
} }
@ -245,8 +247,8 @@ impl<'a> RustdocVisitor<'a> {
om.enums.push(self.visit_enum_def(item, ed, gen)), om.enums.push(self.visit_enum_def(item, ed, gen)),
ast::ItemStruct(sd, ref gen) => ast::ItemStruct(sd, ref gen) =>
om.structs.push(self.visit_struct_def(item, sd, gen)), om.structs.push(self.visit_struct_def(item, sd, gen)),
ast::ItemFn(fd, ref pur, ref abi, ref gen, _) => ast::ItemFn(ref fd, ref pur, ref abi, ref gen, _) =>
om.fns.push(self.visit_fn(item, fd, pur, abi, gen)), om.fns.push(self.visit_fn(item, &**fd, pur, abi, gen)),
ast::ItemTy(ty, ref gen) => { ast::ItemTy(ty, ref gen) => {
let t = Typedef { let t = Typedef {
ty: ty, ty: ty,

View File

@ -16,6 +16,7 @@ Core encoding and decoding interfaces.
use std::path; use std::path;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
pub trait Encoder<E> { pub trait Encoder<E> {
// Primitive types: // Primitive types:
@ -387,7 +388,7 @@ impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Box<T> {
} }
} }
impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for @T { impl<E, S:Encoder<E>,T:'static + Encodable<S, E>> Encodable<S, E> for Gc<T> {
fn encode(&self, s: &mut S) -> Result<(), E> { fn encode(&self, s: &mut S) -> Result<(), E> {
(**self).encode(s) (**self).encode(s)
} }
@ -407,9 +408,9 @@ impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Rc<T> {
} }
} }
impl<E, D:Decoder<E>,T:Decodable<D, E> + 'static> Decodable<D, E> for @T { impl<E, D:Decoder<E>,T:Decodable<D, E> + 'static> Decodable<D, E> for Gc<T> {
fn decode(d: &mut D) -> Result<@T, E> { fn decode(d: &mut D) -> Result<Gc<T>, E> {
Ok(@try!(Decodable::decode(d))) Ok(box(GC) try!(Decodable::decode(d)))
} }
} }

View File

@ -18,52 +18,32 @@ collector is task-local so `Gc<T>` is not sendable.
#![allow(experimental)] #![allow(experimental)]
use kinds::marker;
use clone::Clone; use clone::Clone;
use cmp::{Ord, PartialOrd, Ordering, Eq, PartialEq};
use default::Default;
use fmt;
use hash;
use kinds::marker;
use ops::Deref;
use raw;
/// Immutable garbage-collected pointer type /// Immutable garbage-collected pointer type
#[lang="gc"] #[lang="gc"]
#[cfg(not(test))]
#[experimental = "Gc is currently based on reference-counting and will not collect cycles until \ #[experimental = "Gc is currently based on reference-counting and will not collect cycles until \
task annihilation. For now, cycles need to be broken manually by using `Rc<T>` \ task annihilation. For now, cycles need to be broken manually by using `Rc<T>` \
with a non-owning `Weak<T>` pointer. A tracing garbage collector is planned."] with a non-owning `Weak<T>` pointer. A tracing garbage collector is planned."]
pub struct Gc<T> { pub struct Gc<T> {
#[cfg(stage0)]
ptr: @T, ptr: @T,
#[cfg(not(stage0))]
_ptr: *T,
marker: marker::NoSend, marker: marker::NoSend,
} }
#[cfg(test)]
pub struct Gc<T> {
ptr: @T,
marker: marker::NoSend,
}
impl<T: 'static> Gc<T> {
/// Construct a new garbage-collected box
#[inline]
pub fn new(value: T) -> Gc<T> {
Gc { ptr: @value, marker: marker::NoSend }
}
/// Borrow the value contained in the garbage-collected box
#[inline]
pub fn borrow<'r>(&'r self) -> &'r T {
&*self.ptr
}
/// Determine if two garbage-collected boxes point to the same object
#[inline]
pub fn ptr_eq(&self, other: &Gc<T>) -> bool {
self.borrow() as *T == other.borrow() as *T
}
}
impl<T> Clone for Gc<T> { impl<T> Clone for Gc<T> {
/// Clone the pointer only /// Clone the pointer only
#[inline] #[inline]
fn clone(&self) -> Gc<T> { fn clone(&self) -> Gc<T> { *self }
Gc{ ptr: self.ptr, marker: marker::NoSend }
}
} }
/// An value that represents the task-local managed heap. /// An value that represents the task-local managed heap.
@ -73,8 +53,54 @@ impl<T> Clone for Gc<T> {
#[cfg(not(test))] #[cfg(not(test))]
pub static GC: () = (); pub static GC: () = ();
#[cfg(test)] impl<T: PartialEq + 'static> PartialEq for Gc<T> {
pub static GC: () = (); #[inline]
fn eq(&self, other: &Gc<T>) -> bool { *(*self) == *(*other) }
#[inline]
fn ne(&self, other: &Gc<T>) -> bool { *(*self) != *(*other) }
}
impl<T: PartialOrd + 'static> PartialOrd for Gc<T> {
#[inline]
fn lt(&self, other: &Gc<T>) -> bool { *(*self) < *(*other) }
#[inline]
fn le(&self, other: &Gc<T>) -> bool { *(*self) <= *(*other) }
#[inline]
fn ge(&self, other: &Gc<T>) -> bool { *(*self) >= *(*other) }
#[inline]
fn gt(&self, other: &Gc<T>) -> bool { *(*self) > *(*other) }
}
impl<T: Ord + 'static> Ord for Gc<T> {
#[inline]
fn cmp(&self, other: &Gc<T>) -> Ordering { (**self).cmp(&**other) }
}
impl<T: Eq + 'static> Eq for Gc<T> {}
impl<T: 'static> Deref<T> for Gc<T> {
#[cfg(stage0)]
fn deref<'a>(&'a self) -> &'a T { &*self.ptr }
#[cfg(not(stage0))]
fn deref<'a>(&'a self) -> &'a T { &**self }
}
impl<T: Default + 'static> Default for Gc<T> {
fn default() -> Gc<T> {
box(GC) Default::default()
}
}
impl<T: 'static> raw::Repr<*raw::Box<T>> for Gc<T> {}
impl<S: hash::Writer, T: hash::Hash<S> + 'static> hash::Hash<S> for Gc<T> {
fn hash(&self, s: &mut S) {
(**self).hash(s)
}
}
impl<T: 'static + fmt::Show> fmt::Show for Gc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -135,6 +135,8 @@ extern crate rustrt;
#[cfg(test)] pub use realstd::ops; #[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp; #[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::ty; #[cfg(test)] pub use realstd::ty;
#[cfg(test)] pub use realstd::owned;
#[cfg(test)] pub use realstd::gc;
// NB: These reexports are in the order they should be listed in rustdoc // NB: These reexports are in the order they should be listed in rustdoc
@ -219,6 +221,7 @@ pub mod rand;
pub mod ascii; pub mod ascii;
#[cfg(not(test))]
pub mod gc; pub mod gc;
/* Common traits */ /* Common traits */

View File

@ -21,15 +21,16 @@ use std::fmt;
use std::fmt::Show; use std::fmt::Show;
use std::option::Option; use std::option::Option;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
/// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future. /// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
pub type P<T> = @T; pub type P<T> = Gc<T>;
#[allow(non_snake_case_functions)] #[allow(non_snake_case_functions)]
/// Construct a P<T> from a T value. /// Construct a P<T> from a T value.
pub fn P<T: 'static>(value: T) -> P<T> { pub fn P<T: 'static>(value: T) -> P<T> {
@value box(GC) value
} }
// FIXME #6993: in librustc, uses of "ident" should be replaced // FIXME #6993: in librustc, uses of "ident" should be replaced
@ -217,7 +218,7 @@ pub enum DefRegion {
// The set of MetaItems that define the compilation environment of the crate, // The set of MetaItems that define the compilation environment of the crate,
// used to drive conditional compilation // used to drive conditional compilation
pub type CrateConfig = Vec<@MetaItem> ; pub type CrateConfig = Vec<Gc<MetaItem>>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Crate { pub struct Crate {
@ -232,7 +233,7 @@ pub type MetaItem = Spanned<MetaItem_>;
#[deriving(Clone, Encodable, Decodable, Eq, Hash)] #[deriving(Clone, Encodable, Decodable, Eq, Hash)]
pub enum MetaItem_ { pub enum MetaItem_ {
MetaWord(InternedString), MetaWord(InternedString),
MetaList(InternedString, Vec<@MetaItem> ), MetaList(InternedString, Vec<Gc<MetaItem>>),
MetaNameValue(InternedString, Lit), MetaNameValue(InternedString, Lit),
} }
@ -264,8 +265,8 @@ impl PartialEq for MetaItem_ {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Block { pub struct Block {
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub stmts: Vec<@Stmt>, pub stmts: Vec<Gc<Stmt>>,
pub expr: Option<@Expr>, pub expr: Option<Gc<Expr>>,
pub id: NodeId, pub id: NodeId,
pub rules: BlockCheckMode, pub rules: BlockCheckMode,
pub span: Span, pub span: Span,
@ -281,7 +282,7 @@ pub struct Pat {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct FieldPat { pub struct FieldPat {
pub ident: Ident, pub ident: Ident,
pub pat: @Pat, pub pat: Gc<Pat>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -301,18 +302,18 @@ pub enum Pat_ {
// which it is. The resolver determines this, and // which it is. The resolver determines this, and
// records this pattern's NodeId in an auxiliary // records this pattern's NodeId in an auxiliary
// set (of "pat_idents that refer to nullary enums") // set (of "pat_idents that refer to nullary enums")
PatIdent(BindingMode, Path, Option<@Pat>), PatIdent(BindingMode, Path, Option<Gc<Pat>>),
PatEnum(Path, Option<Vec<@Pat> >), /* "none" means a * pattern where PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
* we don't bind the fields to names */ * we don't bind the fields to names */
PatStruct(Path, Vec<FieldPat> , bool), PatStruct(Path, Vec<FieldPat>, bool),
PatTup(Vec<@Pat> ), PatTup(Vec<Gc<Pat>>),
PatBox(@Pat), PatBox(Gc<Pat>),
PatRegion(@Pat), // reference pattern PatRegion(Gc<Pat>), // reference pattern
PatLit(@Expr), PatLit(Gc<Expr>),
PatRange(@Expr, @Expr), PatRange(Gc<Expr>, Gc<Expr>),
// [a, b, ..i, y, z] is represented as // [a, b, ..i, y, z] is represented as
// PatVec(~[a, b], Some(i), ~[y, z]) // PatVec(~[a, b], Some(i), ~[y, z])
PatVec(Vec<@Pat> , Option<@Pat>, Vec<@Pat> ), PatVec(Vec<Gc<Pat>>, Option<Gc<Pat>>, Vec<Gc<Pat>>),
PatMac(Mac), PatMac(Mac),
} }
@ -365,13 +366,13 @@ pub type Stmt = Spanned<Stmt_>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Stmt_ { pub enum Stmt_ {
// could be an item or a local (let) binding: // could be an item or a local (let) binding:
StmtDecl(@Decl, NodeId), StmtDecl(Gc<Decl>, NodeId),
// expr without trailing semi-colon (must have unit type): // expr without trailing semi-colon (must have unit type):
StmtExpr(@Expr, NodeId), StmtExpr(Gc<Expr>, NodeId),
// expr with trailing semi-colon (may have any type): // expr with trailing semi-colon (may have any type):
StmtSemi(@Expr, NodeId), StmtSemi(Gc<Expr>, NodeId),
// bool: is there a trailing sem-colon? // bool: is there a trailing sem-colon?
StmtMac(Mac, bool), StmtMac(Mac, bool),
@ -391,8 +392,8 @@ pub enum LocalSource {
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Local { pub struct Local {
pub ty: P<Ty>, pub ty: P<Ty>,
pub pat: @Pat, pub pat: Gc<Pat>,
pub init: Option<@Expr>, pub init: Option<Gc<Expr>>,
pub id: NodeId, pub id: NodeId,
pub span: Span, pub span: Span,
pub source: LocalSource, pub source: LocalSource,
@ -403,23 +404,23 @@ pub type Decl = Spanned<Decl_>;
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Decl_ { pub enum Decl_ {
// a local (let) binding: // a local (let) binding:
DeclLocal(@Local), DeclLocal(Gc<Local>),
// an item binding: // an item binding:
DeclItem(@Item), DeclItem(Gc<Item>),
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Arm { pub struct Arm {
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
pub pats: Vec<@Pat>, pub pats: Vec<Gc<Pat>>,
pub guard: Option<@Expr>, pub guard: Option<Gc<Expr>>,
pub body: @Expr, pub body: Gc<Expr>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Field { pub struct Field {
pub ident: SpannedIdent, pub ident: SpannedIdent,
pub expr: @Expr, pub expr: Gc<Expr>,
pub span: Span, pub span: Span,
} }
@ -446,56 +447,56 @@ pub struct Expr {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Expr_ { pub enum Expr_ {
ExprVstore(@Expr, ExprVstore), ExprVstore(Gc<Expr>, ExprVstore),
// First expr is the place; second expr is the value. // First expr is the place; second expr is the value.
ExprBox(@Expr, @Expr), ExprBox(Gc<Expr>, Gc<Expr>),
ExprVec(Vec<@Expr>), ExprVec(Vec<Gc<Expr>>),
ExprCall(@Expr, Vec<@Expr>), ExprCall(Gc<Expr>, Vec<Gc<Expr>>),
ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<@Expr>), ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<Gc<Expr>>),
ExprTup(Vec<@Expr>), ExprTup(Vec<Gc<Expr>>),
ExprBinary(BinOp, @Expr, @Expr), ExprBinary(BinOp, Gc<Expr>, Gc<Expr>),
ExprUnary(UnOp, @Expr), ExprUnary(UnOp, Gc<Expr>),
ExprLit(@Lit), ExprLit(Gc<Lit>),
ExprCast(@Expr, P<Ty>), ExprCast(Gc<Expr>, P<Ty>),
ExprIf(@Expr, P<Block>, Option<@Expr>), ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
ExprWhile(@Expr, P<Block>), ExprWhile(Gc<Expr>, P<Block>),
// FIXME #6993: change to Option<Name> // FIXME #6993: change to Option<Name>
ExprForLoop(@Pat, @Expr, P<Block>, Option<Ident>), ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>),
// Conditionless loop (can be exited with break, cont, or ret) // Conditionless loop (can be exited with break, cont, or ret)
// FIXME #6993: change to Option<Name> // FIXME #6993: change to Option<Name>
ExprLoop(P<Block>, Option<Ident>), ExprLoop(P<Block>, Option<Ident>),
ExprMatch(@Expr, Vec<Arm>), ExprMatch(Gc<Expr>, Vec<Arm>),
ExprFnBlock(P<FnDecl>, P<Block>), ExprFnBlock(P<FnDecl>, P<Block>),
ExprProc(P<FnDecl>, P<Block>), ExprProc(P<FnDecl>, P<Block>),
ExprBlock(P<Block>), ExprBlock(P<Block>),
ExprAssign(@Expr, @Expr), ExprAssign(Gc<Expr>, Gc<Expr>),
ExprAssignOp(BinOp, @Expr, @Expr), ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
ExprField(@Expr, Ident, Vec<P<Ty>>), ExprField(Gc<Expr>, Ident, Vec<P<Ty>>),
ExprIndex(@Expr, @Expr), ExprIndex(Gc<Expr>, Gc<Expr>),
/// Expression that looks like a "name". For example, /// Expression that looks like a "name". For example,
/// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part /// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
/// of a function call. /// of a function call.
ExprPath(Path), ExprPath(Path),
ExprAddrOf(Mutability, @Expr), ExprAddrOf(Mutability, Gc<Expr>),
ExprBreak(Option<Ident>), ExprBreak(Option<Ident>),
ExprAgain(Option<Ident>), ExprAgain(Option<Ident>),
ExprRet(Option<@Expr>), ExprRet(Option<Gc<Expr>>),
ExprInlineAsm(InlineAsm), ExprInlineAsm(InlineAsm),
ExprMac(Mac), ExprMac(Mac),
// A struct literal expression. // A struct literal expression.
ExprStruct(Path, Vec<Field> , Option<@Expr> /* base */), ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
// A vector literal constructed from one repeated element. // A vector literal constructed from one repeated element.
ExprRepeat(@Expr /* element */, @Expr /* count */), ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
// No-op: used solely so we can pretty-print faithfully // No-op: used solely so we can pretty-print faithfully
ExprParen(@Expr) ExprParen(Gc<Expr>)
} }
// When the main rust parser encounters a syntax-extension invocation, it // When the main rust parser encounters a syntax-extension invocation, it
@ -667,7 +668,7 @@ pub struct TypeMethod {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum TraitMethod { pub enum TraitMethod {
Required(TypeMethod), Required(TypeMethod),
Provided(@Method), Provided(Gc<Method>),
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -782,16 +783,16 @@ pub enum Ty_ {
TyBox(P<Ty>), TyBox(P<Ty>),
TyUniq(P<Ty>), TyUniq(P<Ty>),
TyVec(P<Ty>), TyVec(P<Ty>),
TyFixedLengthVec(P<Ty>, @Expr), TyFixedLengthVec(P<Ty>, Gc<Expr>),
TyPtr(MutTy), TyPtr(MutTy),
TyRptr(Option<Lifetime>, MutTy), TyRptr(Option<Lifetime>, MutTy),
TyClosure(@ClosureTy, Option<Lifetime>), TyClosure(Gc<ClosureTy>, Option<Lifetime>),
TyProc(@ClosureTy), TyProc(Gc<ClosureTy>),
TyBareFn(@BareFnTy), TyBareFn(Gc<BareFnTy>),
TyUnboxedFn(@UnboxedFnTy), TyUnboxedFn(Gc<UnboxedFnTy>),
TyTup(Vec<P<Ty>> ), TyTup(Vec<P<Ty>> ),
TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
TyTypeof(@Expr), TyTypeof(Gc<Expr>),
// TyInfer means the type should be inferred instead of it having been // TyInfer means the type should be inferred instead of it having been
// specified. This can appear anywhere in a type. // specified. This can appear anywhere in a type.
TyInfer, TyInfer,
@ -808,8 +809,8 @@ pub struct InlineAsm {
pub asm: InternedString, pub asm: InternedString,
pub asm_str_style: StrStyle, pub asm_str_style: StrStyle,
pub clobbers: InternedString, pub clobbers: InternedString,
pub inputs: Vec<(InternedString, @Expr)>, pub inputs: Vec<(InternedString, Gc<Expr>)>,
pub outputs: Vec<(InternedString, @Expr)>, pub outputs: Vec<(InternedString, Gc<Expr>)>,
pub volatile: bool, pub volatile: bool,
pub alignstack: bool, pub alignstack: bool,
pub dialect: AsmDialect pub dialect: AsmDialect
@ -818,7 +819,7 @@ pub struct InlineAsm {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Arg { pub struct Arg {
pub ty: P<Ty>, pub ty: P<Ty>,
pub pat: @Pat, pub pat: Gc<Pat>,
pub id: NodeId, pub id: NodeId,
} }
@ -832,7 +833,7 @@ impl Arg {
node: TyInfer, node: TyInfer,
span: DUMMY_SP, span: DUMMY_SP,
}), }),
pat: @Pat { pat: box(GC) Pat {
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
node: PatIdent(BindByValue(mutability), path, None), node: PatIdent(BindByValue(mutability), path, None),
span: span span: span
@ -903,14 +904,14 @@ pub struct Mod {
/// to the last token in the external file. /// to the last token in the external file.
pub inner: Span, pub inner: Span,
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub items: Vec<@Item>, pub items: Vec<Gc<Item>>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct ForeignMod { pub struct ForeignMod {
pub abi: Abi, pub abi: Abi,
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub items: Vec<@ForeignItem>, pub items: Vec<Gc<ForeignItem>>,
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -922,7 +923,7 @@ pub struct VariantArg {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum VariantKind { pub enum VariantKind {
TupleVariantKind(Vec<VariantArg>), TupleVariantKind(Vec<VariantArg>),
StructVariantKind(@StructDef), StructVariantKind(Gc<StructDef>),
} }
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@ -936,7 +937,7 @@ pub struct Variant_ {
pub attrs: Vec<Attribute>, pub attrs: Vec<Attribute>,
pub kind: VariantKind, pub kind: VariantKind,
pub id: NodeId, pub id: NodeId,
pub disr_expr: Option<@Expr>, pub disr_expr: Option<Gc<Expr>>,
pub vis: Visibility, pub vis: Visibility,
} }
@ -984,7 +985,7 @@ pub enum ViewItem_ {
// (containing arbitrary characters) from which to fetch the crate sources // (containing arbitrary characters) from which to fetch the crate sources
// For example, extern crate whatever = "github.com/mozilla/rust" // For example, extern crate whatever = "github.com/mozilla/rust"
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId), ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
ViewItemUse(@ViewPath), ViewItemUse(Gc<ViewPath>),
} }
// Meta-data associated with an item // Meta-data associated with an item
@ -1007,7 +1008,7 @@ pub struct AttrId(pub uint);
pub struct Attribute_ { pub struct Attribute_ {
pub id: AttrId, pub id: AttrId,
pub style: AttrStyle, pub style: AttrStyle,
pub value: @MetaItem, pub value: Gc<MetaItem>,
pub is_sugared_doc: bool, pub is_sugared_doc: bool,
} }
@ -1105,18 +1106,18 @@ pub struct Item {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Item_ { pub enum Item_ {
ItemStatic(P<Ty>, Mutability, @Expr), ItemStatic(P<Ty>, Mutability, Gc<Expr>),
ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>), ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
ItemMod(Mod), ItemMod(Mod),
ItemForeignMod(ForeignMod), ItemForeignMod(ForeignMod),
ItemTy(P<Ty>, Generics), ItemTy(P<Ty>, Generics),
ItemEnum(EnumDef, Generics), ItemEnum(EnumDef, Generics),
ItemStruct(@StructDef, Generics), ItemStruct(Gc<StructDef>, Generics),
ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ), ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
ItemImpl(Generics, ItemImpl(Generics,
Option<TraitRef>, // (optional) trait this impl implements Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self P<Ty>, // self
Vec<@Method> ), Vec<Gc<Method>>),
// a macro invocation (which includes macro definition) // a macro invocation (which includes macro definition)
ItemMac(Mac), ItemMac(Mac),
} }
@ -1142,9 +1143,9 @@ pub enum ForeignItem_ {
// that we trans. // that we trans.
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)] #[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum InlinedItem { pub enum InlinedItem {
IIItem(@Item), IIItem(Gc<Item>),
IIMethod(DefId /* impl id */, bool /* is provided */, @Method), IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
IIForeign(@ForeignItem), IIForeign(Gc<ForeignItem>),
} }
#[cfg(test)] #[cfg(test)]

View File

@ -20,9 +20,9 @@ use util::small_vector::SmallVector;
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt; use std::fmt;
use std::gc::Gc;
use std::iter; use std::iter;
use std::slice; use std::slice;
use std::string::String;
#[deriving(Clone, PartialEq)] #[deriving(Clone, PartialEq)]
pub enum PathElem { pub enum PathElem {
@ -94,22 +94,22 @@ pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> String {
#[deriving(Clone)] #[deriving(Clone)]
pub enum Node { pub enum Node {
NodeItem(@Item), NodeItem(Gc<Item>),
NodeForeignItem(@ForeignItem), NodeForeignItem(Gc<ForeignItem>),
NodeTraitMethod(@TraitMethod), NodeTraitMethod(Gc<TraitMethod>),
NodeMethod(@Method), NodeMethod(Gc<Method>),
NodeVariant(P<Variant>), NodeVariant(P<Variant>),
NodeExpr(@Expr), NodeExpr(Gc<Expr>),
NodeStmt(@Stmt), NodeStmt(Gc<Stmt>),
NodeArg(@Pat), NodeArg(Gc<Pat>),
NodeLocal(@Pat), NodeLocal(Gc<Pat>),
NodePat(@Pat), NodePat(Gc<Pat>),
NodeBlock(P<Block>), NodeBlock(P<Block>),
/// NodeStructCtor represents a tuple struct. /// NodeStructCtor represents a tuple struct.
NodeStructCtor(@StructDef), NodeStructCtor(Gc<StructDef>),
NodeLifetime(@Lifetime), NodeLifetime(Gc<Lifetime>),
} }
// The odd layout is to bring down the total size. // The odd layout is to bring down the total size.
@ -119,19 +119,19 @@ enum MapEntry {
NotPresent, NotPresent,
// All the node types, with a parent ID. // All the node types, with a parent ID.
EntryItem(NodeId, @Item), EntryItem(NodeId, Gc<Item>),
EntryForeignItem(NodeId, @ForeignItem), EntryForeignItem(NodeId, Gc<ForeignItem>),
EntryTraitMethod(NodeId, @TraitMethod), EntryTraitMethod(NodeId, Gc<TraitMethod>),
EntryMethod(NodeId, @Method), EntryMethod(NodeId, Gc<Method>),
EntryVariant(NodeId, P<Variant>), EntryVariant(NodeId, P<Variant>),
EntryExpr(NodeId, @Expr), EntryExpr(NodeId, Gc<Expr>),
EntryStmt(NodeId, @Stmt), EntryStmt(NodeId, Gc<Stmt>),
EntryArg(NodeId, @Pat), EntryArg(NodeId, Gc<Pat>),
EntryLocal(NodeId, @Pat), EntryLocal(NodeId, Gc<Pat>),
EntryPat(NodeId, @Pat), EntryPat(NodeId, Gc<Pat>),
EntryBlock(NodeId, P<Block>), EntryBlock(NodeId, P<Block>),
EntryStructCtor(NodeId, @StructDef), EntryStructCtor(NodeId, Gc<StructDef>),
EntryLifetime(NodeId, @Lifetime), EntryLifetime(NodeId, Gc<Lifetime>),
// Roots for node trees. // Roots for node trees.
RootCrate, RootCrate,
@ -262,14 +262,14 @@ impl Map {
} }
} }
pub fn expect_item(&self, id: NodeId) -> @Item { pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
match self.find(id) { match self.find(id) {
Some(NodeItem(item)) => item, Some(NodeItem(item)) => item,
_ => fail!("expected item, found {}", self.node_to_str(id)) _ => fail!("expected item, found {}", self.node_to_str(id))
} }
} }
pub fn expect_struct(&self, id: NodeId) -> @StructDef { pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
match self.find(id) { match self.find(id) {
Some(NodeItem(i)) => { Some(NodeItem(i)) => {
match i.node { match i.node {
@ -294,7 +294,7 @@ impl Map {
} }
} }
pub fn expect_foreign_item(&self, id: NodeId) -> @ForeignItem { pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
match self.find(id) { match self.find(id) {
Some(NodeForeignItem(item)) => item, Some(NodeForeignItem(item)) => item,
_ => fail!("expected foreign item, found {}", self.node_to_str(id)) _ => fail!("expected foreign item, found {}", self.node_to_str(id))
@ -457,11 +457,11 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
self.fold_ops.new_span(span) self.fold_ops.new_span(span)
} }
fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> { fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
let parent = self.parent; let parent = self.parent;
self.parent = DUMMY_NODE_ID; self.parent = DUMMY_NODE_ID;
let i = fold::noop_fold_item(i, self).expect_one("expected one item"); let i = fold::noop_fold_item(&*i, self).expect_one("expected one item");
assert_eq!(self.parent, i.id); assert_eq!(self.parent, i.id);
match i.node { match i.node {
@ -476,16 +476,17 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
} }
} }
ItemForeignMod(ref nm) => { ItemForeignMod(ref nm) => {
for &nitem in nm.items.iter() { for nitem in nm.items.iter() {
self.insert(nitem.id, EntryForeignItem(self.parent, nitem)); self.insert(nitem.id, EntryForeignItem(self.parent,
nitem.clone()));
} }
} }
ItemStruct(struct_def, _) => { ItemStruct(ref struct_def, _) => {
// If this is a tuple-like struct, register the constructor. // If this is a tuple-like struct, register the constructor.
match struct_def.ctor_id { match struct_def.ctor_id {
Some(ctor_id) => { Some(ctor_id) => {
self.insert(ctor_id, EntryStructCtor(self.parent, self.insert(ctor_id, EntryStructCtor(self.parent,
struct_def)); struct_def.clone()));
} }
None => {} None => {}
} }
@ -499,11 +500,11 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
match *tm { match *tm {
Required(ref m) => { Required(ref m) => {
self.insert(m.id, EntryTraitMethod(self.parent, self.insert(m.id, EntryTraitMethod(self.parent,
@(*tm).clone())); box(GC) (*tm).clone()));
} }
Provided(m) => { Provided(m) => {
self.insert(m.id, EntryTraitMethod(self.parent, self.insert(m.id, EntryTraitMethod(self.parent,
@Provided(m))); box(GC) Provided(m)));
} }
} }
} }
@ -517,7 +518,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
SmallVector::one(i) SmallVector::one(i)
} }
fn fold_pat(&mut self, pat: @Pat) -> @Pat { fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
let pat = fold::noop_fold_pat(pat, self); let pat = fold::noop_fold_pat(pat, self);
match pat.node { match pat.node {
PatIdent(..) => { PatIdent(..) => {
@ -532,7 +533,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
pat pat
} }
fn fold_expr(&mut self, expr: @Expr) -> @Expr { fn fold_expr(&mut self, expr: Gc<Expr>) -> Gc<Expr> {
let expr = fold::noop_fold_expr(expr, self); let expr = fold::noop_fold_expr(expr, self);
self.insert(expr.id, EntryExpr(self.parent, expr)); self.insert(expr.id, EntryExpr(self.parent, expr));
@ -540,9 +541,9 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
expr expr
} }
fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<@Stmt> { fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<Gc<Stmt>> {
let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement"); let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
self.insert(ast_util::stmt_id(stmt), EntryStmt(self.parent, stmt)); self.insert(ast_util::stmt_id(&*stmt), EntryStmt(self.parent, stmt));
SmallVector::one(stmt) SmallVector::one(stmt)
} }
@ -555,10 +556,10 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
m m
} }
fn fold_method(&mut self, m: @Method) -> @Method { fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
let parent = self.parent; let parent = self.parent;
self.parent = DUMMY_NODE_ID; self.parent = DUMMY_NODE_ID;
let m = fold::noop_fold_method(m, self); let m = fold::noop_fold_method(&*m, self);
assert_eq!(self.parent, m.id); assert_eq!(self.parent, m.id);
self.parent = parent; self.parent = parent;
m m
@ -580,7 +581,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime { fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
let lifetime = fold::noop_fold_lifetime(lifetime, self); let lifetime = fold::noop_fold_lifetime(lifetime, self);
self.insert(lifetime.id, EntryLifetime(self.parent, @lifetime)); self.insert(lifetime.id, EntryLifetime(self.parent, box(GC) lifetime));
lifetime lifetime
} }
} }
@ -643,7 +644,7 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
IIItem(_) => {} IIItem(_) => {}
IIMethod(impl_did, is_provided, m) => { IIMethod(impl_did, is_provided, m) => {
let entry = if is_provided { let entry = if is_provided {
EntryTraitMethod(cx.parent, @Provided(m)) EntryTraitMethod(cx.parent, box(GC) Provided(m))
} else { } else {
EntryMethod(cx.parent, m) EntryMethod(cx.parent, m)
}; };
@ -701,28 +702,28 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
token::get_ident(variant.node.name), token::get_ident(variant.node.name),
map.path_to_str(id), id)).to_string() map.path_to_str(id), id)).to_string()
} }
Some(NodeExpr(expr)) => { Some(NodeExpr(ref expr)) => {
(format!("expr {} (id={})", (format!("expr {} (id={})",
pprust::expr_to_str(expr), id)).to_string() pprust::expr_to_str(&**expr), id)).to_string()
} }
Some(NodeStmt(stmt)) => { Some(NodeStmt(ref stmt)) => {
(format!("stmt {} (id={})", (format!("stmt {} (id={})",
pprust::stmt_to_str(stmt), id)).to_string() pprust::stmt_to_str(&**stmt), id)).to_string()
} }
Some(NodeArg(pat)) => { Some(NodeArg(ref pat)) => {
(format!("arg {} (id={})", (format!("arg {} (id={})",
pprust::pat_to_str(pat), id)).to_string() pprust::pat_to_str(&**pat), id)).to_string()
} }
Some(NodeLocal(pat)) => { Some(NodeLocal(ref pat)) => {
(format!("local {} (id={})", (format!("local {} (id={})",
pprust::pat_to_str(pat), id)).to_string() pprust::pat_to_str(&**pat), id)).to_string()
} }
Some(NodePat(pat)) => { Some(NodePat(ref pat)) => {
(format!("pat {} (id={})", pprust::pat_to_str(pat), id)).to_string() (format!("pat {} (id={})", pprust::pat_to_str(&**pat), id)).to_string()
} }
Some(NodeBlock(block)) => { Some(NodeBlock(ref block)) => {
(format!("block {} (id={})", (format!("block {} (id={})",
pprust::block_to_str(block), id)).to_string() pprust::block_to_str(&**block), id)).to_string()
} }
Some(NodeStructCtor(_)) => { Some(NodeStructCtor(_)) => {
(format!("struct_ctor {} (id={})", (format!("struct_ctor {} (id={})",
@ -730,7 +731,7 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
} }
Some(NodeLifetime(ref l)) => { Some(NodeLifetime(ref l)) => {
(format!("lifetime {} (id={})", (format!("lifetime {} (id={})",
pprust::lifetime_to_str(*l), id)).to_string() pprust::lifetime_to_str(&**l), id)).to_string()
} }
None => { None => {
(format!("unknown node (id={})", id)).to_string() (format!("unknown node (id={})", id)).to_string()

View File

@ -21,7 +21,7 @@ use visit;
use std::cell::Cell; use std::cell::Cell;
use std::cmp; use std::cmp;
use std::string::String; use std::gc::Gc;
use std::u32; use std::u32;
pub fn path_name_i(idents: &[Ident]) -> String { pub fn path_name_i(idents: &[Ident]) -> String {
@ -93,7 +93,7 @@ pub fn is_shift_binop(b: BinOp) -> bool {
pub fn unop_to_str(op: UnOp) -> &'static str { pub fn unop_to_str(op: UnOp) -> &'static str {
match op { match op {
UnBox => "@", UnBox => "box(GC) ",
UnUniq => "box() ", UnUniq => "box() ",
UnDeref => "*", UnDeref => "*",
UnNot => "!", UnNot => "!",
@ -101,7 +101,7 @@ pub fn unop_to_str(op: UnOp) -> &'static str {
} }
} }
pub fn is_path(e: @Expr) -> bool { pub fn is_path(e: Gc<Expr>) -> bool {
return match e.node { ExprPath(_) => true, _ => false }; return match e.node { ExprPath(_) => true, _ => false };
} }
@ -181,11 +181,11 @@ pub fn float_ty_to_str(t: FloatTy) -> String {
} }
} }
pub fn is_call_expr(e: @Expr) -> bool { pub fn is_call_expr(e: Gc<Expr>) -> bool {
match e.node { ExprCall(..) => true, _ => false } match e.node { ExprCall(..) => true, _ => false }
} }
pub fn block_from_expr(e: @Expr) -> P<Block> { pub fn block_from_expr(e: Gc<Expr>) -> P<Block> {
P(Block { P(Block {
view_items: Vec::new(), view_items: Vec::new(),
stmts: Vec::new(), stmts: Vec::new(),
@ -210,8 +210,8 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
} }
} }
pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> @Pat { pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> Gc<Pat> {
@ast::Pat { id: id, box(GC) ast::Pat { id: id,
node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None), node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None),
span: s } span: s }
} }
@ -229,7 +229,7 @@ pub fn is_unguarded(a: &Arm) -> bool {
} }
} }
pub fn unguarded_pat(a: &Arm) -> Option<Vec<@Pat> > { pub fn unguarded_pat(a: &Arm) -> Option<Vec<Gc<Pat>>> {
if is_unguarded(a) { if is_unguarded(a) {
Some(/* FIXME (#2543) */ a.pats.clone()) Some(/* FIXME (#2543) */ a.pats.clone())
} else { } else {
@ -254,7 +254,7 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
token::gensym_ident(pretty.as_slice()) token::gensym_ident(pretty.as_slice())
} }
pub fn public_methods(ms: Vec<@Method> ) -> Vec<@Method> { pub fn public_methods(ms: Vec<Gc<Method>> ) -> Vec<Gc<Method>> {
ms.move_iter().filter(|m| { ms.move_iter().filter(|m| {
match m.vis { match m.vis {
Public => true, Public => true,
@ -285,7 +285,7 @@ pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
} }
pub fn split_trait_methods(trait_methods: &[TraitMethod]) pub fn split_trait_methods(trait_methods: &[TraitMethod])
-> (Vec<TypeMethod> , Vec<@Method> ) { -> (Vec<TypeMethod> , Vec<Gc<Method>> ) {
let mut reqd = Vec::new(); let mut reqd = Vec::new();
let mut provd = Vec::new(); let mut provd = Vec::new();
for trt_method in trait_methods.iter() { for trt_method in trait_methods.iter() {
@ -610,7 +610,7 @@ pub fn compute_id_range_for_fn_body(fk: &visit::FnKind,
visitor.result.get() visitor.result.get()
} }
pub fn is_item_impl(item: @ast::Item) -> bool { pub fn is_item_impl(item: Gc<ast::Item>) -> bool {
match item.node { match item.node {
ItemImpl(..) => true, ItemImpl(..) => true,
_ => false _ => false
@ -623,20 +623,20 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
} }
match pat.node { match pat.node {
PatIdent(_, _, Some(p)) => walk_pat(p, it), PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
PatStruct(_, ref fields, _) => { PatStruct(_, ref fields, _) => {
fields.iter().advance(|f| walk_pat(f.pat, |p| it(p))) fields.iter().advance(|f| walk_pat(&*f.pat, |p| it(p)))
} }
PatEnum(_, Some(ref s)) | PatTup(ref s) => { PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().advance(|&p| walk_pat(p, |p| it(p))) s.iter().advance(|p| walk_pat(&**p, |p| it(p)))
} }
PatBox(s) | PatRegion(s) => { PatBox(ref s) | PatRegion(ref s) => {
walk_pat(s, it) walk_pat(&**s, it)
} }
PatVec(ref before, ref slice, ref after) => { PatVec(ref before, ref slice, ref after) => {
before.iter().advance(|&p| walk_pat(p, |p| it(p))) && before.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
slice.iter().advance(|&p| walk_pat(p, |p| it(p))) && slice.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
after.iter().advance(|&p| walk_pat(p, |p| it(p))) after.iter().advance(|p| walk_pat(&**p, |p| it(p)))
} }
PatMac(_) => fail!("attempted to analyze unexpanded pattern"), PatMac(_) => fail!("attempted to analyze unexpanded pattern"),
PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) | PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
@ -685,7 +685,7 @@ pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
/// Returns true if the given pattern consists solely of an identifier /// Returns true if the given pattern consists solely of an identifier
/// and false otherwise. /// and false otherwise.
pub fn pat_is_ident(pat: @ast::Pat) -> bool { pub fn pat_is_ident(pat: Gc<ast::Pat>) -> bool {
match pat.node { match pat.node {
ast::PatIdent(..) => true, ast::PatIdent(..) => true,
_ => false, _ => false,
@ -720,7 +720,7 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
} }
// Returns true if this literal is a string and false otherwise. // Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: @Lit) -> bool { pub fn lit_is_str(lit: Gc<Lit>) -> bool {
match lit.node { match lit.node {
LitStr(..) => true, LitStr(..) => true,
_ => false, _ => false,

View File

@ -22,6 +22,7 @@ use crateid::CrateId;
use std::collections::HashSet; use std::collections::HashSet;
use std::collections::BitvSet; use std::collections::BitvSet;
use std::gc::Gc;
local_data_key!(used_attrs: BitvSet) local_data_key!(used_attrs: BitvSet)
@ -52,7 +53,7 @@ pub trait AttrMetaMethods {
*/ */
fn value_str(&self) -> Option<InternedString>; fn value_str(&self) -> Option<InternedString>;
/// Gets a list of inner meta items from a list MetaItem type. /// Gets a list of inner meta items from a list MetaItem type.
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]>; fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]>;
} }
impl AttrMetaMethods for Attribute { impl AttrMetaMethods for Attribute {
@ -67,7 +68,7 @@ impl AttrMetaMethods for Attribute {
fn value_str(&self) -> Option<InternedString> { fn value_str(&self) -> Option<InternedString> {
self.meta().value_str() self.meta().value_str()
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> {
self.node.value.meta_item_list() self.node.value.meta_item_list()
} }
} }
@ -93,7 +94,7 @@ impl AttrMetaMethods for MetaItem {
} }
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> {
match self.node { match self.node {
MetaList(_, ref l) => Some(l.as_slice()), MetaList(_, ref l) => Some(l.as_slice()),
_ => None _ => None
@ -102,23 +103,23 @@ impl AttrMetaMethods for MetaItem {
} }
// Annoying, but required to get test_cfg to work // Annoying, but required to get test_cfg to work
impl AttrMetaMethods for @MetaItem { impl AttrMetaMethods for Gc<MetaItem> {
fn name(&self) -> InternedString { (**self).name() } fn name(&self) -> InternedString { (**self).name() }
fn value_str(&self) -> Option<InternedString> { (**self).value_str() } fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> {
(**self).meta_item_list() (**self).meta_item_list()
} }
} }
pub trait AttributeMethods { pub trait AttributeMethods {
fn meta(&self) -> @MetaItem; fn meta(&self) -> Gc<MetaItem>;
fn desugar_doc(&self) -> Attribute; fn desugar_doc(&self) -> Attribute;
} }
impl AttributeMethods for Attribute { impl AttributeMethods for Attribute {
/// Extract the MetaItem from inside this Attribute. /// Extract the MetaItem from inside this Attribute.
fn meta(&self) -> @MetaItem { fn meta(&self) -> Gc<MetaItem> {
self.node.value self.node.value
} }
@ -146,22 +147,23 @@ impl AttributeMethods for Attribute {
/* Constructors */ /* Constructors */
pub fn mk_name_value_item_str(name: InternedString, value: InternedString) pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
-> @MetaItem { -> Gc<MetaItem> {
let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr)); let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr));
mk_name_value_item(name, value_lit) mk_name_value_item(name, value_lit)
} }
pub fn mk_name_value_item(name: InternedString, value: ast::Lit) pub fn mk_name_value_item(name: InternedString, value: ast::Lit)
-> @MetaItem { -> Gc<MetaItem> {
@dummy_spanned(MetaNameValue(name, value)) box(GC) dummy_spanned(MetaNameValue(name, value))
} }
pub fn mk_list_item(name: InternedString, items: Vec<@MetaItem> ) -> @MetaItem { pub fn mk_list_item(name: InternedString,
@dummy_spanned(MetaList(name, items)) items: Vec<Gc<MetaItem>>) -> Gc<MetaItem> {
box(GC) dummy_spanned(MetaList(name, items))
} }
pub fn mk_word_item(name: InternedString) -> @MetaItem { pub fn mk_word_item(name: InternedString) -> Gc<MetaItem> {
@dummy_spanned(MetaWord(name)) box(GC) dummy_spanned(MetaWord(name))
} }
local_data_key!(next_attr_id: uint) local_data_key!(next_attr_id: uint)
@ -173,7 +175,7 @@ pub fn mk_attr_id() -> AttrId {
} }
/// Returns an inner attribute with the given value. /// Returns an inner attribute with the given value.
pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute { pub fn mk_attr_inner(id: AttrId, item: Gc<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ { dummy_spanned(Attribute_ {
id: id, id: id,
style: ast::AttrInner, style: ast::AttrInner,
@ -183,7 +185,7 @@ pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute {
} }
/// Returns an outer attribute with the given value. /// Returns an outer attribute with the given value.
pub fn mk_attr_outer(id: AttrId, item: @MetaItem) -> Attribute { pub fn mk_attr_outer(id: AttrId, item: Gc<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ { dummy_spanned(Attribute_ {
id: id, id: id,
style: ast::AttrOuter, style: ast::AttrOuter,
@ -200,7 +202,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
let attr = Attribute_ { let attr = Attribute_ {
id: id, id: id,
style: style, style: style,
value: @spanned(lo, hi, MetaNameValue(InternedString::new("doc"), value: box(GC) spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
lit)), lit)),
is_sugared_doc: true is_sugared_doc: true
}; };
@ -211,8 +213,8 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
/// Check if `needle` occurs in `haystack` by a structural /// Check if `needle` occurs in `haystack` by a structural
/// comparison. This is slightly subtle, and relies on ignoring the /// comparison. This is slightly subtle, and relies on ignoring the
/// span included in the `==` comparison a plain MetaItem. /// span included in the `==` comparison a plain MetaItem.
pub fn contains(haystack: &[@ast::MetaItem], pub fn contains(haystack: &[Gc<ast::MetaItem>],
needle: @ast::MetaItem) -> bool { needle: Gc<ast::MetaItem>) -> bool {
debug!("attr::contains (name={})", needle.name()); debug!("attr::contains (name={})", needle.name());
haystack.iter().any(|item| { haystack.iter().any(|item| {
debug!(" testing: {}", item.name()); debug!(" testing: {}", item.name());
@ -235,7 +237,7 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
.and_then(|at| at.value_str()) .and_then(|at| at.value_str())
} }
pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str) pub fn last_meta_item_value_str_by_name(items: &[Gc<MetaItem>], name: &str)
-> Option<InternedString> { -> Option<InternedString> {
items.iter() items.iter()
.rev() .rev()
@ -245,12 +247,12 @@ pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str)
/* Higher-level applications */ /* Higher-level applications */
pub fn sort_meta_items(items: &[@MetaItem]) -> Vec<@MetaItem> { pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
// This is sort of stupid here, but we need to sort by // This is sort of stupid here, but we need to sort by
// human-readable strings. // human-readable strings.
let mut v = items.iter() let mut v = items.iter()
.map(|&mi| (mi.name(), mi)) .map(|&mi| (mi.name(), mi))
.collect::<Vec<(InternedString, @MetaItem)> >(); .collect::<Vec<(InternedString, Gc<MetaItem>)> >();
v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b)); v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
@ -258,7 +260,7 @@ pub fn sort_meta_items(items: &[@MetaItem]) -> Vec<@MetaItem> {
v.move_iter().map(|(_, m)| { v.move_iter().map(|(_, m)| {
match m.node { match m.node {
MetaList(ref n, ref mis) => { MetaList(ref n, ref mis) => {
@Spanned { box(GC) Spanned {
node: MetaList((*n).clone(), node: MetaList((*n).clone(),
sort_meta_items(mis.as_slice())), sort_meta_items(mis.as_slice())),
.. /*bad*/ (*m).clone() .. /*bad*/ (*m).clone()
@ -273,7 +275,7 @@ pub fn sort_meta_items(items: &[@MetaItem]) -> Vec<@MetaItem> {
* From a list of crate attributes get only the meta_items that affect crate * From a list of crate attributes get only the meta_items that affect crate
* linkage * linkage
*/ */
pub fn find_linkage_metas(attrs: &[Attribute]) -> Vec<@MetaItem> { pub fn find_linkage_metas(attrs: &[Attribute]) -> Vec<Gc<MetaItem>> {
let mut result = Vec::new(); let mut result = Vec::new();
for attr in attrs.iter().filter(|at| at.check_name("link")) { for attr in attrs.iter().filter(|at| at.check_name("link")) {
match attr.meta().node { match attr.meta().node {
@ -330,7 +332,7 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true /// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false /// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false
pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>> pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>>
(cfg: &[@MetaItem], mut metas: It) -> bool { (cfg: &[Gc<MetaItem>], mut metas: It) -> bool {
// having no #[cfg(...)] attributes counts as matching. // having no #[cfg(...)] attributes counts as matching.
let mut no_cfgs = true; let mut no_cfgs = true;
@ -422,7 +424,7 @@ pub fn find_stability(attrs: &[Attribute]) -> Option<Stability> {
}) })
} }
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[@MetaItem]) { pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[Gc<MetaItem>]) {
let mut set = HashSet::new(); let mut set = HashSet::new();
for meta in metas.iter() { for meta in metas.iter() {
let name = meta.name(); let name = meta.name();

View File

@ -23,8 +23,8 @@ source code snippets, etc.
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use std::rc::Rc; use std::rc::Rc;
use std::string::String;
pub trait Pos { pub trait Pos {
fn from_uint(n: uint) -> Self; fn from_uint(n: uint) -> Self;
@ -91,7 +91,7 @@ pub struct Span {
pub hi: BytePos, pub hi: BytePos,
/// Information about where the macro came from, if this piece of /// Information about where the macro came from, if this piece of
/// code was created by a macro expansion. /// code was created by a macro expansion.
pub expn_info: Option<@ExpnInfo> pub expn_info: Option<Gc<ExpnInfo>>
} }
pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None }; pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };

View File

@ -20,7 +20,6 @@ use parse;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
enum State { enum State {
Asm, Asm,
Outputs, Outputs,
@ -214,7 +213,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
out)); out));
} }
MacExpr::new(@ast::Expr { MacExpr::new(box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprInlineAsm(ast::InlineAsm { node: ast::ExprInlineAsm(ast::InlineAsm {
asm: token::intern_and_get_ident(asm.get()), asm: token::intern_and_get_ident(asm.get()),

View File

@ -20,6 +20,7 @@ use parse::token::{InternedString, intern, str_to_ident};
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use std::collections::HashMap; use std::collections::HashMap;
use std::gc::Gc;
// new-style macro! tt code: // new-style macro! tt code:
// //
@ -35,10 +36,10 @@ pub struct MacroDef {
} }
pub type ItemDecorator = pub type ItemDecorator =
fn(&mut ExtCtxt, Span, @ast::MetaItem, @ast::Item, |@ast::Item|); fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>, |Gc<ast::Item>|);
pub type ItemModifier = pub type ItemModifier =
fn(&mut ExtCtxt, Span, @ast::MetaItem, @ast::Item) -> @ast::Item; fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>) -> Gc<ast::Item>;
pub struct BasicMacroExpander { pub struct BasicMacroExpander {
pub expander: MacroExpanderFn, pub expander: MacroExpanderFn,
@ -104,15 +105,15 @@ pub trait MacResult {
None None
} }
/// Create an expression. /// Create an expression.
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
None None
} }
/// Create zero or more items. /// Create zero or more items.
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
None None
} }
/// Create a pattern. /// Create a pattern.
fn make_pat(&self) -> Option<@ast::Pat> { fn make_pat(&self) -> Option<Gc<ast::Pat>> {
None None
} }
@ -120,58 +121,58 @@ pub trait MacResult {
/// ///
/// By default this attempts to create an expression statement, /// By default this attempts to create an expression statement,
/// returning None if that fails. /// returning None if that fails.
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
self.make_expr() self.make_expr()
.map(|e| @codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))) .map(|e| box(GC) codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID)))
} }
} }
/// A convenience type for macros that return a single expression. /// A convenience type for macros that return a single expression.
pub struct MacExpr { pub struct MacExpr {
e: @ast::Expr e: Gc<ast::Expr>,
} }
impl MacExpr { impl MacExpr {
pub fn new(e: @ast::Expr) -> Box<MacResult> { pub fn new(e: Gc<ast::Expr>) -> Box<MacResult> {
box MacExpr { e: e } as Box<MacResult> box MacExpr { e: e } as Box<MacResult>
} }
} }
impl MacResult for MacExpr { impl MacResult for MacExpr {
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
Some(self.e) Some(self.e)
} }
} }
/// A convenience type for macros that return a single pattern. /// A convenience type for macros that return a single pattern.
pub struct MacPat { pub struct MacPat {
p: @ast::Pat p: Gc<ast::Pat>,
} }
impl MacPat { impl MacPat {
pub fn new(p: @ast::Pat) -> Box<MacResult> { pub fn new(p: Gc<ast::Pat>) -> Box<MacResult> {
box MacPat { p: p } as Box<MacResult> box MacPat { p: p } as Box<MacResult>
} }
} }
impl MacResult for MacPat { impl MacResult for MacPat {
fn make_pat(&self) -> Option<@ast::Pat> { fn make_pat(&self) -> Option<Gc<ast::Pat>> {
Some(self.p) Some(self.p)
} }
} }
/// A convenience type for macros that return a single item. /// A convenience type for macros that return a single item.
pub struct MacItem { pub struct MacItem {
i: @ast::Item i: Gc<ast::Item>
} }
impl MacItem { impl MacItem {
pub fn new(i: @ast::Item) -> Box<MacResult> { pub fn new(i: Gc<ast::Item>) -> Box<MacResult> {
box MacItem { i: i } as Box<MacResult> box MacItem { i: i } as Box<MacResult>
} }
} }
impl MacResult for MacItem { impl MacResult for MacItem {
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
Some(SmallVector::one(self.i)) Some(SmallVector::one(self.i))
} }
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
Some(@codemap::respan( Some(box(GC) codemap::respan(
self.i.span, self.i.span,
ast::StmtDecl( ast::StmtDecl(
@codemap::respan(self.i.span, ast::DeclItem(self.i)), box(GC) codemap::respan(self.i.span, ast::DeclItem(self.i)),
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
} }
} }
@ -202,17 +203,17 @@ impl DummyResult {
} }
/// A plain dummy expression. /// A plain dummy expression.
pub fn raw_expr(sp: Span) -> @ast::Expr { pub fn raw_expr(sp: Span) -> Gc<ast::Expr> {
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprLit(@codemap::respan(sp, ast::LitNil)), node: ast::ExprLit(box(GC) codemap::respan(sp, ast::LitNil)),
span: sp, span: sp,
} }
} }
/// A plain dummy pattern. /// A plain dummy pattern.
pub fn raw_pat(sp: Span) -> @ast::Pat { pub fn raw_pat(sp: Span) -> Gc<ast::Pat> {
@ast::Pat { box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::PatWild, node: ast::PatWild,
span: sp, span: sp,
@ -221,21 +222,21 @@ impl DummyResult {
} }
impl MacResult for DummyResult { impl MacResult for DummyResult {
fn make_expr(&self) -> Option<@ast::Expr> { fn make_expr(&self) -> Option<Gc<ast::Expr>> {
Some(DummyResult::raw_expr(self.span)) Some(DummyResult::raw_expr(self.span))
} }
fn make_pat(&self) -> Option<@ast::Pat> { fn make_pat(&self) -> Option<Gc<ast::Pat>> {
Some(DummyResult::raw_pat(self.span)) Some(DummyResult::raw_pat(self.span))
} }
fn make_items(&self) -> Option<SmallVector<@ast::Item>> { fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
if self.expr_only { if self.expr_only {
None None
} else { } else {
Some(SmallVector::zero()) Some(SmallVector::zero())
} }
} }
fn make_stmt(&self) -> Option<@ast::Stmt> { fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
Some(@codemap::respan(self.span, Some(box(GC) codemap::respan(self.span,
ast::StmtExpr(DummyResult::raw_expr(self.span), ast::StmtExpr(DummyResult::raw_expr(self.span),
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
} }
@ -397,7 +398,7 @@ pub fn syntax_expander_table() -> SyntaxEnv {
pub struct ExtCtxt<'a> { pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess, pub parse_sess: &'a parse::ParseSess,
pub cfg: ast::CrateConfig, pub cfg: ast::CrateConfig,
pub backtrace: Option<@ExpnInfo>, pub backtrace: Option<Gc<ExpnInfo>>,
pub ecfg: expand::ExpansionConfig, pub ecfg: expand::ExpansionConfig,
pub mod_path: Vec<ast::Ident> , pub mod_path: Vec<ast::Ident> ,
@ -417,7 +418,7 @@ impl<'a> ExtCtxt<'a> {
} }
} }
pub fn expand_expr(&mut self, mut e: @ast::Expr) -> @ast::Expr { pub fn expand_expr(&mut self, mut e: Gc<ast::Expr>) -> Gc<ast::Expr> {
loop { loop {
match e.node { match e.node {
ast::ExprMac(..) => { ast::ExprMac(..) => {
@ -442,7 +443,7 @@ impl<'a> ExtCtxt<'a> {
} }
} }
pub fn print_backtrace(&self) { } pub fn print_backtrace(&self) { }
pub fn backtrace(&self) -> Option<@ExpnInfo> { self.backtrace } pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace }
pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); } pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); } pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
pub fn mod_path(&self) -> Vec<ast::Ident> { pub fn mod_path(&self) -> Vec<ast::Ident> {
@ -455,9 +456,9 @@ impl<'a> ExtCtxt<'a> {
match ei { match ei {
ExpnInfo {call_site: cs, callee: ref callee} => { ExpnInfo {call_site: cs, callee: ref callee} => {
self.backtrace = self.backtrace =
Some(@ExpnInfo { Some(box(GC) ExpnInfo {
call_site: Span {lo: cs.lo, hi: cs.hi, call_site: Span {lo: cs.lo, hi: cs.hi,
expn_info: self.backtrace}, expn_info: self.backtrace.clone()},
callee: (*callee).clone() callee: (*callee).clone()
}); });
} }
@ -528,7 +529,7 @@ impl<'a> ExtCtxt<'a> {
/// Extract a string literal from the macro expanded version of `expr`, /// Extract a string literal from the macro expanded version of `expr`,
/// emitting `err_msg` if `expr` is not a string literal. This does not stop /// emitting `err_msg` if `expr` is not a string literal. This does not stop
/// compilation on error, merely emits a non-fatal error and returns None. /// compilation on error, merely emits a non-fatal error and returns None.
pub fn expr_to_str(cx: &mut ExtCtxt, expr: @ast::Expr, err_msg: &str) pub fn expr_to_str(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
-> Option<(InternedString, ast::StrStyle)> { -> Option<(InternedString, ast::StrStyle)> {
// we want to be able to handle e.g. concat("foo", "bar") // we want to be able to handle e.g. concat("foo", "bar")
let expr = cx.expand_expr(expr); let expr = cx.expand_expr(expr);
@ -584,7 +585,7 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
/// parsing error, emit a non-fatal error and return None. /// parsing error, emit a non-fatal error and return None.
pub fn get_exprs_from_tts(cx: &mut ExtCtxt, pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
sp: Span, sp: Span,
tts: &[ast::TokenTree]) -> Option<Vec<@ast::Expr> > { tts: &[ast::TokenTree]) -> Option<Vec<Gc<ast::Expr>>> {
let mut p = parse::new_parser_from_tts(cx.parse_sess(), let mut p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(), cx.cfg(),
tts.iter() tts.iter()

View File

@ -21,6 +21,8 @@ use parse::token::special_idents;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use std::gc::Gc;
// Transitional reexports so qquote can find the paths it is looking for // Transitional reexports so qquote can find the paths it is looking for
mod syntax { mod syntax {
pub use ext; pub use ext;
@ -73,115 +75,129 @@ pub trait AstBuilder {
fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime; fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime;
// statements // statements
fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt; fn stmt_expr(&self, expr: Gc<ast::Expr>) -> Gc<ast::Stmt>;
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt; fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
ex: Gc<ast::Expr>) -> Gc<ast::Stmt>;
fn stmt_let_typed(&self, fn stmt_let_typed(&self,
sp: Span, sp: Span,
mutbl: bool, mutbl: bool,
ident: ast::Ident, ident: ast::Ident,
typ: P<ast::Ty>, typ: P<ast::Ty>,
ex: @ast::Expr) ex: Gc<ast::Expr>)
-> @ast::Stmt; -> Gc<ast::Stmt>;
// blocks // blocks
fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@ast::Expr>) -> P<ast::Block>; fn block(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block>; expr: Option<Gc<ast::Expr>>) -> P<ast::Block>;
fn block_expr(&self, expr: Gc<ast::Expr>) -> P<ast::Block>;
fn block_all(&self, span: Span, fn block_all(&self, span: Span,
view_items: Vec<ast::ViewItem> , view_items: Vec<ast::ViewItem> ,
stmts: Vec<@ast::Stmt> , stmts: Vec<Gc<ast::Stmt>> ,
expr: Option<@ast::Expr>) -> P<ast::Block>; expr: Option<Gc<ast::Expr>>) -> P<ast::Block>;
// expressions // expressions
fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr; fn expr(&self, span: Span, node: ast::Expr_) -> Gc<ast::Expr>;
fn expr_path(&self, path: ast::Path) -> @ast::Expr; fn expr_path(&self, path: ast::Path) -> Gc<ast::Expr>;
fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr; fn expr_ident(&self, span: Span, id: ast::Ident) -> Gc<ast::Expr>;
fn expr_self(&self, span: Span) -> @ast::Expr; fn expr_self(&self, span: Span) -> Gc<ast::Expr>;
fn expr_binary(&self, sp: Span, op: ast::BinOp, fn expr_binary(&self, sp: Span, op: ast::BinOp,
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr; lhs: Gc<ast::Expr>, rhs: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_deref(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr; fn expr_unary(&self, sp: Span, op: ast::UnOp, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_managed(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr; fn expr_mut_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_field_access(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr; fn expr_field_access(&self, span: Span, expr: Gc<ast::Expr>,
fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr; ident: ast::Ident) -> Gc<ast::Expr>;
fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@ast::Expr> ) -> @ast::Expr; fn expr_call(&self, span: Span, expr: Gc<ast::Expr>,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn expr_call_ident(&self, span: Span, id: ast::Ident,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> , fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
args: Vec<@ast::Expr> ) -> @ast::Expr; args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn expr_method_call(&self, span: Span, fn expr_method_call(&self, span: Span,
expr: @ast::Expr, ident: ast::Ident, expr: Gc<ast::Expr>, ident: ast::Ident,
args: Vec<@ast::Expr> ) -> @ast::Expr; args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr; fn expr_block(&self, b: P<ast::Block>) -> Gc<ast::Expr>;
fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr; fn expr_cast(&self, sp: Span, expr: Gc<ast::Expr>,
ty: P<ast::Ty>) -> Gc<ast::Expr>;
fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field; fn field_imm(&self, span: Span, name: Ident, e: Gc<ast::Expr>) -> ast::Field;
fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr; fn expr_struct(&self, span: Span, path: ast::Path,
fn expr_struct_ident(&self, span: Span, id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr; fields: Vec<ast::Field> ) -> Gc<ast::Expr>;
fn expr_struct_ident(&self, span: Span, id: ast::Ident,
fields: Vec<ast::Field> ) -> Gc<ast::Expr>;
fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr; fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> Gc<ast::Expr>;
fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr; fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr>;
fn expr_int(&self, sp: Span, i: int) -> @ast::Expr; fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr>;
fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr; fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr>;
fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr; fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr>;
fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr; fn expr_vstore(&self, sp: Span, expr: Gc<ast::Expr>, vst: ast::ExprVstore) -> Gc<ast::Expr>;
fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr; fn expr_vec(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
fn expr_vec_ng(&self, sp: Span) -> @ast::Expr; fn expr_vec_ng(&self, sp: Span) -> Gc<ast::Expr>;
fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr; fn expr_vec_slice(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr; fn expr_str(&self, sp: Span, s: InternedString) -> Gc<ast::Expr>;
fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr; fn expr_str_uniq(&self, sp: Span, s: InternedString) -> Gc<ast::Expr>;
fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr; fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_none(&self, sp: Span) -> @ast::Expr; fn expr_none(&self, sp: Span) -> Gc<ast::Expr>;
fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr; fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr>;
fn expr_unreachable(&self, span: Span) -> @ast::Expr; fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr>;
fn expr_ok(&self, span: Span, expr: @ast::Expr) -> @ast::Expr; fn expr_ok(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_err(&self, span: Span, expr: @ast::Expr) -> @ast::Expr; fn expr_err(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_try(&self, span: Span, head: @ast::Expr) -> @ast::Expr; fn expr_try(&self, span: Span, head: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat; fn pat(&self, span: Span, pat: ast::Pat_) -> Gc<ast::Pat>;
fn pat_wild(&self, span: Span) -> @ast::Pat; fn pat_wild(&self, span: Span) -> Gc<ast::Pat>;
fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat; fn pat_lit(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Pat>;
fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat; fn pat_ident(&self, span: Span, ident: ast::Ident) -> Gc<ast::Pat>;
fn pat_ident_binding_mode(&self, fn pat_ident_binding_mode(&self,
span: Span, span: Span,
ident: ast::Ident, ident: ast::Ident,
bm: ast::BindingMode) -> @ast::Pat; bm: ast::BindingMode) -> Gc<ast::Pat>;
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat; fn pat_enum(&self, span: Span, path: ast::Path,
subpats: Vec<Gc<ast::Pat>>) -> Gc<ast::Pat>;
fn pat_struct(&self, span: Span, fn pat_struct(&self, span: Span,
path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> @ast::Pat; path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> Gc<ast::Pat>;
fn arm(&self, span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm; fn arm(&self, span: Span, pats: Vec<Gc<ast::Pat>> , expr: Gc<ast::Expr>) -> ast::Arm;
fn arm_unreachable(&self, span: Span) -> ast::Arm; fn arm_unreachable(&self, span: Span) -> ast::Arm;
fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @ast::Expr; fn expr_match(&self, span: Span, arg: Gc<ast::Expr>, arms: Vec<ast::Arm> ) -> Gc<ast::Expr>;
fn expr_if(&self, span: Span, fn expr_if(&self, span: Span,
cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr; cond: Gc<ast::Expr>, then: Gc<ast::Expr>,
els: Option<Gc<ast::Expr>>) -> Gc<ast::Expr>;
fn lambda_fn_decl(&self, span: Span, fn lambda_fn_decl(&self, span: Span,
fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr; fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr>;
fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> @ast::Expr; fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> Gc<ast::Expr>;
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr; fn lambda0(&self, span: Span, blk: P<ast::Block>) -> Gc<ast::Expr>;
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr; fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> Gc<ast::Expr>;
fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: @ast::Expr) -> @ast::Expr; fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr; fn lambda_expr_0(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr; fn lambda_expr_1(&self, span: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr>;
fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident> , blk: Vec<@ast::Stmt> ) -> @ast::Expr; fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident>,
fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr; blk: Vec<Gc<ast::Stmt>>) -> Gc<ast::Expr>;
fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr; fn lambda_stmts_0(&self, span: Span,
stmts: Vec<Gc<ast::Stmt>>) -> Gc<ast::Expr>;
fn lambda_stmts_1(&self, span: Span,
stmts: Vec<Gc<ast::Stmt>>, ident: ast::Ident) -> Gc<ast::Expr>;
// items // items
fn item(&self, span: Span, fn item(&self, span: Span,
name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item; name: Ident, attrs: Vec<ast::Attribute>,
node: ast::Item_) -> Gc<ast::Item>;
fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg; fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
// FIXME unused self // FIXME unused self
@ -193,56 +209,59 @@ pub trait AstBuilder {
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
generics: Generics, generics: Generics,
body: P<ast::Block>) -> @ast::Item; body: P<ast::Block>) -> Gc<ast::Item>;
fn item_fn(&self, fn item_fn(&self,
span: Span, span: Span,
name: Ident, name: Ident,
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
body: P<ast::Block>) -> @ast::Item; body: P<ast::Block>) -> Gc<ast::Item>;
fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant; fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant;
fn item_enum_poly(&self, fn item_enum_poly(&self,
span: Span, span: Span,
name: Ident, name: Ident,
enum_definition: ast::EnumDef, enum_definition: ast::EnumDef,
generics: Generics) -> @ast::Item; generics: Generics) -> Gc<ast::Item>;
fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> @ast::Item; fn item_enum(&self, span: Span, name: Ident,
enum_def: ast::EnumDef) -> Gc<ast::Item>;
fn item_struct_poly(&self, fn item_struct_poly(&self,
span: Span, span: Span,
name: Ident, name: Ident,
struct_def: ast::StructDef, struct_def: ast::StructDef,
generics: Generics) -> @ast::Item; generics: Generics) -> Gc<ast::Item>;
fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> @ast::Item; fn item_struct(&self, span: Span, name: Ident,
struct_def: ast::StructDef) -> Gc<ast::Item>;
fn item_mod(&self, span: Span, inner_span: Span, fn item_mod(&self, span: Span, inner_span: Span,
name: Ident, attrs: Vec<ast::Attribute> , name: Ident, attrs: Vec<ast::Attribute>,
vi: Vec<ast::ViewItem> , items: Vec<@ast::Item> ) -> @ast::Item; vi: Vec<ast::ViewItem>,
items: Vec<Gc<ast::Item>>) -> Gc<ast::Item>;
fn item_ty_poly(&self, fn item_ty_poly(&self,
span: Span, span: Span,
name: Ident, name: Ident,
ty: P<ast::Ty>, ty: P<ast::Ty>,
generics: Generics) -> @ast::Item; generics: Generics) -> Gc<ast::Item>;
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item; fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> Gc<ast::Item>;
fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute; fn attribute(&self, sp: Span, mi: Gc<ast::MetaItem>) -> ast::Attribute;
fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem; fn meta_word(&self, sp: Span, w: InternedString) -> Gc<ast::MetaItem>;
fn meta_list(&self, fn meta_list(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
mis: Vec<@ast::MetaItem> ) mis: Vec<Gc<ast::MetaItem>>)
-> @ast::MetaItem; -> Gc<ast::MetaItem>;
fn meta_name_value(&self, fn meta_name_value(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
value: ast::Lit_) value: ast::Lit_)
-> @ast::MetaItem; -> Gc<ast::MetaItem>;
fn view_use(&self, sp: Span, fn view_use(&self, sp: Span,
vis: ast::Visibility, vp: @ast::ViewPath) -> ast::ViewItem; vis: ast::Visibility, vp: Gc<ast::ViewPath>) -> ast::ViewItem;
fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem; fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem;
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility, fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> ast::ViewItem; ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
@ -418,17 +437,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name } ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name }
} }
fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt { fn stmt_expr(&self, expr: Gc<ast::Expr>) -> Gc<ast::Stmt> {
@respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID)) box(GC) respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID))
} }
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt { fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
ex: Gc<ast::Expr>) -> Gc<ast::Stmt> {
let pat = if mutbl { let pat = if mutbl {
self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable)) self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
} else { } else {
self.pat_ident(sp, ident) self.pat_ident(sp, ident)
}; };
let local = @ast::Local { let local = box(GC) ast::Local {
ty: self.ty_infer(sp), ty: self.ty_infer(sp),
pat: pat, pat: pat,
init: Some(ex), init: Some(ex),
@ -437,7 +457,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
source: ast::LocalLet, source: ast::LocalLet,
}; };
let decl = respan(sp, ast::DeclLocal(local)); let decl = respan(sp, ast::DeclLocal(local));
@respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID)) box(GC) respan(sp, ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))
} }
fn stmt_let_typed(&self, fn stmt_let_typed(&self,
@ -445,14 +465,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
mutbl: bool, mutbl: bool,
ident: ast::Ident, ident: ast::Ident,
typ: P<ast::Ty>, typ: P<ast::Ty>,
ex: @ast::Expr) ex: Gc<ast::Expr>)
-> @ast::Stmt { -> Gc<ast::Stmt> {
let pat = if mutbl { let pat = if mutbl {
self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable)) self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
} else { } else {
self.pat_ident(sp, ident) self.pat_ident(sp, ident)
}; };
let local = @ast::Local { let local = box(GC) ast::Local {
ty: typ, ty: typ,
pat: pat, pat: pat,
init: Some(ex), init: Some(ex),
@ -461,21 +481,22 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
source: ast::LocalLet, source: ast::LocalLet,
}; };
let decl = respan(sp, ast::DeclLocal(local)); let decl = respan(sp, ast::DeclLocal(local));
@respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID)) box(GC) respan(sp, ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))
} }
fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@Expr>) -> P<ast::Block> { fn block(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
expr: Option<Gc<Expr>>) -> P<ast::Block> {
self.block_all(span, Vec::new(), stmts, expr) self.block_all(span, Vec::new(), stmts, expr)
} }
fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block> { fn block_expr(&self, expr: Gc<ast::Expr>) -> P<ast::Block> {
self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr)) self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
} }
fn block_all(&self, fn block_all(&self,
span: Span, span: Span,
view_items: Vec<ast::ViewItem> , view_items: Vec<ast::ViewItem> ,
stmts: Vec<@ast::Stmt> , stmts: Vec<Gc<ast::Stmt>>,
expr: Option<@ast::Expr>) -> P<ast::Block> { expr: Option<Gc<ast::Expr>>) -> P<ast::Block> {
P(ast::Block { P(ast::Block {
view_items: view_items, view_items: view_items,
stmts: stmts, stmts: stmts,
@ -486,107 +507,109 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}) })
} }
fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr { fn expr(&self, span: Span, node: ast::Expr_) -> Gc<ast::Expr> {
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: node, node: node,
span: span, span: span,
} }
} }
fn expr_path(&self, path: ast::Path) -> @ast::Expr { fn expr_path(&self, path: ast::Path) -> Gc<ast::Expr> {
self.expr(path.span, ast::ExprPath(path)) self.expr(path.span, ast::ExprPath(path))
} }
fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr { fn expr_ident(&self, span: Span, id: ast::Ident) -> Gc<ast::Expr> {
self.expr_path(self.path_ident(span, id)) self.expr_path(self.path_ident(span, id))
} }
fn expr_self(&self, span: Span) -> @ast::Expr { fn expr_self(&self, span: Span) -> Gc<ast::Expr> {
self.expr_ident(span, special_idents::self_) self.expr_ident(span, special_idents::self_)
} }
fn expr_binary(&self, sp: Span, op: ast::BinOp, fn expr_binary(&self, sp: Span, op: ast::BinOp,
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr { lhs: Gc<ast::Expr>, rhs: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprBinary(op, lhs, rhs)) self.expr(sp, ast::ExprBinary(op, lhs, rhs))
} }
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_deref(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr_unary(sp, ast::UnDeref, e) self.expr_unary(sp, ast::UnDeref, e)
} }
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr { fn expr_unary(&self, sp: Span, op: ast::UnOp, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprUnary(op, e)) self.expr(sp, ast::ExprUnary(op, e))
} }
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_managed(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr_unary(sp, ast::UnBox, e) self.expr_unary(sp, ast::UnBox, e)
} }
fn expr_field_access(&self, sp: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr { fn expr_field_access(&self, sp: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprField(expr, ident, Vec::new())) self.expr(sp, ast::ExprField(expr, ident, Vec::new()))
} }
fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e)) self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))
} }
fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_mut_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e)) self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e))
} }
fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_call(&self, span: Span, expr: Gc<ast::Expr>,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
self.expr(span, ast::ExprCall(expr, args)) self.expr(span, ast::ExprCall(expr, args))
} }
fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_call_ident(&self, span: Span, id: ast::Ident,
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
self.expr(span, ast::ExprCall(self.expr_ident(span, id), args)) self.expr(span, ast::ExprCall(self.expr_ident(span, id), args))
} }
fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> , fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
args: Vec<@ast::Expr> ) -> @ast::Expr { args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
let pathexpr = self.expr_path(self.path_global(sp, fn_path)); let pathexpr = self.expr_path(self.path_global(sp, fn_path));
self.expr_call(sp, pathexpr, args) self.expr_call(sp, pathexpr, args)
} }
fn expr_method_call(&self, span: Span, fn expr_method_call(&self, span: Span,
expr: @ast::Expr, expr: Gc<ast::Expr>,
ident: ast::Ident, ident: ast::Ident,
mut args: Vec<@ast::Expr> ) -> @ast::Expr { mut args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
let id = Spanned { node: ident, span: span }; let id = Spanned { node: ident, span: span };
args.unshift(expr); args.unshift(expr);
self.expr(span, ast::ExprMethodCall(id, Vec::new(), args)) self.expr(span, ast::ExprMethodCall(id, Vec::new(), args))
} }
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr { fn expr_block(&self, b: P<ast::Block>) -> Gc<ast::Expr> {
self.expr(b.span, ast::ExprBlock(b)) self.expr(b.span, ast::ExprBlock(b))
} }
fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field { fn field_imm(&self, span: Span, name: Ident, e: Gc<ast::Expr>) -> ast::Field {
ast::Field { ident: respan(span, name), expr: e, span: span } ast::Field { ident: respan(span, name), expr: e, span: span }
} }
fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr { fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> Gc<ast::Expr> {
self.expr(span, ast::ExprStruct(path, fields, None)) self.expr(span, ast::ExprStruct(path, fields, None))
} }
fn expr_struct_ident(&self, span: Span, fn expr_struct_ident(&self, span: Span,
id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr { id: ast::Ident, fields: Vec<ast::Field> ) -> Gc<ast::Expr> {
self.expr_struct(span, self.path_ident(span, id), fields) self.expr_struct(span, self.path_ident(span, id), fields)
} }
fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr { fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprLit(@respan(sp, lit))) self.expr(sp, ast::ExprLit(box(GC) respan(sp, lit)))
} }
fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr { fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr> {
self.expr_lit(span, ast::LitUint(i as u64, ast::TyU)) self.expr_lit(span, ast::LitUint(i as u64, ast::TyU))
} }
fn expr_int(&self, sp: Span, i: int) -> @ast::Expr { fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI)) self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI))
} }
fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr { fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8)) self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8))
} }
fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr { fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitBool(value)) self.expr_lit(sp, ast::LitBool(value))
} }
fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr { fn expr_vstore(&self, sp: Span, expr: Gc<ast::Expr>, vst: ast::ExprVstore) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprVstore(expr, vst)) self.expr(sp, ast::ExprVstore(expr, vst))
} }
fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_vec(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprVec(exprs)) self.expr(sp, ast::ExprVec(exprs))
} }
fn expr_vec_ng(&self, sp: Span) -> @ast::Expr { fn expr_vec_ng(&self, sp: Span) -> Gc<ast::Expr> {
self.expr_call_global(sp, self.expr_call_global(sp,
vec!(self.ident_of("std"), vec!(self.ident_of("std"),
self.ident_of("vec"), self.ident_of("vec"),
@ -594,23 +617,23 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.ident_of("new")), self.ident_of("new")),
Vec::new()) Vec::new())
} }
fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr { fn expr_vec_slice(&self, sp: Span, exprs: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr> {
self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice) self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice)
} }
fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr { fn expr_str(&self, sp: Span, s: InternedString) -> Gc<ast::Expr> {
self.expr_lit(sp, ast::LitStr(s, ast::CookedStr)) self.expr_lit(sp, ast::LitStr(s, ast::CookedStr))
} }
fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr { fn expr_str_uniq(&self, sp: Span, s: InternedString) -> Gc<ast::Expr> {
self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq) self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq)
} }
fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr { fn expr_cast(&self, sp: Span, expr: Gc<ast::Expr>, ty: P<ast::Ty>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprCast(expr, ty)) self.expr(sp, ast::ExprCast(expr, ty))
} }
fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr { fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let some = vec!( let some = vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("option"), self.ident_of("option"),
@ -618,7 +641,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(sp, some, vec!(expr)) self.expr_call_global(sp, some, vec!(expr))
} }
fn expr_none(&self, sp: Span) -> @ast::Expr { fn expr_none(&self, sp: Span) -> Gc<ast::Expr> {
let none = self.path_global(sp, vec!( let none = self.path_global(sp, vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("option"), self.ident_of("option"),
@ -626,7 +649,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_path(none) self.expr_path(none)
} }
fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr { fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr> {
let loc = self.codemap().lookup_char_pos(span.lo); let loc = self.codemap().lookup_char_pos(span.lo);
self.expr_call_global( self.expr_call_global(
span, span,
@ -643,13 +666,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_uint(span, loc.line))) self.expr_uint(span, loc.line)))
} }
fn expr_unreachable(&self, span: Span) -> @ast::Expr { fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr> {
self.expr_fail(span, self.expr_fail(span,
InternedString::new( InternedString::new(
"internal error: entered unreachable code")) "internal error: entered unreachable code"))
} }
fn expr_ok(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr { fn expr_ok(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let ok = vec!( let ok = vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("result"), self.ident_of("result"),
@ -657,7 +680,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(sp, ok, vec!(expr)) self.expr_call_global(sp, ok, vec!(expr))
} }
fn expr_err(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr { fn expr_err(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
let err = vec!( let err = vec!(
self.ident_of("std"), self.ident_of("std"),
self.ident_of("result"), self.ident_of("result"),
@ -665,7 +688,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_call_global(sp, err, vec!(expr)) self.expr_call_global(sp, err, vec!(expr))
} }
fn expr_try(&self, sp: Span, head: @ast::Expr) -> @ast::Expr { fn expr_try(&self, sp: Span, head: Gc<ast::Expr>) -> Gc<ast::Expr> {
let ok = self.ident_of("Ok"); let ok = self.ident_of("Ok");
let ok_path = self.path_ident(sp, ok); let ok_path = self.path_ident(sp, ok);
let err = self.ident_of("Err"); let err = self.ident_of("Err");
@ -694,38 +717,38 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat { fn pat(&self, span: Span, pat: ast::Pat_) -> Gc<ast::Pat> {
@ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span } box(GC) ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }
} }
fn pat_wild(&self, span: Span) -> @ast::Pat { fn pat_wild(&self, span: Span) -> Gc<ast::Pat> {
self.pat(span, ast::PatWild) self.pat(span, ast::PatWild)
} }
fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat { fn pat_lit(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Pat> {
self.pat(span, ast::PatLit(expr)) self.pat(span, ast::PatLit(expr))
} }
fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat { fn pat_ident(&self, span: Span, ident: ast::Ident) -> Gc<ast::Pat> {
self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable)) self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable))
} }
fn pat_ident_binding_mode(&self, fn pat_ident_binding_mode(&self,
span: Span, span: Span,
ident: ast::Ident, ident: ast::Ident,
bm: ast::BindingMode) -> @ast::Pat { bm: ast::BindingMode) -> Gc<ast::Pat> {
let path = self.path_ident(span, ident); let path = self.path_ident(span, ident);
let pat = ast::PatIdent(bm, path, None); let pat = ast::PatIdent(bm, path, None);
self.pat(span, pat) self.pat(span, pat)
} }
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat { fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<Gc<ast::Pat>> ) -> Gc<ast::Pat> {
let pat = ast::PatEnum(path, Some(subpats)); let pat = ast::PatEnum(path, Some(subpats));
self.pat(span, pat) self.pat(span, pat)
} }
fn pat_struct(&self, span: Span, fn pat_struct(&self, span: Span,
path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> @ast::Pat { path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> Gc<ast::Pat> {
let pat = ast::PatStruct(path, field_pats, false); let pat = ast::PatStruct(path, field_pats, false);
self.pat(span, pat) self.pat(span, pat)
} }
fn arm(&self, _span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm { fn arm(&self, _span: Span, pats: Vec<Gc<ast::Pat>> , expr: Gc<ast::Expr>) -> ast::Arm {
ast::Arm { ast::Arm {
attrs: vec!(), attrs: vec!(),
pats: pats, pats: pats,
@ -738,56 +761,60 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span)) self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span))
} }
fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @Expr { fn expr_match(&self, span: Span, arg: Gc<ast::Expr>,
arms: Vec<ast::Arm>) -> Gc<Expr> {
self.expr(span, ast::ExprMatch(arg, arms)) self.expr(span, ast::ExprMatch(arg, arms))
} }
fn expr_if(&self, span: Span, fn expr_if(&self, span: Span,
cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr { cond: Gc<ast::Expr>, then: Gc<ast::Expr>,
els: Option<Gc<ast::Expr>>) -> Gc<ast::Expr> {
let els = els.map(|x| self.expr_block(self.block_expr(x))); let els = els.map(|x| self.expr_block(self.block_expr(x)));
self.expr(span, ast::ExprIf(cond, self.block_expr(then), els)) self.expr(span, ast::ExprIf(cond, self.block_expr(then), els))
} }
fn lambda_fn_decl(&self, span: Span, fn lambda_fn_decl(&self, span: Span,
fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr { fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> Gc<ast::Expr> {
self.expr(span, ast::ExprFnBlock(fn_decl, blk)) self.expr(span, ast::ExprFnBlock(fn_decl, blk))
} }
fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> @ast::Expr { fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> Gc<ast::Expr> {
let fn_decl = self.fn_decl( let fn_decl = self.fn_decl(
ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
self.ty_infer(span)); self.ty_infer(span));
self.expr(span, ast::ExprFnBlock(fn_decl, blk)) self.expr(span, ast::ExprFnBlock(fn_decl, blk))
} }
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr { fn lambda0(&self, span: Span, blk: P<ast::Block>) -> Gc<ast::Expr> {
self.lambda(span, Vec::new(), blk) self.lambda(span, Vec::new(), blk)
} }
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr { fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> Gc<ast::Expr> {
self.lambda(span, vec!(ident), blk) self.lambda(span, vec!(ident), blk)
} }
fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , expr: @ast::Expr) -> @ast::Expr { fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.lambda(span, ids, self.block_expr(expr)) self.lambda(span, ids, self.block_expr(expr))
} }
fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr { fn lambda_expr_0(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.lambda0(span, self.block_expr(expr)) self.lambda0(span, self.block_expr(expr))
} }
fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr { fn lambda_expr_1(&self, span: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr> {
self.lambda1(span, self.block_expr(expr), ident) self.lambda1(span, self.block_expr(expr), ident)
} }
fn lambda_stmts(&self, fn lambda_stmts(&self,
span: Span, span: Span,
ids: Vec<ast::Ident>, ids: Vec<ast::Ident>,
stmts: Vec<@ast::Stmt>) stmts: Vec<Gc<ast::Stmt>>)
-> @ast::Expr { -> Gc<ast::Expr> {
self.lambda(span, ids, self.block(span, stmts, None)) self.lambda(span, ids, self.block(span, stmts, None))
} }
fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr { fn lambda_stmts_0(&self, span: Span,
stmts: Vec<Gc<ast::Stmt>>) -> Gc<ast::Expr> {
self.lambda0(span, self.block(span, stmts, None)) self.lambda0(span, self.block(span, stmts, None))
} }
fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr { fn lambda_stmts_1(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
ident: ast::Ident) -> Gc<ast::Expr> {
self.lambda1(span, self.block(span, stmts, None), ident) self.lambda1(span, self.block(span, stmts, None), ident)
} }
@ -811,10 +838,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn item(&self, span: Span, fn item(&self, span: Span,
name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item { name: Ident, attrs: Vec<ast::Attribute>,
node: ast::Item_) -> Gc<ast::Item> {
// FIXME: Would be nice if our generated code didn't violate // FIXME: Would be nice if our generated code didn't violate
// Rust coding conventions // Rust coding conventions
@ast::Item { ident: name, box(GC) ast::Item { ident: name,
attrs: attrs, attrs: attrs,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: node, node: node,
@ -828,7 +856,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
generics: Generics, generics: Generics,
body: P<ast::Block>) -> @ast::Item { body: P<ast::Block>) -> Gc<ast::Item> {
self.item(span, self.item(span,
name, name,
Vec::new(), Vec::new(),
@ -845,7 +873,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
inputs: Vec<ast::Arg> , inputs: Vec<ast::Arg> ,
output: P<ast::Ty>, output: P<ast::Ty>,
body: P<ast::Block> body: P<ast::Block>
) -> @ast::Item { ) -> Gc<ast::Item> {
self.item_fn_poly( self.item_fn_poly(
span, span,
name, name,
@ -873,18 +901,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn item_enum_poly(&self, span: Span, name: Ident, fn item_enum_poly(&self, span: Span, name: Ident,
enum_definition: ast::EnumDef, enum_definition: ast::EnumDef,
generics: Generics) -> @ast::Item { generics: Generics) -> Gc<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics)) self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics))
} }
fn item_enum(&self, span: Span, name: Ident, fn item_enum(&self, span: Span, name: Ident,
enum_definition: ast::EnumDef) -> @ast::Item { enum_definition: ast::EnumDef) -> Gc<ast::Item> {
self.item_enum_poly(span, name, enum_definition, self.item_enum_poly(span, name, enum_definition,
ast_util::empty_generics()) ast_util::empty_generics())
} }
fn item_struct(&self, span: Span, name: Ident, fn item_struct(&self, span: Span, name: Ident,
struct_def: ast::StructDef) -> @ast::Item { struct_def: ast::StructDef) -> Gc<ast::Item> {
self.item_struct_poly( self.item_struct_poly(
span, span,
name, name,
@ -894,14 +922,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn item_struct_poly(&self, span: Span, name: Ident, fn item_struct_poly(&self, span: Span, name: Ident,
struct_def: ast::StructDef, generics: Generics) -> @ast::Item { struct_def: ast::StructDef, generics: Generics) -> Gc<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemStruct(@struct_def, generics)) self.item(span, name, Vec::new(), ast::ItemStruct(box(GC) struct_def, generics))
} }
fn item_mod(&self, span: Span, inner_span: Span, name: Ident, fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
attrs: Vec<ast::Attribute> , attrs: Vec<ast::Attribute> ,
vi: Vec<ast::ViewItem> , vi: Vec<ast::ViewItem> ,
items: Vec<@ast::Item> ) -> @ast::Item { items: Vec<Gc<ast::Item>>) -> Gc<ast::Item> {
self.item( self.item(
span, span,
name, name,
@ -915,15 +943,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>, fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>,
generics: Generics) -> @ast::Item { generics: Generics) -> Gc<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemTy(ty, generics)) self.item(span, name, Vec::new(), ast::ItemTy(ty, generics))
} }
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item { fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> Gc<ast::Item> {
self.item_ty_poly(span, name, ty, ast_util::empty_generics()) self.item_ty_poly(span, name, ty, ast_util::empty_generics())
} }
fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute { fn attribute(&self, sp: Span, mi: Gc<ast::MetaItem>) -> ast::Attribute {
respan(sp, ast::Attribute_ { respan(sp, ast::Attribute_ {
id: attr::mk_attr_id(), id: attr::mk_attr_id(),
style: ast::AttrOuter, style: ast::AttrOuter,
@ -932,26 +960,26 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}) })
} }
fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem { fn meta_word(&self, sp: Span, w: InternedString) -> Gc<ast::MetaItem> {
@respan(sp, ast::MetaWord(w)) box(GC) respan(sp, ast::MetaWord(w))
} }
fn meta_list(&self, fn meta_list(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
mis: Vec<@ast::MetaItem> ) mis: Vec<Gc<ast::MetaItem>> )
-> @ast::MetaItem { -> Gc<ast::MetaItem> {
@respan(sp, ast::MetaList(name, mis)) box(GC) respan(sp, ast::MetaList(name, mis))
} }
fn meta_name_value(&self, fn meta_name_value(&self,
sp: Span, sp: Span,
name: InternedString, name: InternedString,
value: ast::Lit_) value: ast::Lit_)
-> @ast::MetaItem { -> Gc<ast::MetaItem> {
@respan(sp, ast::MetaNameValue(name, respan(sp, value))) box(GC) respan(sp, ast::MetaNameValue(name, respan(sp, value)))
} }
fn view_use(&self, sp: Span, fn view_use(&self, sp: Span,
vis: ast::Visibility, vp: @ast::ViewPath) -> ast::ViewItem { vis: ast::Visibility, vp: Gc<ast::ViewPath>) -> ast::ViewItem {
ast::ViewItem { ast::ViewItem {
node: ast::ViewItemUse(vp), node: ast::ViewItemUse(vp),
attrs: Vec::new(), attrs: Vec::new(),
@ -968,7 +996,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility, fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> ast::ViewItem { ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
self.view_use(sp, vis, self.view_use(sp, vis,
@respan(sp, box(GC) respan(sp,
ast::ViewPathSimple(ident, ast::ViewPathSimple(ident,
path, path,
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
@ -981,7 +1009,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}).collect(); }).collect();
self.view_use(sp, vis, self.view_use(sp, vis,
@respan(sp, box(GC) respan(sp,
ast::ViewPathList(self.path(sp, path), ast::ViewPathList(self.path(sp, path),
imports, imports,
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID)))
@ -990,7 +1018,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn view_use_glob(&self, sp: Span, fn view_use_glob(&self, sp: Span,
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem { vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
self.view_use(sp, vis, self.view_use(sp, vis,
@respan(sp, box(GC) respan(sp,
ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))) ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID)))
} }
} }
@ -1013,8 +1041,8 @@ pub trait Duplicate {
fn duplicate(&self, cx: &ExtCtxt) -> Self; fn duplicate(&self, cx: &ExtCtxt) -> Self;
} }
impl Duplicate for @ast::Expr { impl Duplicate for Gc<ast::Expr> {
fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr { fn duplicate(&self, _: &ExtCtxt) -> Gc<ast::Expr> {
let mut folder = Duplicator; let mut folder = Duplicator;
folder.fold_expr(*self) folder.fold_expr(*self)
} }

View File

@ -44,7 +44,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
} }
let res = str_to_ident(res_str.as_slice()); let res = str_to_ident(res_str.as_slice());
let e = @ast::Expr { let e = box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath( node: ast::ExprPath(
ast::Path { ast::Path {

View File

@ -14,11 +14,13 @@ use ext::base::ExtCtxt;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use std::gc::Gc;
pub fn expand_deriving_bound(cx: &mut ExtCtxt, pub fn expand_deriving_bound(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let name = match mitem.node { let name = match mitem.node {
MetaWord(ref tname) => { MetaWord(ref tname) => {

View File

@ -16,11 +16,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_clone(cx: &mut ExtCtxt, pub fn expand_deriving_clone(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -51,7 +53,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
fn cs_clone( fn cs_clone(
name: &str, name: &str,
cx: &mut ExtCtxt, trait_span: Span, cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let clone_ident = substr.method_ident; let clone_ident = substr.method_ident;
let ctor_ident; let ctor_ident;
let all_fields; let all_fields;

View File

@ -16,18 +16,20 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_eq(cx: &mut ExtCtxt, pub fn expand_deriving_eq(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
// structures are equal if all fields are equal, and non equal, if // structures are equal if all fields are equal, and non equal, if
// any fields are not equal or if the enum variants are different // any fields are not equal or if the enum variants are different
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> {
cs_and(|cx, span, _, _| cx.expr_bool(span, false), cs_and(|cx, span, _, _| cx.expr_bool(span, false),
cx, span, substr) cx, span, substr)
} }
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> {
cs_or(|cx, span, _, _| cx.expr_bool(span, true), cs_or(|cx, span, _, _| cx.expr_bool(span, true),
cx, span, substr) cx, span, substr)
} }

View File

@ -17,11 +17,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_ord(cx: &mut ExtCtxt, pub fn expand_deriving_ord(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
macro_rules! md ( macro_rules! md (
($name:expr, $op:expr, $equal:expr) => { { ($name:expr, $op:expr, $equal:expr) => { {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
@ -58,7 +60,8 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
} }
/// Strict inequality. /// Strict inequality.
fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
let op = if less {ast::BiLt} else {ast::BiGt}; let op = if less {ast::BiLt} else {ast::BiGt};
cs_fold( cs_fold(
false, // need foldr, false, // need foldr,

View File

@ -16,12 +16,15 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
cs_same_method(|cx, span, exprs| { cs_same_method(|cx, span, exprs| {
// create `a.<method>(); b.<method>(); c.<method>(); ...` // create `a.<method>(); b.<method>(); c.<method>(); ...`
// (where method is `assert_receiver_is_total_eq`) // (where method is `assert_receiver_is_total_eq`)

View File

@ -18,12 +18,13 @@ use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::cmp::{Ordering, Equal, Less, Greater}; use std::cmp::{Ordering, Equal, Less, Greater};
use std::gc::Gc;
pub fn expand_deriving_totalord(cx: &mut ExtCtxt, pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -65,7 +66,7 @@ pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path
} }
pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let test_id = cx.ident_of("__test"); let test_id = cx.ident_of("__test");
let equals_path = ordering_const(cx, span, Equal); let equals_path = ordering_const(cx, span, Equal);

View File

@ -23,11 +23,13 @@ use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use std::gc::Gc;
pub fn expand_deriving_decodable(cx: &mut ExtCtxt, pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -64,7 +66,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
} }
fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let decoder = substr.nonself_args[0]; let decoder = substr.nonself_args[0];
let recurse = vec!(cx.ident_of("serialize"), let recurse = vec!(cx.ident_of("serialize"),
cx.ident_of("Decodable"), cx.ident_of("Decodable"),
@ -159,8 +161,8 @@ fn decode_static_fields(cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
outer_pat_ident: Ident, outer_pat_ident: Ident,
fields: &StaticFields, fields: &StaticFields,
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> @Expr) getarg: |&mut ExtCtxt, Span, InternedString, uint| -> Gc<Expr>)
-> @Expr { -> Gc<Expr> {
match *fields { match *fields {
Unnamed(ref fields) => { Unnamed(ref fields) => {
if fields.is_empty() { if fields.is_empty() {

View File

@ -16,11 +16,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_default(cx: &mut ExtCtxt, pub fn expand_deriving_default(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -46,7 +48,8 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn default_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let default_ident = vec!( let default_ident = vec!(
cx.ident_of("std"), cx.ident_of("std"),
cx.ident_of("default"), cx.ident_of("default"),

View File

@ -91,11 +91,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token; use parse::token;
use std::gc::Gc;
pub fn expand_deriving_encodable(cx: &mut ExtCtxt, pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -134,7 +136,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
} }
fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
let encoder = substr.nonself_args[0]; let encoder = substr.nonself_args[0];
// throw an underscore in front to suppress unused variable warnings // throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_e"); let blkarg = cx.ident_of("_e");

View File

@ -178,6 +178,7 @@ StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span
*/ */
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use ast; use ast;
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef}; use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
@ -248,9 +249,9 @@ pub struct Substructure<'a> {
/// ident of the method /// ident of the method
pub method_ident: Ident, pub method_ident: Ident,
/// dereferenced access to any Self or Ptr(Self, _) arguments /// dereferenced access to any Self or Ptr(Self, _) arguments
pub self_args: &'a [@Expr], pub self_args: &'a [Gc<Expr>],
/// verbatim access to any other arguments /// verbatim access to any other arguments
pub nonself_args: &'a [@Expr], pub nonself_args: &'a [Gc<Expr>],
pub fields: &'a SubstructureFields<'a> pub fields: &'a SubstructureFields<'a>
} }
@ -262,42 +263,43 @@ pub struct FieldInfo {
pub name: Option<Ident>, pub name: Option<Ident>,
/// The expression corresponding to this field of `self` /// The expression corresponding to this field of `self`
/// (specifically, a reference to it). /// (specifically, a reference to it).
pub self_: @Expr, pub self_: Gc<Expr>,
/// The expressions corresponding to references to this field in /// The expressions corresponding to references to this field in
/// the other Self arguments. /// the other Self arguments.
pub other: Vec<@Expr>, pub other: Vec<Gc<Expr>>,
} }
/// Fields for a static method /// Fields for a static method
pub enum StaticFields { pub enum StaticFields {
/// Tuple structs/enum variants like this /// Tuple structs/enum variants like this
Unnamed(Vec<Span> ), Unnamed(Vec<Span>),
/// Normal structs/struct variants. /// Normal structs/struct variants.
Named(Vec<(Ident, Span)> ) Named(Vec<(Ident, Span)>),
} }
/// A summary of the possible sets of fields. See above for details /// A summary of the possible sets of fields. See above for details
/// and examples /// and examples
pub enum SubstructureFields<'a> { pub enum SubstructureFields<'a> {
Struct(Vec<FieldInfo> ), Struct(Vec<FieldInfo>),
/** /**
Matching variants of the enum: variant index, ast::Variant, Matching variants of the enum: variant index, ast::Variant,
fields: the field name is only non-`None` in the case of a struct fields: the field name is only non-`None` in the case of a struct
variant. variant.
*/ */
EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo> ), EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo>),
/** /**
non-matching variants of the enum, [(variant index, ast::Variant, non-matching variants of the enum, [(variant index, ast::Variant,
[field span, field ident, fields])] \(i.e. all fields for self are in the [field span, field ident, fields])] \(i.e. all fields for self are in the
first tuple, for other1 are in the second tuple, etc.) first tuple, for other1 are in the second tuple, etc.)
*/ */
EnumNonMatching(&'a [(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )]), EnumNonMatching(&'a [(uint, P<ast::Variant>,
Vec<(Span, Option<Ident>, Gc<Expr>)>)]),
/// A static method where Self is a struct. /// A static method where Self is a struct.
StaticStruct(&'a ast::StructDef, StaticFields), StaticStruct(&'a ast::StructDef, StaticFields),
/// A static method where Self is an enum. /// A static method where Self is an enum.
StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)> ) StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
} }
@ -307,7 +309,7 @@ Combine the values of all the fields together. The last argument is
all the fields of all the structures, see above for details. all the fields of all the structures, see above for details.
*/ */
pub type CombineSubstructureFunc<'a> = pub type CombineSubstructureFunc<'a> =
|&mut ExtCtxt, Span, &Substructure|: 'a -> @Expr; |&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>;
/** /**
Deal with non-matching enum variants, the arguments are a list Deal with non-matching enum variants, the arguments are a list
@ -317,9 +319,9 @@ representing each variant: (variant index, ast::Variant instance,
pub type EnumNonMatchFunc<'a> = pub type EnumNonMatchFunc<'a> =
|&mut ExtCtxt, |&mut ExtCtxt,
Span, Span,
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )], &[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, Gc<Expr>)>)],
&[@Expr]|: 'a &[Gc<Expr>]|: 'a
-> @Expr; -> Gc<Expr>;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
-> RefCell<CombineSubstructureFunc<'a>> { -> RefCell<CombineSubstructureFunc<'a>> {
@ -330,13 +332,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
impl<'a> TraitDef<'a> { impl<'a> TraitDef<'a> {
pub fn expand(&self, pub fn expand(&self,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
_mitem: @ast::MetaItem, _mitem: Gc<ast::MetaItem>,
item: @ast::Item, item: Gc<ast::Item>,
push: |@ast::Item|) { push: |Gc<ast::Item>|) {
let newitem = match item.node { let newitem = match item.node {
ast::ItemStruct(struct_def, ref generics) => { ast::ItemStruct(ref struct_def, ref generics) => {
self.expand_struct_def(cx, self.expand_struct_def(cx,
struct_def, &**struct_def,
item.ident, item.ident,
generics) generics)
} }
@ -357,7 +359,7 @@ impl<'a> TraitDef<'a> {
_ => false, _ => false,
} }
}).map(|a| a.clone())); }).map(|a| a.clone()));
push(@ast::Item { push(box(GC) ast::Item {
attrs: attrs, attrs: attrs,
..(*newitem).clone() ..(*newitem).clone()
}) })
@ -379,7 +381,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
type_ident: Ident, type_ident: Ident,
generics: &Generics, generics: &Generics,
methods: Vec<@ast::Method> ) -> @ast::Item { methods: Vec<Gc<ast::Method>> ) -> Gc<ast::Item> {
let trait_path = self.path.to_path(cx, self.span, type_ident, generics); let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
let Generics { mut lifetimes, ty_params } = let Generics { mut lifetimes, ty_params } =
@ -435,7 +437,7 @@ impl<'a> TraitDef<'a> {
// Just mark it now since we know that it'll end up used downstream // Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr); attr::mark_used(&attr);
let opt_trait_ref = Some(trait_ref); let opt_trait_ref = Some(trait_ref);
let ident = ast_util::impl_pretty_name(&opt_trait_ref, self_type); let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
cx.item( cx.item(
self.span, self.span,
ident, ident,
@ -448,7 +450,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> @ast::Item { generics: &Generics) -> Gc<ast::Item> {
let methods = self.methods.iter().map(|method_def| { let methods = self.methods.iter().map(|method_def| {
let (explicit_self, self_args, nonself_args, tys) = let (explicit_self, self_args, nonself_args, tys) =
method_def.split_self_nonself_args( method_def.split_self_nonself_args(
@ -484,7 +486,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> @ast::Item { generics: &Generics) -> Gc<ast::Item> {
let methods = self.methods.iter().map(|method_def| { let methods = self.methods.iter().map(|method_def| {
let (explicit_self, self_args, nonself_args, tys) = let (explicit_self, self_args, nonself_args, tys) =
method_def.split_self_nonself_args(cx, self, method_def.split_self_nonself_args(cx, self,
@ -522,10 +524,10 @@ impl<'a> MethodDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_: &TraitDef, trait_: &TraitDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr], nonself_args: &[Gc<Expr>],
fields: &SubstructureFields) fields: &SubstructureFields)
-> @Expr { -> Gc<Expr> {
let substructure = Substructure { let substructure = Substructure {
type_ident: type_ident, type_ident: type_ident,
method_ident: cx.ident_of(self.name), method_ident: cx.ident_of(self.name),
@ -556,7 +558,8 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) generics: &Generics)
-> (ast::ExplicitSelf, Vec<@Expr> , Vec<@Expr> , Vec<(Ident, P<ast::Ty>)> ) { -> (ast::ExplicitSelf, Vec<Gc<Expr>>, Vec<Gc<Expr>>,
Vec<(Ident, P<ast::Ty>)>) {
let mut self_args = Vec::new(); let mut self_args = Vec::new();
let mut nonself_args = Vec::new(); let mut nonself_args = Vec::new();
@ -608,7 +611,7 @@ impl<'a> MethodDef<'a> {
generics: &Generics, generics: &Generics,
explicit_self: ast::ExplicitSelf, explicit_self: ast::ExplicitSelf,
arg_types: Vec<(Ident, P<ast::Ty>)> , arg_types: Vec<(Ident, P<ast::Ty>)> ,
body: @Expr) -> @ast::Method { body: Gc<Expr>) -> Gc<ast::Method> {
// create the generics that aren't for Self // create the generics that aren't for Self
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
@ -630,7 +633,7 @@ impl<'a> MethodDef<'a> {
let body_block = cx.block_expr(body); let body_block = cx.block_expr(body);
// Create the method. // Create the method.
@ast::Method { box(GC) ast::Method {
ident: method_ident, ident: method_ident,
attrs: self.attributes.clone(), attrs: self.attributes.clone(),
generics: fn_generics, generics: fn_generics,
@ -670,9 +673,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let mut raw_fields = Vec::new(); // ~[[fields of self], let mut raw_fields = Vec::new(); // ~[[fields of self],
// [fields of next Self arg], [etc]] // [fields of next Self arg], [etc]]
@ -737,9 +740,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let summary = trait_.summarise_struct(cx, struct_def); let summary = trait_.summarise_struct(cx, struct_def);
self.call_substructure_method(cx, self.call_substructure_method(cx,
@ -780,9 +783,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let mut matches = Vec::new(); let mut matches = Vec::new();
self.build_enum_match(cx, trait_, enum_def, type_ident, self.build_enum_match(cx, trait_, enum_def, type_ident,
self_args, nonself_args, self_args, nonself_args,
@ -816,12 +819,12 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr], nonself_args: &[Gc<Expr>],
matching: Option<uint>, matching: Option<uint>,
matches_so_far: &mut Vec<(uint, P<ast::Variant>, matches_so_far: &mut Vec<(uint, P<ast::Variant>,
Vec<(Span, Option<Ident>, @Expr)> )> , Vec<(Span, Option<Ident>, Gc<Expr>)>)> ,
match_count: uint) -> @Expr { match_count: uint) -> Gc<Expr> {
if match_count == self_args.len() { if match_count == self_args.len() {
// we've matched against all arguments, so make the final // we've matched against all arguments, so make the final
// expression at the bottom of the match tree // expression at the bottom of the match tree
@ -871,7 +874,7 @@ impl<'a> MethodDef<'a> {
other: (*other).clone() other: (*other).clone()
} }
}).collect(); }).collect();
EnumMatching(variant_index, variant, field_tuples) EnumMatching(variant_index, &*variant, field_tuples)
} }
None => { None => {
EnumNonMatching(matches_so_far.as_slice()) EnumNonMatching(matches_so_far.as_slice())
@ -905,7 +908,7 @@ impl<'a> MethodDef<'a> {
let variant = *enum_def.variants.get(index); let variant = *enum_def.variants.get(index);
let (pattern, idents) = trait_.create_enum_variant_pattern( let (pattern, idents) = trait_.create_enum_variant_pattern(
cx, cx,
variant, &*variant,
current_match_str.as_slice(), current_match_str.as_slice(),
ast::MutImmutable); ast::MutImmutable);
@ -938,7 +941,7 @@ impl<'a> MethodDef<'a> {
let (pattern, idents) = let (pattern, idents) =
trait_.create_enum_variant_pattern( trait_.create_enum_variant_pattern(
cx, cx,
variant, &*variant,
current_match_str.as_slice(), current_match_str.as_slice(),
ast::MutImmutable); ast::MutImmutable);
@ -974,17 +977,17 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[@Expr], self_args: &[Gc<Expr>],
nonself_args: &[@Expr]) nonself_args: &[Gc<Expr>])
-> @Expr { -> Gc<Expr> {
let summary = enum_def.variants.iter().map(|v| { let summary = enum_def.variants.iter().map(|v| {
let ident = v.node.name; let ident = v.node.name;
let summary = match v.node.kind { let summary = match v.node.kind {
ast::TupleVariantKind(ref args) => { ast::TupleVariantKind(ref args) => {
Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect()) Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect())
} }
ast::StructVariantKind(struct_def) => { ast::StructVariantKind(ref struct_def) => {
trait_.summarise_struct(cx, struct_def) trait_.summarise_struct(cx, &**struct_def)
} }
}; };
(ident, v.span, summary) (ident, v.span, summary)
@ -1009,7 +1012,7 @@ impl<'a> TraitDef<'a> {
None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"), None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"),
Some(name) => *name Some(name) => *name
}; };
to_set.expn_info = Some(@codemap::ExpnInfo { to_set.expn_info = Some(box(GC) codemap::ExpnInfo {
call_site: to_set, call_site: to_set,
callee: codemap::NameAndSpan { callee: codemap::NameAndSpan {
name: format!("deriving({})", trait_name).to_string(), name: format!("deriving({})", trait_name).to_string(),
@ -1048,7 +1051,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
field_paths: Vec<ast::Path> , field_paths: Vec<ast::Path> ,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> Vec<@ast::Pat> { -> Vec<Gc<ast::Pat>> {
field_paths.iter().map(|path| { field_paths.iter().map(|path| {
cx.pat(path.span, cx.pat(path.span,
ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None)) ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
@ -1061,7 +1064,7 @@ impl<'a> TraitDef<'a> {
struct_def: &StructDef, struct_def: &StructDef,
prefix: &str, prefix: &str,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> (@ast::Pat, Vec<(Span, Option<Ident>, @Expr)> ) { -> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)>) {
if struct_def.fields.is_empty() { if struct_def.fields.is_empty() {
return ( return (
cx.pat_ident_binding_mode( cx.pat_ident_binding_mode(
@ -1126,7 +1129,7 @@ impl<'a> TraitDef<'a> {
variant: &ast::Variant, variant: &ast::Variant,
prefix: &str, prefix: &str,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> (@ast::Pat, Vec<(Span, Option<Ident>, @Expr)> ) { -> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)> ) {
let variant_ident = variant.node.name; let variant_ident = variant.node.name;
match variant.node.kind { match variant.node.kind {
ast::TupleVariantKind(ref variant_args) => { ast::TupleVariantKind(ref variant_args) => {
@ -1159,8 +1162,8 @@ impl<'a> TraitDef<'a> {
(cx.pat_enum(variant.span, matching_path, subpats), (cx.pat_enum(variant.span, matching_path, subpats),
ident_expr) ident_expr)
} }
ast::StructVariantKind(struct_def) => { ast::StructVariantKind(ref struct_def) => {
self.create_struct_pattern(cx, variant_ident, struct_def, self.create_struct_pattern(cx, variant_ident, &**struct_def,
prefix, mutbl) prefix, mutbl)
} }
} }
@ -1174,13 +1177,13 @@ Fold the fields. `use_foldl` controls whether this is done
left-to-right (`true`) or right-to-left (`false`). left-to-right (`true`) or right-to-left (`false`).
*/ */
pub fn cs_fold(use_foldl: bool, pub fn cs_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr, f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
base: @Expr, base: Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> @Expr { -> Gc<Expr> {
match *substructure.fields { match *substructure.fields {
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
if use_foldl { if use_foldl {
@ -1221,12 +1224,12 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
~~~ ~~~
*/ */
#[inline] #[inline]
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<@Expr> | -> @Expr, pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> @Expr { -> Gc<Expr> {
match *substructure.fields { match *substructure.fields {
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
// call self_n.method(other_1_n, other_2_n, ...) // call self_n.method(other_1_n, other_2_n, ...)
@ -1257,13 +1260,13 @@ fields. `use_foldl` controls whether this is done left-to-right
*/ */
#[inline] #[inline]
pub fn cs_same_method_fold(use_foldl: bool, pub fn cs_same_method_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, @Expr, @Expr| -> @Expr, f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
base: @Expr, base: Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> @Expr { -> Gc<Expr> {
cs_same_method( cs_same_method(
|cx, span, vals| { |cx, span, vals| {
if use_foldl { if use_foldl {
@ -1285,10 +1288,10 @@ Use a given binop to combine the result of calling the derived method
on all the fields. on all the fields.
*/ */
#[inline] #[inline]
pub fn cs_binop(binop: ast::BinOp, base: @Expr, pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
enum_nonmatch_f: EnumNonMatchFunc, enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, trait_span: Span, cx: &mut ExtCtxt, trait_span: Span,
substructure: &Substructure) -> @Expr { substructure: &Substructure) -> Gc<Expr> {
cs_same_method_fold( cs_same_method_fold(
true, // foldl is good enough true, // foldl is good enough
|cx, span, old, new| { |cx, span, old, new| {
@ -1306,7 +1309,7 @@ pub fn cs_binop(binop: ast::BinOp, base: @Expr,
#[inline] #[inline]
pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, span: Span, cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> @Expr { substructure: &Substructure) -> Gc<Expr> {
cs_binop(ast::BiOr, cx.expr_bool(span, false), cs_binop(ast::BiOr, cx.expr_bool(span, false),
enum_nonmatch_f, enum_nonmatch_f,
cx, span, substructure) cx, span, substructure)
@ -1316,7 +1319,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
#[inline] #[inline]
pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc, pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
cx: &mut ExtCtxt, span: Span, cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> @Expr { substructure: &Substructure) -> Gc<Expr> {
cs_binop(ast::BiAnd, cx.expr_bool(span, true), cs_binop(ast::BiAnd, cx.expr_bool(span, true),
enum_nonmatch_f, enum_nonmatch_f,
cx, span, substructure) cx, span, substructure)

View File

@ -20,6 +20,7 @@ use ext::build::AstBuilder;
use codemap::{Span,respan}; use codemap::{Span,respan};
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use std::gc::Gc;
/// The types of pointers /// The types of pointers
pub enum PtrTy<'a> { pub enum PtrTy<'a> {
@ -81,7 +82,7 @@ impl<'a> Path<'a> {
/// A type. Supports pointers (except for *), Self, and literals /// A type. Supports pointers (except for *), Self, and literals
pub enum Ty<'a> { pub enum Ty<'a> {
Self, Self,
// &/Box/@ Ty // &/Box/ Ty
Ptr(Box<Ty<'a>>, PtrTy<'a>), Ptr(Box<Ty<'a>>, PtrTy<'a>),
// mod::mod::Type<[lifetime], [Params...]>, including a plain type // mod::mod::Type<[lifetime], [Params...]>, including a plain type
// parameter, and things like `int` // parameter, and things like `int`
@ -244,7 +245,7 @@ impl<'a> LifetimeBounds<'a> {
pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>) pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
-> (@Expr, ast::ExplicitSelf) { -> (Gc<Expr>, ast::ExplicitSelf) {
let self_path = cx.expr_self(span); let self_path = cx.expr_self(span);
match *self_ptr { match *self_ptr {
None => { None => {

View File

@ -17,11 +17,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_hash(cx: &mut ExtCtxt, pub fn expand_deriving_hash(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
(Path::new_(vec!("std", "hash", "Hash"), None, (Path::new_(vec!("std", "hash", "Hash"), None,
@ -64,7 +66,8 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
hash_trait_def.expand(cx, mitem, item, push); hash_trait_def.expand(cx, mitem, item, push);
} }
fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let state_expr = match substr.nonself_args { let state_expr = match substr.nonself_args {
[state_expr] => state_expr, [state_expr] => state_expr,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`") _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")

View File

@ -22,6 +22,8 @@ use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
use codemap::Span; use codemap::Span;
use std::gc::Gc;
pub mod bounds; pub mod bounds;
pub mod clone; pub mod clone;
pub mod encodable; pub mod encodable;
@ -47,9 +49,9 @@ pub mod generic;
pub fn expand_meta_deriving(cx: &mut ExtCtxt, pub fn expand_meta_deriving(cx: &mut ExtCtxt,
_span: Span, _span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
match mitem.node { match mitem.node {
MetaNameValue(_, ref l) => { MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`"); cx.span_err(l.span, "unexpected value in `deriving`");

View File

@ -17,11 +17,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -70,7 +72,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let n = match substr.nonself_args { let n = match substr.nonself_args {
[n] => n, [n] => n,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`") _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`")

View File

@ -16,11 +16,13 @@ use ext::build::{AstBuilder};
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use std::gc::Gc;
pub fn expand_deriving_rand(cx: &mut ExtCtxt, pub fn expand_deriving_rand(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -53,7 +55,8 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let rng = match substr.nonself_args { let rng = match substr.nonself_args {
[rng] => vec!( rng ), [rng] => vec!( rng ),
_ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
@ -134,8 +137,8 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
trait_span: Span, trait_span: Span,
ctor_ident: Ident, ctor_ident: Ident,
summary: &StaticFields, summary: &StaticFields,
rand_call: |&mut ExtCtxt, Span| -> @Expr) rand_call: |&mut ExtCtxt, Span| -> Gc<Expr>)
-> @Expr { -> Gc<Expr> {
match *summary { match *summary {
Unnamed(ref fields) => { Unnamed(ref fields) => {
if fields.is_empty() { if fields.is_empty() {

View File

@ -20,12 +20,13 @@ use parse::token;
use std::collections::HashMap; use std::collections::HashMap;
use std::string::String; use std::string::String;
use std::gc::Gc;
pub fn expand_deriving_show(cx: &mut ExtCtxt, pub fn expand_deriving_show(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
// &mut ::std::fmt::Formatter // &mut ::std::fmt::Formatter
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))), let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
Borrowed(None, ast::MutMutable)); Borrowed(None, ast::MutMutable));
@ -57,7 +58,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
// we construct a format string and then defer to std::fmt, since that // we construct a format string and then defer to std::fmt, since that
// knows what's up with formatting at so on. // knows what's up with formatting at so on.
fn show_substructure(cx: &mut ExtCtxt, span: Span, fn show_substructure(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> @Expr { substr: &Substructure) -> Gc<Expr> {
// build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {}, // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
// <field>: {}, ... }` based on the "shape". // <field>: {}, ... }` based on the "shape".
// //

View File

@ -16,11 +16,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use std::gc::Gc;
pub fn expand_deriving_zero(cx: &mut ExtCtxt, pub fn expand_deriving_zero(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: @MetaItem, mitem: Gc<MetaItem>,
item: @Item, item: Gc<Item>,
push: |@Item|) { push: |Gc<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -63,7 +65,8 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> {
let zero_ident = vec!( let zero_ident = vec!(
cx.ident_of("std"), cx.ident_of("std"),
cx.ident_of("num"), cx.ident_of("num"),

View File

@ -29,7 +29,9 @@ use visit;
use visit::Visitor; use visit::Visitor;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { use std::gc::Gc;
pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
match e.node { match e.node {
// expr_mac should really be expr_ext or something; it's the // expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions. // entry-point for all syntax extensions.
@ -115,7 +117,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
fld.fold_expr(marked_after).node.clone(); fld.fold_expr(marked_after).node.clone();
fld.cx.bt_pop(); fld.cx.bt_pop();
@ast::Expr { box(GC) ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: fully_expanded, node: fully_expanded,
span: e.span, span: e.span,
@ -172,7 +174,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
let value_ident = token::gensym_ident("__value"); let value_ident = token::gensym_ident("__value");
// this is careful to use src_pat.span so that error // this is careful to use src_pat.span so that error
// messages point exact at that. // messages point exact at that.
let local = @ast::Local { let local = box(GC) ast::Local {
ty: fld.cx.ty_infer(src_pat.span), ty: fld.cx.ty_infer(src_pat.span),
pat: src_pat, pat: src_pat,
init: Some(fld.cx.expr_ident(src_pat.span, value_ident)), init: Some(fld.cx.expr_ident(src_pat.span, value_ident)),
@ -181,7 +183,8 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
source: ast::LocalFor source: ast::LocalFor
}; };
let local = codemap::respan(src_pat.span, ast::DeclLocal(local)); let local = codemap::respan(src_pat.span, ast::DeclLocal(local));
let local = @codemap::respan(span, ast::StmtDecl(@local, ast::DUMMY_NODE_ID)); let local = box(GC) codemap::respan(span, ast::StmtDecl(box(GC) local,
ast::DUMMY_NODE_ID));
// { let ...; <src_loop_block> } // { let ...; <src_loop_block> }
let block = fld.cx.block(span, vec![local], let block = fld.cx.block(span, vec![local],
@ -256,7 +259,7 @@ fn expand_loop_block(loop_block: P<Block>,
// in a block enclosed by loop head. // in a block enclosed by loop head.
fld.extsbox.push_frame(); fld.extsbox.push_frame();
fld.extsbox.info().pending_renames.push(rename); fld.extsbox.info().pending_renames.push(rename);
let expanded_block = expand_block_elts(loop_block, fld); let expanded_block = expand_block_elts(&*loop_block, fld);
fld.extsbox.pop_frame(); fld.extsbox.pop_frame();
(expanded_block, Some(renamed_ident)) (expanded_block, Some(renamed_ident))
@ -277,8 +280,8 @@ macro_rules! with_exts_frame (
) )
// When we enter a module, record it, for the sake of `module!` // When we enter a module, record it, for the sake of `module!`
pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander) pub fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
-> SmallVector<@ast::Item> { -> SmallVector<Gc<ast::Item>> {
let it = expand_item_modifiers(it, fld); let it = expand_item_modifiers(it, fld);
let mut decorator_items = SmallVector::zero(); let mut decorator_items = SmallVector::zero();
@ -301,7 +304,7 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
// we'd ideally decorator_items.push_all(expand_item(item, fld)), // we'd ideally decorator_items.push_all(expand_item(item, fld)),
// but that double-mut-borrows fld // but that double-mut-borrows fld
let mut items: SmallVector<@ast::Item> = SmallVector::zero(); let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero();
dec_fn(fld.cx, attr.span, attr.node.value, it, dec_fn(fld.cx, attr.span, attr.node.value, it,
|item| items.push(item)); |item| items.push(item));
decorator_items.extend(items.move_iter() decorator_items.extend(items.move_iter()
@ -320,17 +323,17 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
let macro_escape = contains_macro_escape(new_attrs.as_slice()); let macro_escape = contains_macro_escape(new_attrs.as_slice());
let result = with_exts_frame!(fld.extsbox, let result = with_exts_frame!(fld.extsbox,
macro_escape, macro_escape,
noop_fold_item(it, fld)); noop_fold_item(&*it, fld));
fld.cx.mod_pop(); fld.cx.mod_pop();
result result
}, },
_ => { _ => {
let it = @ast::Item { let it = box(GC) ast::Item {
attrs: new_attrs, attrs: new_attrs,
..(*it).clone() ..(*it).clone()
}; };
noop_fold_item(it, fld) noop_fold_item(&*it, fld)
} }
}; };
@ -338,8 +341,8 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
new_items new_items
} }
fn expand_item_modifiers(mut it: @ast::Item, fld: &mut MacroExpander) fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
-> @ast::Item { -> Gc<ast::Item> {
let (modifiers, attrs) = it.attrs.partitioned(|attr| { let (modifiers, attrs) = it.attrs.partitioned(|attr| {
match fld.extsbox.find(&intern(attr.name().get())) { match fld.extsbox.find(&intern(attr.name().get())) {
Some(&ItemModifier(_)) => true, Some(&ItemModifier(_)) => true,
@ -347,7 +350,7 @@ fn expand_item_modifiers(mut it: @ast::Item, fld: &mut MacroExpander)
} }
}); });
it = @ast::Item { it = box(GC) ast::Item {
attrs: attrs, attrs: attrs,
..(*it).clone() ..(*it).clone()
}; };
@ -388,8 +391,8 @@ pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
// Support for item-position macro invocations, exactly the same // Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations. // logic as for expression-position macro invocations.
pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander) pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
-> SmallVector<@ast::Item> { -> SmallVector<Gc<ast::Item>> {
let (pth, tts) = match it.node { let (pth, tts) = match it.node {
ItemMac(codemap::Spanned { ItemMac(codemap::Spanned {
node: MacInvocTT(ref pth, ref tts, _), node: MacInvocTT(ref pth, ref tts, _),
@ -494,7 +497,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
} }
// expand a stmt // expand a stmt
pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> { pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
// why the copying here and not in expand_expr? // why the copying here and not in expand_expr?
// looks like classic changed-in-only-one-place // looks like classic changed-in-only-one-place
let (pth, tts, semi) = match s.node { let (pth, tts, semi) = match s.node {
@ -550,7 +553,7 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
} }
}; };
mark_stmt(expanded,fm) mark_stmt(&*expanded,fm)
} }
_ => { _ => {
@ -561,20 +564,20 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
}; };
// Keep going, outside-in. // Keep going, outside-in.
let fully_expanded = fld.fold_stmt(marked_after); let fully_expanded = fld.fold_stmt(&*marked_after);
if fully_expanded.is_empty() { if fully_expanded.is_empty() {
fld.cx.span_err(pth.span, "macro didn't expand to a statement"); fld.cx.span_err(pth.span, "macro didn't expand to a statement");
return SmallVector::zero(); return SmallVector::zero();
} }
fld.cx.bt_pop(); fld.cx.bt_pop();
let fully_expanded: SmallVector<@Stmt> = fully_expanded.move_iter() let fully_expanded: SmallVector<Gc<Stmt>> = fully_expanded.move_iter()
.map(|s| @Spanned { span: s.span, node: s.node.clone() }) .map(|s| box(GC) Spanned { span: s.span, node: s.node.clone() })
.collect(); .collect();
fully_expanded.move_iter().map(|s| { fully_expanded.move_iter().map(|s| {
match s.node { match s.node {
StmtExpr(e, stmt_id) if semi => { StmtExpr(e, stmt_id) if semi => {
@Spanned { box(GC) Spanned {
span: s.span, span: s.span,
node: StmtSemi(e, stmt_id) node: StmtSemi(e, stmt_id)
} }
@ -587,7 +590,7 @@ pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> {
// expand a non-macro stmt. this is essentially the fallthrough for // expand a non-macro stmt. this is essentially the fallthrough for
// expand_stmt, above. // expand_stmt, above.
fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
-> SmallVector<@Stmt> { -> SmallVector<Gc<Stmt>> {
// is it a let? // is it a let?
match s.node { match s.node {
StmtDecl(decl, node_id) => { StmtDecl(decl, node_id) => {
@ -612,7 +615,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
// names, as well... but that should be okay, as long as // names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones. // the new names are gensyms for the old ones.
let mut name_finder = new_name_finder(Vec::new()); let mut name_finder = new_name_finder(Vec::new());
name_finder.visit_pat(expanded_pat,()); name_finder.visit_pat(&*expanded_pat,());
// generate fresh names, push them to a new pending list // generate fresh names, push them to a new pending list
let mut new_pending_renames = Vec::new(); let mut new_pending_renames = Vec::new();
for ident in name_finder.ident_accumulator.iter() { for ident in name_finder.ident_accumulator.iter() {
@ -631,7 +634,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
// also, don't forget to expand the init: // also, don't forget to expand the init:
let new_init_opt = init.map(|e| fld.fold_expr(e)); let new_init_opt = init.map(|e| fld.fold_expr(e));
let rewritten_local = let rewritten_local =
@Local { box(GC) Local {
ty: local.ty, ty: local.ty,
pat: rewritten_pat, pat: rewritten_pat,
init: new_init_opt, init: new_init_opt,
@ -639,8 +642,8 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
span: span, span: span,
source: source source: source
}; };
SmallVector::one(@Spanned { SmallVector::one(box(GC) Spanned {
node: StmtDecl(@Spanned { node: StmtDecl(box(GC) Spanned {
node: DeclLocal(rewritten_local), node: DeclLocal(rewritten_local),
span: stmt_span span: stmt_span
}, },
@ -687,7 +690,7 @@ impl Visitor<()> for NewNameFinderContext {
} }
// visit optional subpattern of pat_ident: // visit optional subpattern of pat_ident:
for subpat in inner.iter() { for subpat in inner.iter() {
self.visit_pat(*subpat, ()) self.visit_pat(&**subpat, ())
} }
} }
// use the default traversal for non-pat_idents // use the default traversal for non-pat_idents
@ -725,9 +728,9 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
let renamed_stmt = { let renamed_stmt = {
let pending_renames = &mut fld.extsbox.info().pending_renames; let pending_renames = &mut fld.extsbox.info().pending_renames;
let mut rename_fld = renames_to_fold(pending_renames); let mut rename_fld = renames_to_fold(pending_renames);
rename_fld.fold_stmt(*x).expect_one("rename_fold didn't return one value") rename_fld.fold_stmt(&**x).expect_one("rename_fold didn't return one value")
}; };
fld.fold_stmt(renamed_stmt).move_iter() fld.fold_stmt(&*renamed_stmt).move_iter()
}).collect(); }).collect();
let new_expr = b.expr.map(|x| { let new_expr = b.expr.map(|x| {
let expr = { let expr = {
@ -747,7 +750,7 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
}) })
} }
pub fn expand_pat(p: @ast::Pat, fld: &mut MacroExpander) -> @ast::Pat { pub fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
let (pth, tts) = match p.node { let (pth, tts) = match p.node {
PatMac(ref mac) => { PatMac(ref mac) => {
match mac.node { match mac.node {
@ -817,7 +820,7 @@ pub fn expand_pat(p: @ast::Pat, fld: &mut MacroExpander) -> @ast::Pat {
fld.fold_pat(marked_after).node.clone(); fld.fold_pat(marked_after).node.clone();
fld.cx.bt_pop(); fld.cx.bt_pop();
@ast::Pat { box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: fully_expanded, node: fully_expanded,
span: p.span, span: p.span,
@ -863,24 +866,24 @@ pub struct MacroExpander<'a, 'b> {
} }
impl<'a, 'b> Folder for MacroExpander<'a, 'b> { impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
fn fold_expr(&mut self, expr: @ast::Expr) -> @ast::Expr { fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
expand_expr(expr, self) expand_expr(expr, self)
} }
fn fold_pat(&mut self, pat: @ast::Pat) -> @ast::Pat { fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
expand_pat(pat, self) expand_pat(pat, self)
} }
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> { fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
expand_item(item, self) expand_item(item, self)
} }
fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> { fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<Gc<ast::Stmt>> {
expand_stmt(stmt, self) expand_stmt(stmt, self)
} }
fn fold_block(&mut self, block: P<Block>) -> P<Block> { fn fold_block(&mut self, block: P<Block>) -> P<Block> {
expand_block(block, self) expand_block(&*block, self)
} }
fn new_span(&mut self, span: Span) -> Span { fn new_span(&mut self, span: Span) -> Span {
@ -976,27 +979,27 @@ fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
} }
// apply a given mark to the given expr. Used following the expansion of a macro. // apply a given mark to the given expr. Used following the expansion of a macro.
fn mark_expr(expr: @ast::Expr, m: Mrk) -> @ast::Expr { fn mark_expr(expr: Gc<ast::Expr>, m: Mrk) -> Gc<ast::Expr> {
new_mark_folder(m).fold_expr(expr) new_mark_folder(m).fold_expr(expr)
} }
// apply a given mark to the given pattern. Used following the expansion of a macro. // apply a given mark to the given pattern. Used following the expansion of a macro.
fn mark_pat(pat: @ast::Pat, m: Mrk) -> @ast::Pat { fn mark_pat(pat: Gc<ast::Pat>, m: Mrk) -> Gc<ast::Pat> {
new_mark_folder(m).fold_pat(pat) new_mark_folder(m).fold_pat(pat)
} }
// apply a given mark to the given stmt. Used following the expansion of a macro. // apply a given mark to the given stmt. Used following the expansion of a macro.
fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> @ast::Stmt { fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> Gc<ast::Stmt> {
new_mark_folder(m).fold_stmt(expr) new_mark_folder(m).fold_stmt(expr)
.expect_one("marking a stmt didn't return a stmt") .expect_one("marking a stmt didn't return a stmt")
} }
// apply a given mark to the given item. Used following the expansion of a macro. // apply a given mark to the given item. Used following the expansion of a macro.
fn mark_item(expr: @ast::Item, m: Mrk) -> SmallVector<@ast::Item> { fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> SmallVector<Gc<ast::Item>> {
new_mark_folder(m).fold_item(expr) new_mark_folder(m).fold_item(expr)
} }
fn original_span(cx: &ExtCtxt) -> @codemap::ExpnInfo { fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
let mut relevant_info = cx.backtrace(); let mut relevant_info = cx.backtrace();
let mut einfo = relevant_info.unwrap(); let mut einfo = relevant_info.unwrap();
loop { loop {
@ -1134,7 +1137,7 @@ mod test {
node: Attribute_ { node: Attribute_ {
id: attr::mk_attr_id(), id: attr::mk_attr_id(),
style: AttrOuter, style: AttrOuter,
value: @Spanned { value: box(GC) Spanned {
node: MetaWord(token::intern_and_get_ident(s)), node: MetaWord(token::intern_and_get_ident(s)),
span: codemap::DUMMY_SP, span: codemap::DUMMY_SP,
}, },

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