mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-18 01:44:04 +00:00
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:
commit
f0f9095f1d
@ -1710,14 +1710,14 @@ having ownership of the box. It allows the creation of cycles, and the individua
|
||||
not have a destructor.
|
||||
|
||||
~~~
|
||||
use std::gc::Gc;
|
||||
use std::gc::GC;
|
||||
|
||||
// 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 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,
|
||||
|
@ -320,8 +320,8 @@ mod tests {
|
||||
#[test]
|
||||
fn gc_inside() {
|
||||
// see issue #11532
|
||||
use std::gc::Gc;
|
||||
let a = Rc::new(RefCell::new(Gc::new(1)));
|
||||
use std::gc::GC;
|
||||
let a = Rc::new(RefCell::new(box(GC) 1));
|
||||
assert!(a.try_borrow_mut().is_some());
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
#[inline]
|
||||
fn hash(&self, state: &mut S) {
|
||||
|
@ -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 {
|
||||
/// Return a shallow copy of the reference.
|
||||
#[inline]
|
||||
@ -116,6 +110,7 @@ extern_fn_clone!(A, B, C, D, E, F, G, H)
|
||||
mod test {
|
||||
use prelude::*;
|
||||
use realstd::owned::Box;
|
||||
use realstd::gc::{Gc, GC};
|
||||
|
||||
fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
|
||||
use realstd::clone::Clone;
|
||||
@ -136,9 +131,9 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_managed_clone() {
|
||||
let a = @5i;
|
||||
let b: @int = a.clone();
|
||||
assert_eq!(a, b);
|
||||
let a = box(GC) 5i;
|
||||
let b: Gc<int> = realclone(&a);
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -326,29 +326,6 @@ mod impls {
|
||||
fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
|
||||
}
|
||||
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)]
|
||||
|
@ -43,7 +43,3 @@ default_impl!(i64, 0i64)
|
||||
|
||||
default_impl!(f32, 0.0f32)
|
||||
default_impl!(f64, 0.0f64)
|
||||
|
||||
impl<T: Default + 'static> Default for @T {
|
||||
fn default() -> @T { @Default::default() }
|
||||
}
|
||||
|
@ -628,9 +628,6 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
|
||||
|
||||
// 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 {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
|
||||
}
|
||||
|
@ -79,7 +79,6 @@ pub trait Repr<T> {
|
||||
|
||||
impl<'a, T> Repr<Slice<T>> for &'a [T] {}
|
||||
impl<'a> Repr<Slice<u8>> for &'a str {}
|
||||
impl<T> Repr<*Box<T>> for @T {}
|
||||
impl<T> Repr<*Vec<T>> for ~[T] {}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -705,7 +705,7 @@ fn print_flowgraph<W:io::Writer>(analysis: CrateAnalysis,
|
||||
block: ast::P<ast::Block>,
|
||||
mut out: W) -> io::IoResult<()> {
|
||||
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,
|
||||
cfg: &cfg,
|
||||
name: format!("block{}", block.id).to_string(), };
|
||||
|
@ -12,6 +12,8 @@ use syntax::fold::Folder;
|
||||
use syntax::{ast, fold, attr};
|
||||
use syntax::codemap;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
struct Context<'a> {
|
||||
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_ {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
let filtered_items: Vec<&@ast::Item> = m.items.iter()
|
||||
.filter(|&a| item_in_cfg(cx, *a))
|
||||
let filtered_items: Vec<&Gc<ast::Item>> = m.items.iter()
|
||||
.filter(|a| item_in_cfg(cx, &***a))
|
||||
.collect();
|
||||
let flattened_items = filtered_items.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)
|
||||
-> Option<@ast::ForeignItem> {
|
||||
if foreign_item_in_cfg(cx, item) {
|
||||
fn filter_foreign_item(cx: &mut Context, item: Gc<ast::ForeignItem>)
|
||||
-> Option<Gc<ast::ForeignItem>> {
|
||||
if foreign_item_in_cfg(cx, &*item) {
|
||||
Some(item)
|
||||
} else {
|
||||
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_ {
|
||||
let item = match *item {
|
||||
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();
|
||||
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();
|
||||
ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
|
||||
}
|
||||
ast::ItemStruct(def, ref generics) => {
|
||||
ast::ItemStruct(fold_struct(cx, def), generics.clone())
|
||||
ast::ItemStruct(ref def, ref generics) => {
|
||||
ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
|
||||
}
|
||||
ast::ItemEnum(ref def, ref generics) => {
|
||||
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 {
|
||||
Some(match v.node.kind {
|
||||
ast::TupleVariantKind(..) => v,
|
||||
ast::StructVariantKind(def) => {
|
||||
let def = fold_struct(cx, def);
|
||||
@codemap::Spanned {
|
||||
ast::StructVariantKind(ref def) => {
|
||||
let def = fold_struct(cx, &**def);
|
||||
box(GC) codemap::Spanned {
|
||||
node: ast::Variant_ {
|
||||
kind: ast::StructVariantKind(def),
|
||||
kind: ast::StructVariantKind(def.clone()),
|
||||
..v.node.clone()
|
||||
},
|
||||
..*v
|
||||
@ -148,11 +150,11 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
|
||||
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| {
|
||||
(cx.in_cfg)(m.node.attrs.as_slice())
|
||||
});
|
||||
@ast::StructDef {
|
||||
box(GC) ast::StructDef {
|
||||
fields: fields.collect(),
|
||||
ctor_id: def.ctor_id,
|
||||
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 {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
match decl.node {
|
||||
ast::DeclItem(item) => {
|
||||
item_in_cfg(cx, item)
|
||||
ast::DeclItem(ref item) => {
|
||||
item_in_cfg(cx, &**item)
|
||||
}
|
||||
_ => 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> {
|
||||
let resulting_stmts: Vec<&@ast::Stmt> =
|
||||
let resulting_stmts: Vec<&Gc<ast::Stmt>> =
|
||||
b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
|
||||
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();
|
||||
let filtered_view_items = b.view_items.iter().filter_map(|a| {
|
||||
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 {
|
||||
ast::ExprMatch(ref m, ref arms) => {
|
||||
let arms = arms.iter()
|
||||
.filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
|
||||
.map(|a| a.clone())
|
||||
.collect();
|
||||
@ast::Expr {
|
||||
box(GC) ast::Expr {
|
||||
id: expr.id,
|
||||
span: expr.span.clone(),
|
||||
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
|
||||
// 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))
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ use syntax::parse::token;
|
||||
use syntax::util::small_vector::SmallVector;
|
||||
|
||||
use std::mem;
|
||||
use std::gc::Gc;
|
||||
|
||||
pub static VERSION: &'static str = "0.11.0-pre";
|
||||
|
||||
@ -165,12 +166,12 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
||||
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()) {
|
||||
// only recur if there wasn't `#![no_implicit_prelude]`
|
||||
// on this item, i.e. this means that the prelude is not
|
||||
// implicitly imported though the whole subtree
|
||||
fold::noop_fold_item(item, self)
|
||||
fold::noop_fold_item(&*item, self)
|
||||
} else {
|
||||
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 {
|
||||
node: ast::ViewItemUse(vp),
|
||||
attrs: Vec::new(),
|
||||
|
@ -18,8 +18,8 @@ use front::config;
|
||||
use front::std_inject::with_version;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
use std::slice;
|
||||
use std::vec::Vec;
|
||||
use std::vec;
|
||||
use syntax::ast_util::*;
|
||||
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);
|
||||
debug!("current path: {}",
|
||||
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();
|
||||
res
|
||||
}
|
||||
@ -124,8 +124,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
||||
// Remove any #[main] from the AST so it doesn't clash with
|
||||
// the one we're going to add. Only if compiling an executable.
|
||||
|
||||
fn nomain(item: @ast::Item) -> @ast::Item {
|
||||
@ast::Item {
|
||||
fn nomain(item: Gc<ast::Item>) -> Gc<ast::Item> {
|
||||
box(GC) ast::Item {
|
||||
attrs: item.attrs.iter().filter_map(|attr| {
|
||||
if !attr.name().equiv(&("main")) {
|
||||
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");
|
||||
|
||||
fn has_test_signature(i: @ast::Item) -> bool {
|
||||
fn has_test_signature(i: Gc<ast::Item>) -> bool {
|
||||
match &i.node {
|
||||
&ast::ItemFn(ref decl, _, _, ref generics, _) => {
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
fn has_test_signature(i: @ast::Item) -> bool {
|
||||
fn has_test_signature(i: Gc<ast::Item>) -> bool {
|
||||
match i.node {
|
||||
ast::ItemFn(ref decl, _, _, ref generics, _) => {
|
||||
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);
|
||||
}
|
||||
|
||||
fn is_ignored(cx: &TestCtxt, i: @ast::Item) -> bool {
|
||||
fn is_ignored(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
|
||||
i.attrs.iter().any(|attr| {
|
||||
// check ignore(cfg(foo, bar))
|
||||
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")
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
||||
let id_test = token::str_to_ident("test");
|
||||
let (vi, vis) = if cx.is_test_crate {
|
||||
(ast::ViewItemUse(
|
||||
@nospan(ast::ViewPathSimple(id_test,
|
||||
box(GC) nospan(ast::ViewPathSimple(id_test,
|
||||
path_node(vec!(id_test)),
|
||||
ast::DUMMY_NODE_ID))),
|
||||
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
|
||||
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));
|
||||
|
||||
return @item;
|
||||
box(GC) item
|
||||
}
|
||||
|
||||
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
|
||||
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());
|
||||
|
||||
@ast::Expr {
|
||||
box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprVstore(@ast::Expr {
|
||||
node: ast::ExprVstore(box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprVec(cx.testfns.borrow().iter().map(|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 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::CookedStr));
|
||||
|
||||
let name_expr = @ast::Expr {
|
||||
let name_expr = box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprLit(@name_lit),
|
||||
node: ast::ExprLit(box(GC) name_lit),
|
||||
span: span
|
||||
};
|
||||
|
||||
let fn_path = path_node_global(path);
|
||||
|
||||
let fn_expr = @ast::Expr {
|
||||
let fn_expr = box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprPath(fn_path),
|
||||
span: span,
|
||||
|
@ -177,7 +177,7 @@ pub fn get_static_methods_if_impl(cstore: &cstore::CStore,
|
||||
|
||||
pub fn get_item_attrs(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId,
|
||||
f: |Vec<ast::Attribute> |) {
|
||||
f: |Vec<ast::Attribute>|) {
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::get_item_attrs(&*cdata, def_id.node, f)
|
||||
}
|
||||
|
@ -28,13 +28,13 @@ use middle::ty;
|
||||
use middle::typeck;
|
||||
use middle::astencode::vtable_decoder_helpers;
|
||||
|
||||
use std::u64;
|
||||
use std::hash;
|
||||
use std::gc::Gc;
|
||||
use std::hash::Hash;
|
||||
use std::io;
|
||||
use std::hash;
|
||||
use std::io::extensions::u64_from_be_bytes;
|
||||
use std::option;
|
||||
use std::io;
|
||||
use std::rc::Rc;
|
||||
use std::u64;
|
||||
use serialize::ebml::reader;
|
||||
use serialize::ebml;
|
||||
use serialize::Decodable;
|
||||
@ -1010,8 +1010,8 @@ pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId)
|
||||
result
|
||||
}
|
||||
|
||||
fn get_meta_items(md: ebml::Doc) -> Vec<@ast::MetaItem> {
|
||||
let mut items: Vec<@ast::MetaItem> = Vec::new();
|
||||
fn get_meta_items(md: ebml::Doc) -> Vec<Gc<ast::MetaItem>> {
|
||||
let mut items: Vec<Gc<ast::MetaItem>> = Vec::new();
|
||||
reader::tagged_docs(md, tag_meta_item_word, |meta_item_doc| {
|
||||
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
||||
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> {
|
||||
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
||||
match reader::maybe_get_doc(md, tag_attributes) {
|
||||
option::Some(attrs_d) => {
|
||||
Some(attrs_d) => {
|
||||
reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| {
|
||||
let meta_items = get_meta_items(attr_doc);
|
||||
// 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
|
||||
});
|
||||
}
|
||||
option::None => ()
|
||||
None => ()
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
@ -27,11 +27,12 @@ use middle;
|
||||
use util::nodemap::{NodeMap, NodeSet};
|
||||
|
||||
use serialize::Encodable;
|
||||
use std::mem;
|
||||
use std::cell::RefCell;
|
||||
use std::hash;
|
||||
use std::gc::Gc;
|
||||
use std::hash::Hash;
|
||||
use std::hash;
|
||||
use std::io::MemWriter;
|
||||
use std::mem;
|
||||
use std::str;
|
||||
use std::collections::HashMap;
|
||||
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 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;
|
||||
match item.node {
|
||||
ItemEnum(ref enum_def, _) => {
|
||||
@ -746,7 +747,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
||||
impl_path: PathElems,
|
||||
is_default_impl: bool,
|
||||
parent_id: NodeId,
|
||||
ast_method_opt: Option<@Method>) {
|
||||
ast_method_opt: Option<Gc<Method>>) {
|
||||
|
||||
debug!("encode_info_for_method: {:?} {}", m.def_id,
|
||||
token::get_ident(m.ident));
|
||||
@ -774,7 +775,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
||||
is_default_impl ||
|
||||
should_inline(ast_method.attrs.as_slice()) {
|
||||
encode_inlined_item(ecx, ebml_w,
|
||||
IIMethodRef(local_def(parent_id), false, ast_method));
|
||||
IIMethodRef(local_def(parent_id), false,
|
||||
&*ast_method));
|
||||
} else {
|
||||
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_inlined_item(ecx, ebml_w,
|
||||
IIMethodRef(def_id, true, m));
|
||||
IIMethodRef(def_id, true, &*m));
|
||||
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);
|
||||
}
|
||||
|
||||
fn encode_meta_item(ebml_w: &mut Encoder, mi: @MetaItem) {
|
||||
fn encode_meta_item(ebml_w: &mut Encoder, mi: Gc<MetaItem>) {
|
||||
match mi.node {
|
||||
MetaWord(ref name) => {
|
||||
ebml_w.start_tag(tag_meta_item_word);
|
||||
|
@ -40,7 +40,6 @@ use std::io::Seek;
|
||||
use std::io::MemWriter;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::string::String;
|
||||
|
||||
use serialize::ebml::reader;
|
||||
use serialize::ebml;
|
||||
@ -51,6 +50,7 @@ use writer = serialize::ebml::writer;
|
||||
|
||||
#[cfg(test)] use syntax::parse;
|
||||
#[cfg(test)] use syntax::print::pprust;
|
||||
#[cfg(test)] use std::gc::Gc;
|
||||
|
||||
struct DecodeContext<'a> {
|
||||
cdata: &'a cstore::crate_metadata,
|
||||
@ -146,7 +146,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
|
||||
match ii {
|
||||
ast::IIItem(i) => {
|
||||
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::DefUpvar(nid1, def, nid2, nid3) => {
|
||||
def::DefUpvar(xcx.tr_id(nid1),
|
||||
@(*def).tr(xcx),
|
||||
box(GC) (*def).tr(xcx),
|
||||
xcx.tr_id(nid2),
|
||||
xcx.tr_id(nid3))
|
||||
}
|
||||
@ -1395,17 +1395,17 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
|
||||
// Testing of astencode_gen
|
||||
|
||||
#[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);
|
||||
(*item).encode(ebml_w);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
#[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 mut d = reader::Decoder::new(chi_doc);
|
||||
@Decodable::decode(&mut d).unwrap()
|
||||
box(GC) Decodable::decode(&mut d).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -1440,7 +1440,7 @@ fn mk_ctxt() -> parse::ParseSess {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn roundtrip(in_item: Option<@ast::Item>) {
|
||||
fn roundtrip(in_item: Option<Gc<ast::Item>>) {
|
||||
use std::io::MemWriter;
|
||||
|
||||
let in_item = in_item.unwrap();
|
||||
|
@ -894,4 +894,3 @@ impl<'a> CheckLoanCtxt<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,8 +486,8 @@ struct StaticInitializerCtxt<'a> {
|
||||
impl<'a> visit::Visitor<()> for StaticInitializerCtxt<'a> {
|
||||
fn visit_expr(&mut self, ex: &Expr, _: ()) {
|
||||
match ex.node {
|
||||
ast::ExprAddrOf(mutbl, base) => {
|
||||
let base_cmt = self.bccx.cat_expr(base);
|
||||
ast::ExprAddrOf(mutbl, ref base) => {
|
||||
let base_cmt = self.bccx.cat_expr(&**base);
|
||||
let borrow_kind = ty::BorrowKind::from_mutbl(mutbl);
|
||||
// Check that we don't allow borrows of unsafe static items.
|
||||
if check_aliasability(self.bccx, ex.span, euv::AddrOf,
|
||||
|
@ -106,7 +106,7 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
|
||||
// flow dependent conditions.
|
||||
match item.node {
|
||||
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, ());
|
||||
@ -480,7 +480,7 @@ impl<'a> BorrowckCtxt<'a> {
|
||||
move_data::MoveExpr => {
|
||||
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
|
||||
Some(ast_map::NodeExpr(expr)) => {
|
||||
(ty::expr_ty_adjusted(self.tcx, expr), expr.span)
|
||||
(ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
|
||||
}
|
||||
r => {
|
||||
self.tcx.sess.bug(format!("MoveExpr({:?}) maps to \
|
||||
@ -512,7 +512,7 @@ impl<'a> BorrowckCtxt<'a> {
|
||||
move_data::Captured => {
|
||||
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
|
||||
Some(ast_map::NodeExpr(expr)) => {
|
||||
(ty::expr_ty_adjusted(self.tcx, expr), expr.span)
|
||||
(ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
|
||||
}
|
||||
r => {
|
||||
self.tcx.sess.bug(format!("Captured({:?}) maps to \
|
||||
|
@ -17,6 +17,8 @@ use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
struct CFGBuilder<'a> {
|
||||
tcx: &'a ty::ctxt,
|
||||
exit_map: NodeMap<CFGIndex>,
|
||||
@ -66,23 +68,23 @@ fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
|
||||
impl<'a> CFGBuilder<'a> {
|
||||
fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
|
||||
let mut stmts_exit = pred;
|
||||
for &stmt in blk.stmts.iter() {
|
||||
stmts_exit = self.stmt(stmt, stmts_exit);
|
||||
for stmt in blk.stmts.iter() {
|
||||
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])
|
||||
}
|
||||
|
||||
fn stmt(&mut self, stmt: @ast::Stmt, pred: CFGIndex) -> CFGIndex {
|
||||
fn stmt(&mut self, stmt: Gc<ast::Stmt>, pred: CFGIndex) -> CFGIndex {
|
||||
match stmt.node {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
self.decl(decl, pred)
|
||||
ast::StmtDecl(ref decl, _) => {
|
||||
self.decl(&**decl, pred)
|
||||
}
|
||||
|
||||
ast::StmtExpr(expr, _) | ast::StmtSemi(expr, _) => {
|
||||
self.expr(expr, pred)
|
||||
ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
|
||||
self.expr(expr.clone(), pred)
|
||||
}
|
||||
|
||||
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 {
|
||||
ast::DeclLocal(local) => {
|
||||
let init_exit = self.opt_expr(local.init, pred);
|
||||
self.pat(local.pat, init_exit)
|
||||
ast::DeclLocal(ref local) => {
|
||||
let init_exit = self.opt_expr(local.init.clone(), pred);
|
||||
self.pat(&*local.pat, init_exit)
|
||||
}
|
||||
|
||||
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 {
|
||||
ast::PatIdent(_, _, None) |
|
||||
ast::PatEnum(_, None) |
|
||||
@ -114,23 +116,23 @@ impl<'a> CFGBuilder<'a> {
|
||||
self.add_node(pat.id, [pred])
|
||||
}
|
||||
|
||||
ast::PatBox(subpat) |
|
||||
ast::PatRegion(subpat) |
|
||||
ast::PatIdent(_, _, Some(subpat)) => {
|
||||
let subpat_exit = self.pat(subpat, pred);
|
||||
ast::PatBox(ref subpat) |
|
||||
ast::PatRegion(ref subpat) |
|
||||
ast::PatIdent(_, _, Some(ref subpat)) => {
|
||||
let subpat_exit = self.pat(&**subpat, pred);
|
||||
self.add_node(pat.id, [subpat_exit])
|
||||
}
|
||||
|
||||
ast::PatEnum(_, Some(ref subpats)) |
|
||||
ast::PatTup(ref subpats) => {
|
||||
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])
|
||||
}
|
||||
|
||||
ast::PatStruct(_, ref subpats, _) => {
|
||||
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])
|
||||
}
|
||||
|
||||
@ -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,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Handles case where all of the patterns must match.
|
||||
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,
|
||||
pats: &[@ast::Pat],
|
||||
pats: &[Gc<ast::Pat>],
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Handles case where just one of the patterns must match.
|
||||
|
||||
if pats.len() == 1 {
|
||||
self.pat(pats[0], pred)
|
||||
self.pat(&*pats[0], pred)
|
||||
} else {
|
||||
let collect = self.add_dummy_node([]);
|
||||
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);
|
||||
}
|
||||
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 {
|
||||
ast::ExprBlock(blk) => {
|
||||
let blk_exit = self.block(blk, pred);
|
||||
ast::ExprBlock(ref blk) => {
|
||||
let blk_exit = self.block(&**blk, pred);
|
||||
self.add_node(expr.id, [blk_exit])
|
||||
}
|
||||
|
||||
ast::ExprIf(cond, then, None) => {
|
||||
ast::ExprIf(ref cond, ref then, None) => {
|
||||
//
|
||||
// [pred]
|
||||
// |
|
||||
@ -197,12 +199,12 @@ impl<'a> CFGBuilder<'a> {
|
||||
// v 3 v 4
|
||||
// [..expr..]
|
||||
//
|
||||
let cond_exit = self.expr(cond, pred); // 1
|
||||
let then_exit = self.block(then, cond_exit); // 2
|
||||
self.add_node(expr.id, [cond_exit, then_exit]) // 3,4
|
||||
let cond_exit = self.expr(cond.clone(), pred); // 1
|
||||
let then_exit = self.block(&**then, cond_exit); // 2
|
||||
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]
|
||||
// |
|
||||
@ -217,13 +219,13 @@ impl<'a> CFGBuilder<'a> {
|
||||
// v 4 v 5
|
||||
// [..expr..]
|
||||
//
|
||||
let cond_exit = self.expr(cond, pred); // 1
|
||||
let then_exit = self.block(then, cond_exit); // 2
|
||||
let else_exit = self.expr(otherwise, cond_exit); // 3
|
||||
self.add_node(expr.id, [then_exit, else_exit]) // 4, 5
|
||||
let cond_exit = self.expr(cond.clone(), pred); // 1
|
||||
let then_exit = self.block(&**then, cond_exit); // 2
|
||||
let else_exit = self.expr(otherwise.clone(), cond_exit); // 3
|
||||
self.add_node(expr.id, [then_exit, else_exit]) // 4, 5
|
||||
}
|
||||
|
||||
ast::ExprWhile(cond, body) => {
|
||||
ast::ExprWhile(ref cond, ref body) => {
|
||||
//
|
||||
// [pred]
|
||||
// |
|
||||
@ -242,22 +244,22 @@ impl<'a> CFGBuilder<'a> {
|
||||
// may cause additional edges.
|
||||
|
||||
// Is the condition considered part of the loop?
|
||||
let loopback = self.add_dummy_node([pred]); // 1
|
||||
let cond_exit = self.expr(cond, loopback); // 2
|
||||
let expr_exit = self.add_node(expr.id, [cond_exit]); // 3
|
||||
let loopback = self.add_dummy_node([pred]); // 1
|
||||
let cond_exit = self.expr(cond.clone(), loopback); // 2
|
||||
let expr_exit = self.add_node(expr.id, [cond_exit]); // 3
|
||||
self.loop_scopes.push(LoopScope {
|
||||
loop_id: expr.id,
|
||||
continue_index: loopback,
|
||||
break_index: expr_exit
|
||||
});
|
||||
let body_exit = self.block(body, cond_exit); // 4
|
||||
self.add_contained_edge(body_exit, loopback); // 5
|
||||
let body_exit = self.block(&**body, cond_exit); // 4
|
||||
self.add_contained_edge(body_exit, loopback); // 5
|
||||
expr_exit
|
||||
}
|
||||
|
||||
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
|
||||
|
||||
ast::ExprLoop(body, _) => {
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
//
|
||||
// [pred]
|
||||
// |
|
||||
@ -272,20 +274,20 @@ impl<'a> CFGBuilder<'a> {
|
||||
// Note that `break` and `loop` statements
|
||||
// may cause additional edges.
|
||||
|
||||
let loopback = self.add_dummy_node([pred]); // 1
|
||||
let expr_exit = self.add_node(expr.id, []); // 2
|
||||
let loopback = self.add_dummy_node([pred]); // 1
|
||||
let expr_exit = self.add_node(expr.id, []); // 2
|
||||
self.loop_scopes.push(LoopScope {
|
||||
loop_id: expr.id,
|
||||
continue_index: loopback,
|
||||
break_index: expr_exit,
|
||||
});
|
||||
let body_exit = self.block(body, loopback); // 3
|
||||
self.add_contained_edge(body_exit, loopback); // 4
|
||||
let body_exit = self.block(&**body, loopback); // 3
|
||||
self.add_contained_edge(body_exit, loopback); // 4
|
||||
self.loop_scopes.pop();
|
||||
expr_exit
|
||||
}
|
||||
|
||||
ast::ExprMatch(discr, ref arms) => {
|
||||
ast::ExprMatch(ref discr, ref arms) => {
|
||||
//
|
||||
// [pred]
|
||||
// |
|
||||
@ -309,21 +311,21 @@ impl<'a> CFGBuilder<'a> {
|
||||
// v 5 v v
|
||||
// [....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 mut guard_exit = discr_exit;
|
||||
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(),
|
||||
guard_exit); // 3
|
||||
let body_exit = self.expr(arm.body, pats_exit); // 4
|
||||
guard_exit); // 3
|
||||
let body_exit = self.expr(arm.body.clone(), pats_exit); // 4
|
||||
self.add_contained_edge(body_exit, expr_exit); // 5
|
||||
}
|
||||
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]
|
||||
// |
|
||||
@ -338,13 +340,13 @@ impl<'a> CFGBuilder<'a> {
|
||||
// v 3 v 4
|
||||
// [..exit..]
|
||||
//
|
||||
let l_exit = self.expr(l, pred); // 1
|
||||
let r_exit = self.expr(r, l_exit); // 2
|
||||
let l_exit = self.expr(l.clone(), pred); // 1
|
||||
let r_exit = self.expr(r.clone(), l_exit); // 2
|
||||
self.add_node(expr.id, [l_exit, r_exit]) // 3,4
|
||||
}
|
||||
|
||||
ast::ExprRet(v) => {
|
||||
let v_exit = self.opt_expr(v, pred);
|
||||
ast::ExprRet(ref v) => {
|
||||
let v_exit = self.opt_expr(v.clone(), pred);
|
||||
let b = self.add_node(expr.id, [v_exit]);
|
||||
self.add_returning_edge(expr, b);
|
||||
self.add_node(ast::DUMMY_NODE_ID, [])
|
||||
@ -370,21 +372,21 @@ impl<'a> CFGBuilder<'a> {
|
||||
self.straightline(expr, pred, elems.as_slice())
|
||||
}
|
||||
|
||||
ast::ExprCall(func, ref args) => {
|
||||
self.call(expr, pred, func, args.as_slice())
|
||||
ast::ExprCall(ref func, ref args) => {
|
||||
self.call(expr, pred, func.clone(), args.as_slice())
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
self.call(expr, pred, *args.get(0), args.slice_from(1))
|
||||
}
|
||||
|
||||
ast::ExprIndex(l, r) |
|
||||
ast::ExprBinary(_, l, r) if self.is_method_call(expr) => {
|
||||
self.call(expr, pred, l, [r])
|
||||
ast::ExprIndex(ref l, ref r) |
|
||||
ast::ExprBinary(_, ref l, ref r) if self.is_method_call(&*expr) => {
|
||||
self.call(expr, pred, l.clone(), [r.clone()])
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, e) if self.is_method_call(expr) => {
|
||||
self.call(expr, pred, e, [])
|
||||
ast::ExprUnary(_, ref e) if self.is_method_call(&*expr) => {
|
||||
self.call(expr, pred, e.clone(), [])
|
||||
}
|
||||
|
||||
ast::ExprTup(ref exprs) => {
|
||||
@ -393,7 +395,7 @@ impl<'a> CFGBuilder<'a> {
|
||||
|
||||
ast::ExprStruct(_, ref fields, base) => {
|
||||
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();
|
||||
self.straightline(expr, base_exit, field_exprs.as_slice())
|
||||
}
|
||||
@ -437,16 +439,16 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn call(&mut self,
|
||||
call_expr: @ast::Expr,
|
||||
call_expr: Gc<ast::Expr>,
|
||||
pred: CFGIndex,
|
||||
func_or_rcvr: @ast::Expr,
|
||||
args: &[@ast::Expr]) -> CFGIndex {
|
||||
func_or_rcvr: Gc<ast::Expr>,
|
||||
args: &[Gc<ast::Expr>]) -> CFGIndex {
|
||||
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
|
||||
self.straightline(call_expr, func_or_rcvr_exit, args)
|
||||
}
|
||||
|
||||
fn exprs(&mut self,
|
||||
exprs: &[@ast::Expr],
|
||||
exprs: &[Gc<ast::Expr>],
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Constructs graph for `exprs` evaluated in order
|
||||
|
||||
@ -454,7 +456,7 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn opt_expr(&mut self,
|
||||
opt_expr: Option<@ast::Expr>,
|
||||
opt_expr: Option<Gc<ast::Expr>>,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Constructs graph for `opt_expr` evaluated, if Some
|
||||
|
||||
@ -462,9 +464,9 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn straightline(&mut self,
|
||||
expr: @ast::Expr,
|
||||
expr: Gc<ast::Expr>,
|
||||
pred: CFGIndex,
|
||||
subexprs: &[@ast::Expr]) -> CFGIndex {
|
||||
subexprs: &[Gc<ast::Expr>]) -> CFGIndex {
|
||||
//! Handles case of an expression that evaluates `subexprs` in order
|
||||
|
||||
let subexprs_exit = self.exprs(subexprs, pred);
|
||||
@ -496,7 +498,7 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn add_exiting_edge(&mut self,
|
||||
from_expr: @ast::Expr,
|
||||
from_expr: Gc<ast::Expr>,
|
||||
from_index: CFGIndex,
|
||||
to_loop: LoopScope,
|
||||
to_index: CFGIndex) {
|
||||
@ -511,7 +513,7 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn add_returning_edge(&mut self,
|
||||
_from_expr: @ast::Expr,
|
||||
_from_expr: Gc<ast::Expr>,
|
||||
from_index: CFGIndex) {
|
||||
let mut data = CFGEdgeData {
|
||||
exiting_scopes: vec!(),
|
||||
@ -523,7 +525,7 @@ impl<'a> CFGBuilder<'a> {
|
||||
}
|
||||
|
||||
fn find_scope(&self,
|
||||
expr: @ast::Expr,
|
||||
expr: Gc<ast::Expr>,
|
||||
label: Option<ast::Ident>) -> LoopScope {
|
||||
match label {
|
||||
None => {
|
||||
|
@ -45,13 +45,13 @@ pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) {
|
||||
fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) {
|
||||
match it.node {
|
||||
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);
|
||||
}
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
for var in (*enum_definition).variants.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 {
|
||||
// Let through plain ~-string literals here
|
||||
PatLit(a) => if !is_str(a) { v.visit_expr(a, true); },
|
||||
PatRange(a, b) => {
|
||||
if !is_str(a) { v.visit_expr(a, true); }
|
||||
if !is_str(b) { v.visit_expr(b, true); }
|
||||
PatLit(ref a) => if !is_str(&**a) { v.visit_expr(&**a, true); },
|
||||
PatRange(ref a, ref b) => {
|
||||
if !is_str(&**a) { v.visit_expr(&**a, true); }
|
||||
if !is_str(&**b) { v.visit_expr(&**b, true); }
|
||||
}
|
||||
_ => visit::walk_pat(v, p, false)
|
||||
}
|
||||
@ -245,7 +245,7 @@ impl<'a> Visitor<()> for CheckItemRecursionVisitor<'a> {
|
||||
match self.def_map.borrow().find(&e.id) {
|
||||
Some(&DefStatic(def_id, _)) if
|
||||
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), ());
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
@ -35,15 +35,15 @@ impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
|
||||
|
||||
fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
|
||||
match e.node {
|
||||
ast::ExprWhile(e, b) => {
|
||||
self.visit_expr(e, cx);
|
||||
self.visit_block(b, Loop);
|
||||
ast::ExprWhile(ref e, ref b) => {
|
||||
self.visit_expr(&**e, cx);
|
||||
self.visit_block(&**b, Loop);
|
||||
}
|
||||
ast::ExprLoop(b, _) => {
|
||||
self.visit_block(b, Loop);
|
||||
ast::ExprLoop(ref b, _) => {
|
||||
self.visit_block(&**b, Loop);
|
||||
}
|
||||
ast::ExprFnBlock(_, b) | ast::ExprProc(_, b) => {
|
||||
self.visit_block(b, Closure);
|
||||
ast::ExprFnBlock(_, ref b) | ast::ExprProc(_, ref b) => {
|
||||
self.visit_block(&**b, Closure);
|
||||
}
|
||||
ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
|
||||
ast::ExprAgain(_) => self.require_loop("continue", cx, e.span),
|
||||
|
@ -19,6 +19,7 @@ use middle::ty;
|
||||
use util::ppaux::ty_to_str;
|
||||
|
||||
use std::cmp;
|
||||
use std::gc::Gc;
|
||||
use std::iter;
|
||||
use syntax::ast::*;
|
||||
use syntax::ast_util::{is_unguarded, walk_pat};
|
||||
@ -104,7 +105,7 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
|
||||
match opt_def {
|
||||
Some(DefStatic(did, false)) => {
|
||||
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,
|
||||
_ => 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) {
|
||||
cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \
|
||||
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 {
|
||||
PatIdent(_, _, Some(s)) => { raw_pat(s) }
|
||||
_ => { p }
|
||||
@ -193,7 +194,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &matrix) {
|
||||
cx.tcx.sess.span_err(sp, msg.as_slice());
|
||||
}
|
||||
|
||||
type matrix = Vec<Vec<@Pat> > ;
|
||||
type matrix = Vec<Vec<Gc<Pat>>>;
|
||||
|
||||
#[deriving(Clone)]
|
||||
enum useful {
|
||||
@ -224,7 +225,7 @@ enum ctor {
|
||||
|
||||
// Note: is_useful doesn't work on empty types, as the paper notes.
|
||||
// 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 {
|
||||
return useful_;
|
||||
}
|
||||
@ -327,7 +328,7 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
|
||||
|
||||
fn is_useful_specialized(cx: &MatchCheckCtxt,
|
||||
m: &matrix,
|
||||
v: &[@Pat],
|
||||
v: &[Gc<Pat>],
|
||||
ctor: ctor,
|
||||
arity: uint,
|
||||
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);
|
||||
match pat.node {
|
||||
PatWild | PatWildMulti => { None }
|
||||
@ -355,14 +356,14 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
|
||||
Some(DefVariant(_, id, _)) => Some(variant(id)),
|
||||
Some(DefStatic(did, false)) => {
|
||||
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
|
||||
}
|
||||
}
|
||||
PatLit(expr) => { Some(val(eval_const_expr(cx.tcx, expr))) }
|
||||
PatRange(lo, hi) => {
|
||||
Some(range(eval_const_expr(cx.tcx, lo), eval_const_expr(cx.tcx, hi)))
|
||||
PatLit(ref expr) => { Some(val(eval_const_expr(cx.tcx, &**expr))) }
|
||||
PatRange(ref lo, ref hi) => {
|
||||
Some(range(eval_const_expr(cx.tcx, &**lo), eval_const_expr(cx.tcx, &**hi)))
|
||||
}
|
||||
PatStruct(..) => {
|
||||
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);
|
||||
match pat.node {
|
||||
PatWild | PatWildMulti => { true }
|
||||
@ -548,12 +549,12 @@ fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
|
||||
}
|
||||
}
|
||||
|
||||
fn wild() -> @Pat {
|
||||
@Pat {id: 0, node: PatWild, span: DUMMY_SP}
|
||||
fn wild() -> Gc<Pat> {
|
||||
box(GC) Pat {id: 0, node: PatWild, span: DUMMY_SP}
|
||||
}
|
||||
|
||||
fn wild_multi() -> @Pat {
|
||||
@Pat {id: 0, node: PatWildMulti, span: DUMMY_SP}
|
||||
fn wild_multi() -> Gc<Pat> {
|
||||
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> {
|
||||
@ -572,13 +573,13 @@ fn range_covered_by_constructor(ctor_id: &ctor, from: &const_val, to: &const_val
|
||||
}
|
||||
|
||||
fn specialize(cx: &MatchCheckCtxt,
|
||||
r: &[@Pat],
|
||||
r: &[Gc<Pat>],
|
||||
ctor_id: &ctor,
|
||||
arity: uint,
|
||||
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 head: Option<Vec<@Pat>> = match n {
|
||||
let head: Option<Vec<Gc<Pat>>> = match n {
|
||||
&PatWild => {
|
||||
Some(Vec::from_elem(arity, wild()))
|
||||
}
|
||||
@ -597,7 +598,7 @@ fn specialize(cx: &MatchCheckCtxt,
|
||||
}
|
||||
Some(DefStatic(did, _)) => {
|
||||
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) {
|
||||
Some(true) => Some(vec!()),
|
||||
Some(false) => None,
|
||||
@ -617,7 +618,7 @@ fn specialize(cx: &MatchCheckCtxt,
|
||||
match def {
|
||||
DefStatic(did, _) => {
|
||||
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) {
|
||||
Some(true) => Some(vec!()),
|
||||
Some(false) => None,
|
||||
@ -681,7 +682,7 @@ fn specialize(cx: &MatchCheckCtxt,
|
||||
Some(vec!(inner.clone()))
|
||||
}
|
||||
&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) {
|
||||
Some(true) => Some(vec!()),
|
||||
Some(false) => None,
|
||||
@ -692,8 +693,8 @@ fn specialize(cx: &MatchCheckCtxt,
|
||||
}
|
||||
}
|
||||
&PatRange(ref from, ref to) => {
|
||||
let from_value = eval_const_expr(cx.tcx, *from);
|
||||
let to_value = eval_const_expr(cx.tcx, *to);
|
||||
let from_value = eval_const_expr(cx.tcx, &**from);
|
||||
let to_value = eval_const_expr(cx.tcx, &**to);
|
||||
match range_covered_by_constructor(ctor_id, &from_value, &to_value) {
|
||||
Some(true) => Some(vec!()),
|
||||
Some(false) => None,
|
||||
@ -733,7 +734,7 @@ fn specialize(cx: &MatchCheckCtxt,
|
||||
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]) {
|
||||
Some(Vec::from_slice(r.tail()))
|
||||
} else {
|
||||
@ -750,7 +751,7 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
|
||||
};
|
||||
|
||||
let mut spans = vec![];
|
||||
find_refutable(cx, loc.pat, &mut spans);
|
||||
find_refutable(cx, &*loc.pat, &mut spans);
|
||||
|
||||
for span in spans.iter() {
|
||||
cx.tcx.sess.span_err(*span,
|
||||
@ -769,7 +770,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
|
||||
visit::walk_fn(cx, kind, decl, body, sp, ());
|
||||
for input in decl.inputs.iter() {
|
||||
let mut spans = vec![];
|
||||
find_refutable(cx, input.pat, &mut spans);
|
||||
find_refutable(cx, &*input.pat, &mut spans);
|
||||
|
||||
for span in spans.iter() {
|
||||
cx.tcx.sess.span_err(*span,
|
||||
@ -799,8 +800,8 @@ fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) {
|
||||
}
|
||||
|
||||
match pat.node {
|
||||
PatBox(sub) | PatRegion(sub) | PatIdent(_, _, Some(sub)) => {
|
||||
find_refutable(cx, sub, spans)
|
||||
PatBox(ref sub) | PatRegion(ref sub) | PatIdent(_, _, Some(ref sub)) => {
|
||||
find_refutable(cx, &**sub, spans)
|
||||
}
|
||||
PatWild | PatWildMulti | PatIdent(_, _, None) => {}
|
||||
PatLit(lit) => {
|
||||
@ -817,12 +818,12 @@ fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) {
|
||||
PatRange(_, _) => { this_pattern!() }
|
||||
PatStruct(_, ref fields, _) => {
|
||||
for f in fields.iter() {
|
||||
find_refutable(cx, f.pat, spans);
|
||||
find_refutable(cx, &*f.pat, spans);
|
||||
}
|
||||
}
|
||||
PatTup(ref elts) | PatEnum(_, Some(ref elts))=> {
|
||||
for elt in elts.iter() {
|
||||
find_refutable(cx, *elt, spans)
|
||||
find_refutable(cx, &**elt, spans)
|
||||
}
|
||||
}
|
||||
PatEnum(_,_) => {}
|
||||
@ -835,12 +836,12 @@ fn find_refutable(cx: &MatchCheckCtxt, pat: &Pat, spans: &mut Vec<Span>) {
|
||||
|
||||
fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
||||
has_guard: bool,
|
||||
pats: &[@Pat]) {
|
||||
pats: &[Gc<Pat>]) {
|
||||
let tcx = cx.tcx;
|
||||
let def_map = &tcx.def_map;
|
||||
let mut by_ref_span = None;
|
||||
for pat in pats.iter() {
|
||||
pat_bindings(def_map, *pat, |bm, _, span, _path| {
|
||||
pat_bindings(def_map, &**pat, |bm, _, span, _path| {
|
||||
match bm {
|
||||
BindByRef(_) => {
|
||||
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
|
||||
|
||||
// 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(
|
||||
p.span,
|
||||
"cannot bind by-move with sub-bindings");
|
||||
@ -875,8 +876,8 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
||||
};
|
||||
|
||||
for pat in pats.iter() {
|
||||
walk_pat(*pat, |p| {
|
||||
if pat_is_binding(def_map, p) {
|
||||
walk_pat(&**pat, |p| {
|
||||
if pat_is_binding(def_map, &*p) {
|
||||
match p.node {
|
||||
PatIdent(BindByValue(_), _, sub) => {
|
||||
let pat_ty = ty::node_id_to_type(tcx, p.id);
|
||||
|
@ -77,13 +77,14 @@ impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
|
||||
fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
|
||||
debug!("visit_item(item={})", pprust::item_to_str(i));
|
||||
match i.node {
|
||||
ast::ItemStatic(_, mutability, expr) => {
|
||||
ast::ItemStatic(_, mutability, ref expr) => {
|
||||
match mutability {
|
||||
ast::MutImmutable => {
|
||||
self.visit_expr(expr, true);
|
||||
self.visit_expr(&**expr, true);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ use syntax::visit;
|
||||
use syntax::{ast, ast_map, ast_util};
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
|
||||
//
|
||||
// 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))
|
||||
}
|
||||
|
||||
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);
|
||||
match opt_def {
|
||||
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,
|
||||
enum_def: ast::DefId,
|
||||
variant_def: ast::DefId)
|
||||
-> Option<@Expr> {
|
||||
fn variant_expr(variants: &[ast::P<ast::Variant>], id: ast::NodeId) -> Option<@Expr> {
|
||||
-> Option<Gc<Expr>> {
|
||||
fn variant_expr(variants: &[ast::P<ast::Variant>],
|
||||
id: ast::NodeId) -> Option<Gc<Expr>> {
|
||||
for variant in variants.iter() {
|
||||
if variant.node.id == id {
|
||||
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)
|
||||
-> Option<@Expr> {
|
||||
-> Option<Gc<Expr>> {
|
||||
if ast_util::is_local(def_id) {
|
||||
{
|
||||
match tcx.map.find(def_id.node) {
|
||||
@ -186,39 +188,39 @@ impl<'a> ConstEvalVisitor<'a> {
|
||||
None => {}
|
||||
}
|
||||
let cn = match e.node {
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitStr(..) | ast::LitFloat(..) => general_const,
|
||||
_ => integral_const
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, inner) | ast::ExprParen(inner) =>
|
||||
self.classify(inner),
|
||||
ast::ExprUnary(_, ref inner) | ast::ExprParen(ref inner) =>
|
||||
self.classify(&**inner),
|
||||
|
||||
ast::ExprBinary(_, a, b) =>
|
||||
join(self.classify(a), self.classify(b)),
|
||||
ast::ExprBinary(_, ref a, ref b) =>
|
||||
join(self.classify(&**a), self.classify(&**b)),
|
||||
|
||||
ast::ExprTup(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 {
|
||||
ast::ExprVstoreSlice => self.classify(e),
|
||||
ast::ExprVstoreSlice => self.classify(&**e),
|
||||
ast::ExprVstoreUniq |
|
||||
ast::ExprVstoreMutSlice => non_const
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
ast::ExprCast(base, _) => {
|
||||
ast::ExprCast(ref base, _) => {
|
||||
let ty = ty::expr_ty(self.tcx, e);
|
||||
let base = self.classify(base);
|
||||
let base = self.classify(&**base);
|
||||
if ty::type_is_integral(ty) {
|
||||
join(integral_const, base)
|
||||
} 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) =>
|
||||
join(self.classify(base), self.classify(idx)),
|
||||
ast::ExprIndex(ref base, ref 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
|
||||
// surrounding nonlocal constants. But we don't yet.
|
||||
@ -257,7 +260,7 @@ impl<'a> ConstEvalVisitor<'a> {
|
||||
fn lookup_constness(&self, e: &Expr) -> constness {
|
||||
match lookup_const(self.tcx, e) {
|
||||
Some(rhs) => {
|
||||
let ty = ty::expr_ty(self.tcx, rhs);
|
||||
let ty = ty::expr_ty(self.tcx, &*rhs);
|
||||
if ty::type_is_integral(ty) {
|
||||
integral_const
|
||||
} else {
|
||||
@ -310,8 +313,8 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
|
||||
-> Result<const_val, String> {
|
||||
fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
|
||||
match e.node {
|
||||
ExprUnary(UnNeg, inner) => {
|
||||
match eval_const_expr_partial(tcx, inner) {
|
||||
ExprUnary(UnNeg, ref inner) => {
|
||||
match eval_const_expr_partial(tcx, &**inner) {
|
||||
Ok(const_float(f)) => Ok(const_float(-f)),
|
||||
Ok(const_int(i)) => Ok(const_int(-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())
|
||||
}
|
||||
}
|
||||
ExprUnary(UnNot, inner) => {
|
||||
match eval_const_expr_partial(tcx, inner) {
|
||||
ExprUnary(UnNot, ref inner) => {
|
||||
match eval_const_expr_partial(tcx, &**inner) {
|
||||
Ok(const_int(i)) => Ok(const_int(!i)),
|
||||
Ok(const_uint(i)) => Ok(const_uint(!i)),
|
||||
Ok(const_bool(b)) => Ok(const_bool(!b)),
|
||||
_ => Err("not on float or string".to_string())
|
||||
}
|
||||
}
|
||||
ExprBinary(op, a, b) => {
|
||||
match (eval_const_expr_partial(tcx, a),
|
||||
eval_const_expr_partial(tcx, b)) {
|
||||
ExprBinary(op, ref a, ref b) => {
|
||||
match (eval_const_expr_partial(tcx, &**a),
|
||||
eval_const_expr_partial(tcx, &**b)) {
|
||||
(Ok(const_float(a)), Ok(const_float(b))) => {
|
||||
match op {
|
||||
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())
|
||||
}
|
||||
}
|
||||
ExprCast(base, target_ty) => {
|
||||
ExprCast(ref base, ref target_ty) => {
|
||||
// This tends to get called w/o the type actually having been
|
||||
// populated in the ctxt, which was causing things to blow up
|
||||
// (#5900). Fall back to doing a limited lookup to get past it.
|
||||
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(|| {
|
||||
tcx.ty_ctxt().sess.span_fatal(target_ty.span,
|
||||
"target type not found for \
|
||||
const cast")
|
||||
});
|
||||
|
||||
let base = eval_const_expr_partial(tcx, base);
|
||||
let base = eval_const_expr_partial(tcx, &**base);
|
||||
match base {
|
||||
Err(_) => base,
|
||||
Ok(val) => {
|
||||
@ -479,14 +482,14 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
|
||||
}
|
||||
ExprPath(_) => {
|
||||
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())
|
||||
}
|
||||
}
|
||||
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
|
||||
ExprVstore(e, _) => eval_const_expr_partial(tcx, e),
|
||||
ExprParen(e) => eval_const_expr_partial(tcx, e),
|
||||
ExprVstore(ref e, _) => eval_const_expr_partial(tcx, &**e),
|
||||
ExprParen(ref e) => eval_const_expr_partial(tcx, &**e),
|
||||
ExprBlock(ref block) => {
|
||||
match block.expr {
|
||||
Some(ref expr) => eval_const_expr_partial(tcx, &**expr),
|
||||
|
@ -21,7 +21,7 @@ use middle::def;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use std::io;
|
||||
use std::string::String;
|
||||
use std::gc::Gc;
|
||||
use std::uint;
|
||||
use syntax::ast;
|
||||
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);
|
||||
|
||||
for &stmt in blk.stmts.iter() {
|
||||
self.walk_stmt(stmt, in_out, loop_scopes);
|
||||
for stmt in blk.stmts.iter() {
|
||||
self.walk_stmt(stmt.clone(), 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,
|
||||
stmt: @ast::Stmt,
|
||||
stmt: Gc<ast::Stmt>,
|
||||
in_out: &mut [uint],
|
||||
loop_scopes: &mut Vec<LoopScope> ) {
|
||||
match stmt.node {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
self.walk_decl(decl, in_out, loop_scopes);
|
||||
ast::StmtDecl(ref decl, _) => {
|
||||
self.walk_decl(decl.clone(), in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::StmtExpr(expr, _) | ast::StmtSemi(expr, _) => {
|
||||
self.walk_expr(expr, in_out, loop_scopes);
|
||||
ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
|
||||
self.walk_expr(&**expr, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::StmtMac(..) => {
|
||||
@ -375,11 +375,11 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
}
|
||||
|
||||
fn walk_decl(&mut self,
|
||||
decl: @ast::Decl,
|
||||
decl: Gc<ast::Decl>,
|
||||
in_out: &mut [uint],
|
||||
loop_scopes: &mut Vec<LoopScope> ) {
|
||||
match decl.node {
|
||||
ast::DeclLocal(local) => {
|
||||
ast::DeclLocal(ref local) => {
|
||||
self.walk_opt_expr(local.init, 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
|
||||
// ( 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();
|
||||
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);
|
||||
join_bits(&self.dfcx.oper, then_bits, in_out);
|
||||
@ -437,14 +437,14 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
// <--+ (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();
|
||||
loop_scopes.push(LoopScope {
|
||||
loop_id: expr.id,
|
||||
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);
|
||||
let new_loop_scope = loop_scopes.pop().unwrap();
|
||||
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::ExprLoop(blk, _) => {
|
||||
ast::ExprLoop(ref blk, _) => {
|
||||
//
|
||||
// (expr) <--+
|
||||
// | |
|
||||
@ -468,7 +468,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
loop_id: expr.id,
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ast::ExprMatch(discr, ref arms) => {
|
||||
ast::ExprMatch(ref discr, ref arms) => {
|
||||
//
|
||||
// (discr)
|
||||
// / | \
|
||||
@ -488,7 +488,7 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
// ( succ )
|
||||
//
|
||||
//
|
||||
self.walk_expr(discr, in_out, loop_scopes);
|
||||
self.walk_expr(&**discr, in_out, loop_scopes);
|
||||
|
||||
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(),
|
||||
body,
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -530,30 +530,30 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
self.reset(in_out);
|
||||
}
|
||||
|
||||
ast::ExprAssign(l, r) |
|
||||
ast::ExprAssignOp(_, l, r) => {
|
||||
self.walk_expr(r, in_out, loop_scopes);
|
||||
self.walk_expr(l, in_out, loop_scopes);
|
||||
ast::ExprAssign(ref l, ref r) |
|
||||
ast::ExprAssignOp(_, ref l, ref r) => {
|
||||
self.walk_expr(&**r, in_out, loop_scopes);
|
||||
self.walk_expr(&**l, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprVec(ref exprs) => {
|
||||
self.walk_exprs(exprs.as_slice(), in_out, loop_scopes)
|
||||
}
|
||||
|
||||
ast::ExprRepeat(l, r) => {
|
||||
self.walk_expr(l, in_out, loop_scopes);
|
||||
self.walk_expr(r, in_out, loop_scopes);
|
||||
ast::ExprRepeat(ref l, ref r) => {
|
||||
self.walk_expr(&**l, in_out, loop_scopes);
|
||||
self.walk_expr(&**r, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprStruct(_, ref fields, with_expr) => {
|
||||
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);
|
||||
}
|
||||
|
||||
ast::ExprCall(f, ref args) => {
|
||||
self.walk_expr(f, in_out, loop_scopes);
|
||||
ast::ExprCall(ref f, ref args) => {
|
||||
self.walk_expr(&**f, 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);
|
||||
}
|
||||
|
||||
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
|
||||
self.walk_expr(l, in_out, loop_scopes);
|
||||
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
|
||||
self.walk_expr(&**l, in_out, loop_scopes);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -589,31 +589,31 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
ast::ExprLit(..) |
|
||||
ast::ExprPath(..) => {}
|
||||
|
||||
ast::ExprAddrOf(_, e) |
|
||||
ast::ExprCast(e, _) |
|
||||
ast::ExprUnary(_, e) |
|
||||
ast::ExprParen(e) |
|
||||
ast::ExprVstore(e, _) |
|
||||
ast::ExprField(e, _, _) => {
|
||||
self.walk_expr(e, in_out, loop_scopes);
|
||||
ast::ExprAddrOf(_, ref e) |
|
||||
ast::ExprCast(ref e, _) |
|
||||
ast::ExprUnary(_, ref e) |
|
||||
ast::ExprParen(ref e) |
|
||||
ast::ExprVstore(ref e, _) |
|
||||
ast::ExprField(ref e, _, _) => {
|
||||
self.walk_expr(&**e, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprBox(s, e) => {
|
||||
self.walk_expr(s, in_out, loop_scopes);
|
||||
self.walk_expr(e, in_out, loop_scopes);
|
||||
ast::ExprBox(ref s, ref e) => {
|
||||
self.walk_expr(&**s, in_out, loop_scopes);
|
||||
self.walk_expr(&**e, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprInlineAsm(ref inline_asm) => {
|
||||
for &(_, expr) in inline_asm.inputs.iter() {
|
||||
self.walk_expr(expr, in_out, loop_scopes);
|
||||
for &(_, ref expr) in inline_asm.inputs.iter() {
|
||||
self.walk_expr(&**expr, in_out, loop_scopes);
|
||||
}
|
||||
for &(_, expr) in inline_asm.outputs.iter() {
|
||||
self.walk_expr(expr, in_out, loop_scopes);
|
||||
for &(_, ref expr) in inline_asm.outputs.iter() {
|
||||
self.walk_expr(&**expr, in_out, loop_scopes);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprBlock(blk) => {
|
||||
self.walk_block(blk, in_out, loop_scopes);
|
||||
ast::ExprBlock(ref blk) => {
|
||||
self.walk_block(&**blk, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprMac(..) => {
|
||||
@ -674,26 +674,26 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||
}
|
||||
|
||||
fn walk_exprs(&mut self,
|
||||
exprs: &[@ast::Expr],
|
||||
exprs: &[Gc<ast::Expr>],
|
||||
in_out: &mut [uint],
|
||||
loop_scopes: &mut Vec<LoopScope> ) {
|
||||
for &expr in exprs.iter() {
|
||||
self.walk_expr(expr, in_out, loop_scopes);
|
||||
for expr in exprs.iter() {
|
||||
self.walk_expr(&**expr, in_out, loop_scopes);
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_opt_expr(&mut self,
|
||||
opt_expr: Option<@ast::Expr>,
|
||||
opt_expr: Option<Gc<ast::Expr>>,
|
||||
in_out: &mut [uint],
|
||||
loop_scopes: &mut Vec<LoopScope> ) {
|
||||
for &expr in opt_expr.iter() {
|
||||
self.walk_expr(expr, in_out, loop_scopes);
|
||||
for expr in opt_expr.iter() {
|
||||
self.walk_expr(&**expr, in_out, loop_scopes);
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_call(&mut self,
|
||||
call_id: ast::NodeId,
|
||||
args: &[@ast::Expr],
|
||||
args: &[Gc<ast::Expr>],
|
||||
in_out: &mut [uint],
|
||||
loop_scopes: &mut Vec<LoopScope> ) {
|
||||
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,
|
||||
pat: @ast::Pat,
|
||||
pat: Gc<ast::Pat>,
|
||||
in_out: &mut [uint],
|
||||
_loop_scopes: &mut Vec<LoopScope> ) {
|
||||
debug!("DataFlowContext::walk_pat(pat={}, 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));
|
||||
self.merge_with_entry_set(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,
|
||||
pats: &[@ast::Pat],
|
||||
pats: &[Gc<ast::Pat>],
|
||||
in_out: &mut [uint],
|
||||
loop_scopes: &mut Vec<LoopScope> ) {
|
||||
if pats.len() == 1 {
|
||||
|
@ -184,25 +184,25 @@ impl<'a> MarkSymbolVisitor<'a> {
|
||||
}
|
||||
});
|
||||
self.live_symbols.extend(live_fields.map(|f| f.node.id));
|
||||
visit::walk_item(self, item, ());
|
||||
visit::walk_item(self, &*item, ());
|
||||
}
|
||||
ast::ItemFn(..)
|
||||
| ast::ItemTy(..)
|
||||
| ast::ItemEnum(..)
|
||||
| ast::ItemStatic(..) => {
|
||||
visit::walk_item(self, item, ());
|
||||
visit::walk_item(self, &*item, ());
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
ast_map::NodeTraitMethod(trait_method) => {
|
||||
visit::walk_trait_method(self, trait_method, ());
|
||||
visit::walk_trait_method(self, &*trait_method, ());
|
||||
}
|
||||
ast_map::NodeMethod(method) => {
|
||||
visit::walk_block(self, method.body, ());
|
||||
visit::walk_block(self, &*method.body, ());
|
||||
}
|
||||
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);
|
||||
}
|
||||
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.
|
||||
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
|
||||
match *trait_method {
|
||||
ast::Provided(method) => visit::walk_block(self, method.body, ()),
|
||||
ast::Provided(ref method) => visit::walk_block(self, &*method.body, ()),
|
||||
ast::Required(_) => ()
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::local_def;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Def {
|
||||
DefFn(ast::DefId, ast::FnStyle),
|
||||
@ -29,7 +31,7 @@ pub enum Def {
|
||||
DefBinding(ast::NodeId, ast::BindingMode),
|
||||
DefUse(ast::DefId),
|
||||
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), // id for the block/body of the closure expr
|
||||
|
||||
|
@ -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 {
|
||||
ast::ExprIndex(base, _) => ty::node_id_to_type(self.tcx, base.id),
|
||||
_ => return
|
||||
@ -173,11 +173,11 @@ impl<'a> Visitor<()> for EffectCheckVisitor<'a> {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
ast::ExprAssign(base, _) | ast::ExprAssignOp(_, base, _) => {
|
||||
self.check_str_index(base);
|
||||
ast::ExprAssign(ref base, _) | ast::ExprAssignOp(_, ref base, _) => {
|
||||
self.check_str_index(&**base);
|
||||
}
|
||||
ast::ExprAddrOf(ast::MutMutable, base) => {
|
||||
self.check_str_index(base);
|
||||
ast::ExprAddrOf(ast::MutMutable, ref base) => {
|
||||
self.check_str_index(&**base);
|
||||
}
|
||||
ast::ExprInlineAsm(..) => {
|
||||
self.require_unsafe(expr.span, "use of inline assembly")
|
||||
|
@ -25,6 +25,8 @@ use syntax::ast;
|
||||
use syntax::codemap::{Span};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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.
|
||||
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);
|
||||
}
|
||||
|
||||
fn consume_exprs(&mut self, exprs: &Vec<@ast::Expr>) {
|
||||
for &expr in exprs.iter() {
|
||||
self.consume_expr(expr);
|
||||
fn consume_exprs(&mut self, exprs: &Vec<Gc<ast::Expr>>) {
|
||||
for expr in exprs.iter() {
|
||||
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);
|
||||
|
||||
match expr.node {
|
||||
ast::ExprParen(subexpr) => {
|
||||
ast::ExprParen(ref subexpr) => {
|
||||
// Argh but is ExprParen horrible. So, if we consume
|
||||
// `(x)`, that generally is also consuming `x`, UNLESS
|
||||
// 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) {
|
||||
self.walk_expr(expr);
|
||||
} 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);
|
||||
|
||||
match expr.node {
|
||||
ast::ExprParen(subexpr) => {
|
||||
self.walk_expr(subexpr)
|
||||
ast::ExprParen(ref subexpr) => {
|
||||
self.walk_expr(&**subexpr)
|
||||
}
|
||||
|
||||
ast::ExprPath(..) => { }
|
||||
|
||||
ast::ExprUnary(ast::UnDeref, base) => { // *base
|
||||
if !self.walk_overloaded_operator(expr, base, []) {
|
||||
self.select_from_expr(base);
|
||||
ast::ExprUnary(ast::UnDeref, ref base) => { // *base
|
||||
if !self.walk_overloaded_operator(expr, &**base, []) {
|
||||
self.select_from_expr(&**base);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprField(base, _, _) => { // base.f
|
||||
self.select_from_expr(base);
|
||||
ast::ExprField(ref base, _, _) => { // base.f
|
||||
self.select_from_expr(&**base);
|
||||
}
|
||||
|
||||
ast::ExprIndex(lhs, rhs) => { // lhs[rhs]
|
||||
if !self.walk_overloaded_operator(expr, lhs, [rhs]) {
|
||||
self.select_from_expr(lhs);
|
||||
self.consume_expr(rhs);
|
||||
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
|
||||
self.select_from_expr(&**lhs);
|
||||
self.consume_expr(&**rhs);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprCall(callee, ref args) => { // callee(args)
|
||||
self.walk_callee(expr, callee);
|
||||
ast::ExprCall(ref callee, ref args) => { // callee(args)
|
||||
self.walk_callee(expr, &**callee);
|
||||
self.consume_exprs(args);
|
||||
}
|
||||
|
||||
@ -272,27 +274,27 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
self.consume_exprs(args);
|
||||
}
|
||||
|
||||
ast::ExprStruct(_, ref fields, opt_with) => {
|
||||
self.walk_struct_expr(expr, fields, opt_with);
|
||||
ast::ExprStruct(_, ref fields, ref opt_with) => {
|
||||
self.walk_struct_expr(expr, fields, opt_with.clone());
|
||||
}
|
||||
|
||||
ast::ExprTup(ref exprs) => {
|
||||
self.consume_exprs(exprs);
|
||||
}
|
||||
|
||||
ast::ExprIf(cond_expr, then_blk, opt_else_expr) => {
|
||||
self.consume_expr(cond_expr);
|
||||
self.walk_block(then_blk);
|
||||
ast::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
|
||||
self.consume_expr(&**cond_expr);
|
||||
self.walk_block(&**then_blk);
|
||||
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
|
||||
// walking the arms:
|
||||
self.walk_expr(discr);
|
||||
let discr_cmt = return_if_err!(self.mc.cat_expr(discr));
|
||||
self.walk_expr(&**discr);
|
||||
let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
|
||||
for arm in arms.iter() {
|
||||
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);
|
||||
}
|
||||
|
||||
ast::ExprAddrOf(m, base) => { // &base
|
||||
ast::ExprAddrOf(m, ref base) => { // &base
|
||||
// make sure that the thing we are pointing out stays valid
|
||||
// for the lifetime `scope_r` of the resulting ptr:
|
||||
let expr_ty = ty::expr_ty(self.tcx(), expr);
|
||||
if !ty::type_is_bot(expr_ty) {
|
||||
let r = ty::ty_region(self.tcx(), expr.span, expr_ty);
|
||||
let bk = ty::BorrowKind::from_mutbl(m);
|
||||
self.borrow_expr(base, r, bk, AddrOf);
|
||||
self.borrow_expr(&**base, r, bk, AddrOf);
|
||||
} else {
|
||||
self.walk_expr(base);
|
||||
self.walk_expr(&**base);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprInlineAsm(ref ia) => {
|
||||
for &(_, input) in ia.inputs.iter() {
|
||||
self.consume_expr(input);
|
||||
for &(_, ref input) in ia.inputs.iter() {
|
||||
self.consume_expr(&**input);
|
||||
}
|
||||
|
||||
for &(_, output) in ia.outputs.iter() {
|
||||
self.mutate_expr(expr, output, JustWrite);
|
||||
for &(_, ref output) in ia.outputs.iter() {
|
||||
self.mutate_expr(expr, &**output, JustWrite);
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,59 +331,59 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
ast::ExprAgain(..) |
|
||||
ast::ExprLit(..) => {}
|
||||
|
||||
ast::ExprLoop(blk, _) => {
|
||||
self.walk_block(blk);
|
||||
ast::ExprLoop(ref blk, _) => {
|
||||
self.walk_block(&**blk);
|
||||
}
|
||||
|
||||
ast::ExprWhile(cond_expr, blk) => {
|
||||
self.consume_expr(cond_expr);
|
||||
self.walk_block(blk);
|
||||
ast::ExprWhile(ref cond_expr, ref blk) => {
|
||||
self.consume_expr(&**cond_expr);
|
||||
self.walk_block(&**blk);
|
||||
}
|
||||
|
||||
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
|
||||
|
||||
ast::ExprUnary(_, lhs) => {
|
||||
if !self.walk_overloaded_operator(expr, lhs, []) {
|
||||
self.consume_expr(lhs);
|
||||
ast::ExprUnary(_, ref lhs) => {
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, []) {
|
||||
self.consume_expr(&**lhs);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprBinary(_, lhs, rhs) => {
|
||||
if !self.walk_overloaded_operator(expr, lhs, [rhs]) {
|
||||
self.consume_expr(lhs);
|
||||
self.consume_expr(rhs);
|
||||
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
|
||||
self.consume_expr(&**lhs);
|
||||
self.consume_expr(&**rhs);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprBlock(blk) => {
|
||||
self.walk_block(blk);
|
||||
ast::ExprBlock(ref blk) => {
|
||||
self.walk_block(&**blk);
|
||||
}
|
||||
|
||||
ast::ExprRet(ref opt_expr) => {
|
||||
for expr in opt_expr.iter() {
|
||||
self.consume_expr(*expr);
|
||||
self.consume_expr(&**expr);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprAssign(lhs, rhs) => {
|
||||
self.mutate_expr(expr, lhs, JustWrite);
|
||||
self.consume_expr(rhs);
|
||||
ast::ExprAssign(ref lhs, ref rhs) => {
|
||||
self.mutate_expr(expr, &**lhs, JustWrite);
|
||||
self.consume_expr(&**rhs);
|
||||
}
|
||||
|
||||
ast::ExprCast(base, _) => {
|
||||
self.consume_expr(base);
|
||||
ast::ExprCast(ref base, _) => {
|
||||
self.consume_expr(&**base);
|
||||
}
|
||||
|
||||
ast::ExprAssignOp(_, lhs, rhs) => {
|
||||
ast::ExprAssignOp(_, ref lhs, ref rhs) => {
|
||||
// This will have to change if/when we support
|
||||
// overloaded operators for `+=` and so forth.
|
||||
self.mutate_expr(expr, lhs, WriteAndRead);
|
||||
self.consume_expr(rhs);
|
||||
self.mutate_expr(expr, &**lhs, WriteAndRead);
|
||||
self.consume_expr(&**rhs);
|
||||
}
|
||||
|
||||
ast::ExprRepeat(base, count) => {
|
||||
self.consume_expr(base);
|
||||
self.consume_expr(count);
|
||||
ast::ExprRepeat(ref base, ref count) => {
|
||||
self.consume_expr(&**base);
|
||||
self.consume_expr(&**count);
|
||||
}
|
||||
|
||||
ast::ExprFnBlock(..) |
|
||||
@ -389,13 +391,13 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
self.walk_captures(expr)
|
||||
}
|
||||
|
||||
ast::ExprVstore(base, _) => {
|
||||
self.consume_expr(base);
|
||||
ast::ExprVstore(ref base, _) => {
|
||||
self.consume_expr(&**base);
|
||||
}
|
||||
|
||||
ast::ExprBox(place, base) => {
|
||||
self.consume_expr(place);
|
||||
self.consume_expr(base);
|
||||
ast::ExprBox(ref place, ref base) => {
|
||||
self.consume_expr(&**place);
|
||||
self.consume_expr(&**base);
|
||||
}
|
||||
|
||||
ast::ExprMac(..) => {
|
||||
@ -448,10 +450,10 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
|
||||
fn walk_stmt(&mut self, stmt: &ast::Stmt) {
|
||||
match stmt.node {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
ast::StmtDecl(ref decl, _) => {
|
||||
match decl.node {
|
||||
ast::DeclLocal(local) => {
|
||||
self.walk_local(local);
|
||||
ast::DeclLocal(ref local) => {
|
||||
self.walk_local(local.clone());
|
||||
}
|
||||
|
||||
ast::DeclItem(_) => {
|
||||
@ -461,9 +463,9 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
}
|
||||
}
|
||||
|
||||
ast::StmtExpr(expr, _) |
|
||||
ast::StmtSemi(expr, _) => {
|
||||
self.consume_expr(expr);
|
||||
ast::StmtExpr(ref expr, _) |
|
||||
ast::StmtSemi(ref expr, _) => {
|
||||
self.consume_expr(&**expr);
|
||||
}
|
||||
|
||||
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 {
|
||||
None => {
|
||||
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);
|
||||
})
|
||||
}
|
||||
|
||||
Some(expr) => {
|
||||
Some(ref expr) => {
|
||||
// Variable declarations with
|
||||
// initializers are considered
|
||||
// "assigns", which is handled by
|
||||
// `walk_pat`:
|
||||
self.walk_expr(expr);
|
||||
let init_cmt = return_if_err!(self.mc.cat_expr(expr));
|
||||
self.walk_expr(&**expr);
|
||||
let init_cmt = return_if_err!(self.mc.cat_expr(&**expr));
|
||||
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);
|
||||
|
||||
for stmt in blk.stmts.iter() {
|
||||
self.walk_stmt(*stmt);
|
||||
self.walk_stmt(&**stmt);
|
||||
}
|
||||
|
||||
for tail_expr in blk.expr.iter() {
|
||||
self.consume_expr(*tail_expr);
|
||||
self.consume_expr(&**tail_expr);
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_struct_expr(&mut self,
|
||||
_expr: &ast::Expr,
|
||||
fields: &Vec<ast::Field>,
|
||||
opt_with: Option<@ast::Expr>) {
|
||||
opt_with: Option<Gc<ast::Expr>>) {
|
||||
// Consume the expressions supplying values for each field.
|
||||
for field in fields.iter() {
|
||||
self.consume_expr(field.expr);
|
||||
self.consume_expr(&*field.expr);
|
||||
}
|
||||
|
||||
let with_expr = match opt_with {
|
||||
Some(w) => { w }
|
||||
Some(ref w) => { w.clone() }
|
||||
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`
|
||||
// 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.
|
||||
for with_field in with_fields.iter() {
|
||||
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_field.ident,
|
||||
with_field.mt.ty);
|
||||
@ -673,7 +676,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
fn walk_overloaded_operator(&mut self,
|
||||
expr: &ast::Expr,
|
||||
receiver: &ast::Expr,
|
||||
args: &[@ast::Expr])
|
||||
args: &[Gc<ast::Expr>])
|
||||
-> bool
|
||||
{
|
||||
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 bk = ty::ImmBorrow;
|
||||
|
||||
for &arg in args.iter() {
|
||||
self.borrow_expr(arg, r, bk, OverloadedOperator);
|
||||
for arg in args.iter() {
|
||||
self.borrow_expr(&**arg, r, bk, OverloadedOperator);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -701,13 +704,13 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
}
|
||||
|
||||
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()),
|
||||
pat.repr(self.tcx()));
|
||||
let mc = &self.mc;
|
||||
@ -715,7 +718,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
let tcx = typer.tcx();
|
||||
let def_map = &self.typer.tcx().def_map;
|
||||
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) {
|
||||
let tcx = typer.tcx();
|
||||
|
||||
@ -765,7 +768,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
|
||||
// matched.
|
||||
|
||||
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,
|
||||
Err(()) => {
|
||||
tcx.sess.span_bug(slice_pat.span,
|
||||
|
@ -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) {
|
||||
if !attr::contains_name(item.attrs.as_slice(), "unsafe_destructor") {
|
||||
match item.node {
|
||||
ItemImpl(_, Some(ref trait_ref), self_type, _) => {
|
||||
check_impl_of_trait(cx, item, trait_ref, self_type);
|
||||
ItemImpl(_, Some(ref trait_ref), 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 {
|
||||
ExprUnary(UnBox, interior) => {
|
||||
let interior_type = ty::expr_ty(cx.tcx, interior);
|
||||
ExprUnary(UnBox, ref interior) => {
|
||||
let interior_type = ty::expr_ty(cx.tcx, &**interior);
|
||||
let _ = check_static(cx.tcx, interior_type, interior.span);
|
||||
}
|
||||
ExprCast(source, _) => {
|
||||
let source_ty = ty::expr_ty(cx.tcx, source);
|
||||
ExprCast(ref source, _) => {
|
||||
let source_ty = ty::expr_ty(cx.tcx, &**source);
|
||||
let target_ty = ty::expr_ty(cx.tcx, e);
|
||||
check_trait_cast(cx, source_ty, target_ty, source.span);
|
||||
}
|
||||
ExprRepeat(element, count_expr) => {
|
||||
let count = ty::eval_repeat_count(cx.tcx, count_expr);
|
||||
ExprRepeat(ref element, ref count_expr) => {
|
||||
let count = ty::eval_repeat_count(cx.tcx, &**count_expr);
|
||||
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,
|
||||
"repeated element will be copied");
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ use std::i32;
|
||||
use std::i64;
|
||||
use std::i8;
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
use std::to_str::ToStr;
|
||||
use std::u16;
|
||||
use std::u32;
|
||||
@ -652,7 +653,7 @@ impl<'a> Context<'a> {
|
||||
/// Return true if that's the case. Otherwise return false.
|
||||
pub fn each_lint(sess: &session::Session,
|
||||
attrs: &[ast::Attribute],
|
||||
f: |@ast::MetaItem, Level, InternedString| -> bool)
|
||||
f: |Gc<ast::MetaItem>, Level, InternedString| -> bool)
|
||||
-> bool {
|
||||
let xs = [Allow, Warn, Deny, Forbid];
|
||||
for &level in xs.iter() {
|
||||
@ -745,8 +746,8 @@ impl<'a> AstConv for Context<'a>{
|
||||
fn check_unused_casts(cx: &Context, e: &ast::Expr) {
|
||||
return match e.node {
|
||||
ast::ExprCast(expr, 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 {
|
||||
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 {
|
||||
cx.span_lint(UnnecessaryTypecast, ty.span,
|
||||
"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 {
|
||||
ty::ty_uint(_) => {
|
||||
cx.span_lint(UnsignedNegate, e.span,
|
||||
@ -781,7 +782,7 @@ fn check_type_limits(cx: &Context, e: &ast::Expr) {
|
||||
}
|
||||
},
|
||||
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,
|
||||
"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) {
|
||||
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 {
|
||||
ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
|
||||
for ni in nmod.items.iter() {
|
||||
match ni.node {
|
||||
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, decl),
|
||||
ast::ForeignItemStatic(t, _) => check_ty(cx, t)
|
||||
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, &*decl),
|
||||
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 {
|
||||
ast::ItemStruct(..) | ast::ItemEnum(..) => {
|
||||
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,
|
||||
_ => return
|
||||
};
|
||||
let t = ty::expr_ty(cx.tcx, expr);
|
||||
let t = ty::expr_ty(cx.tcx, &*expr);
|
||||
match ty::get(t).sty {
|
||||
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;
|
||||
match ty::get(t).sty {
|
||||
ty::ty_struct(did, _) |
|
||||
@ -1431,7 +1432,7 @@ fn check_unnecessary_parens_expr(cx: &Context, e: &ast::Expr) {
|
||||
ast::ExprAssignOp(_, _, value) => (value, "assigned value"),
|
||||
_ => 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) {
|
||||
@ -1445,7 +1446,7 @@ fn check_unnecessary_parens_stmt(cx: &Context, s: &ast::Stmt) {
|
||||
},
|
||||
_ => return
|
||||
};
|
||||
check_unnecessary_parens_core(cx, value, msg);
|
||||
check_unnecessary_parens_core(cx, &*value, msg);
|
||||
}
|
||||
|
||||
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
|
||||
// avoid false warnings in match arms with multiple patterns
|
||||
let mut mutables = HashMap::new();
|
||||
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 {
|
||||
ast::BindByValue(ast::MutMutable) => {
|
||||
if path.segments.len() != 1 {
|
||||
|
@ -110,9 +110,10 @@ use middle::pat_util;
|
||||
use middle::ty;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
use std::mem::transmute;
|
||||
use std::fmt;
|
||||
use std::gc::Gc;
|
||||
use std::io;
|
||||
use std::mem::transmute;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
use std::uint;
|
||||
@ -364,7 +365,7 @@ fn visit_fn(ir: &mut IrMaps,
|
||||
|
||||
for arg in decl.inputs.iter() {
|
||||
pat_util::pat_bindings(&ir.tcx.def_map,
|
||||
arg.pat,
|
||||
&*arg.pat,
|
||||
|_bm, arg_id, _x, path| {
|
||||
debug!("adding argument {}", arg_id);
|
||||
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) {
|
||||
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);
|
||||
let name = ast_util::path_to_ident(path);
|
||||
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) {
|
||||
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 {:?}",
|
||||
p_id, bm);
|
||||
let name = ast_util::path_to_ident(path);
|
||||
@ -588,22 +589,22 @@ impl<'a> Liveness<'a> {
|
||||
}
|
||||
|
||||
fn arm_pats_bindings(&mut self,
|
||||
pats: &[@Pat],
|
||||
pats: &[Gc<Pat>],
|
||||
f: |&mut Liveness<'a>, LiveNode, Variable, Span, NodeId|) {
|
||||
// only consider the first pattern; any later patterns must have
|
||||
// the same bindings, and we also consider the first pattern to be
|
||||
// the "authoritative" set of ids
|
||||
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 {
|
||||
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 {
|
||||
let mut succ = succ;
|
||||
self.arm_pats_bindings(pats, |this, ln, var, _sp, _id| {
|
||||
@ -858,19 +859,19 @@ impl<'a> Liveness<'a> {
|
||||
-> LiveNode {
|
||||
let succ = self.propagate_through_opt_expr(blk.expr, succ);
|
||||
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)
|
||||
-> LiveNode {
|
||||
match stmt.node {
|
||||
StmtDecl(decl, _) => {
|
||||
self.propagate_through_decl(decl, succ)
|
||||
StmtDecl(ref decl, _) => {
|
||||
self.propagate_through_decl(&**decl, succ)
|
||||
}
|
||||
|
||||
StmtExpr(expr, _) | StmtSemi(expr, _) => {
|
||||
self.propagate_through_expr(expr, succ)
|
||||
StmtExpr(ref expr, _) | StmtSemi(ref expr, _) => {
|
||||
self.propagate_through_expr(&**expr, succ)
|
||||
}
|
||||
|
||||
StmtMac(..) => {
|
||||
@ -883,7 +884,7 @@ impl<'a> Liveness<'a> {
|
||||
-> LiveNode {
|
||||
match decl.node {
|
||||
DeclLocal(ref local) => {
|
||||
self.propagate_through_local(*local, succ)
|
||||
self.propagate_through_local(&**local, succ)
|
||||
}
|
||||
DeclItem(_) => succ,
|
||||
}
|
||||
@ -909,19 +910,19 @@ impl<'a> Liveness<'a> {
|
||||
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 {
|
||||
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,
|
||||
opt_expr: Option<@Expr>,
|
||||
opt_expr: Option<Gc<Expr>>,
|
||||
succ: LiveNode)
|
||||
-> LiveNode {
|
||||
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)
|
||||
}
|
||||
|
||||
ExprField(e, _, _) => {
|
||||
self.propagate_through_expr(e, succ)
|
||||
ExprField(ref e, _, _) => {
|
||||
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));
|
||||
|
||||
/*
|
||||
@ -967,7 +968,7 @@ impl<'a> Liveness<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
ExprIf(cond, then, els) => {
|
||||
ExprIf(ref cond, ref then, ref els) => {
|
||||
//
|
||||
// (cond)
|
||||
// |
|
||||
@ -981,27 +982,27 @@ impl<'a> Liveness<'a> {
|
||||
// v v
|
||||
// ( succ )
|
||||
//
|
||||
let else_ln = self.propagate_through_opt_expr(els, succ);
|
||||
let then_ln = self.propagate_through_block(then, succ);
|
||||
let else_ln = self.propagate_through_opt_expr(els.clone(), succ);
|
||||
let then_ln = self.propagate_through_block(&**then, succ);
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
self.init_from_succ(ln, else_ln);
|
||||
self.merge_from_succ(ln, then_ln, false);
|
||||
self.propagate_through_expr(cond, ln)
|
||||
self.propagate_through_expr(&**cond, ln)
|
||||
}
|
||||
|
||||
ExprWhile(cond, blk) => {
|
||||
self.propagate_through_loop(expr, Some(cond), blk, succ)
|
||||
ExprWhile(ref cond, ref blk) => {
|
||||
self.propagate_through_loop(expr, Some(cond.clone()), &**blk, succ)
|
||||
}
|
||||
|
||||
ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
|
||||
|
||||
// Note that labels have been resolved, so we don't need to look
|
||||
// at the label ident
|
||||
ExprLoop(blk, _) => {
|
||||
self.propagate_through_loop(expr, None, blk, succ)
|
||||
ExprLoop(ref blk, _) => {
|
||||
self.propagate_through_loop(expr, None, &**blk, succ)
|
||||
}
|
||||
|
||||
ExprMatch(e, ref arms) => {
|
||||
ExprMatch(ref e, ref arms) => {
|
||||
//
|
||||
// (e)
|
||||
// |
|
||||
@ -1021,7 +1022,7 @@ impl<'a> Liveness<'a> {
|
||||
let mut first_merge = true;
|
||||
for arm in arms.iter() {
|
||||
let body_succ =
|
||||
self.propagate_through_expr(arm.body, succ);
|
||||
self.propagate_through_expr(&*arm.body, succ);
|
||||
let guard_succ =
|
||||
self.propagate_through_opt_expr(arm.guard, body_succ);
|
||||
let arm_succ =
|
||||
@ -1030,7 +1031,7 @@ impl<'a> Liveness<'a> {
|
||||
self.merge_from_succ(ln, arm_succ, first_merge);
|
||||
first_merge = false;
|
||||
};
|
||||
self.propagate_through_expr(e, ln)
|
||||
self.propagate_through_expr(&**e, ln)
|
||||
}
|
||||
|
||||
ExprRet(o_e) => {
|
||||
@ -1066,49 +1067,49 @@ impl<'a> Liveness<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
ExprAssign(l, r) => {
|
||||
ExprAssign(ref l, ref r) => {
|
||||
// see comment on lvalues in
|
||||
// propagate_through_lvalue_components()
|
||||
let succ = self.write_lvalue(l, succ, ACC_WRITE);
|
||||
let succ = self.propagate_through_lvalue_components(l, succ);
|
||||
self.propagate_through_expr(r, succ)
|
||||
let succ = self.write_lvalue(&**l, succ, ACC_WRITE);
|
||||
let succ = self.propagate_through_lvalue_components(&**l, succ);
|
||||
self.propagate_through_expr(&**r, succ)
|
||||
}
|
||||
|
||||
ExprAssignOp(_, l, r) => {
|
||||
ExprAssignOp(_, ref l, ref r) => {
|
||||
// see comment on lvalues in
|
||||
// propagate_through_lvalue_components()
|
||||
let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ);
|
||||
let succ = self.propagate_through_expr(r, succ);
|
||||
self.propagate_through_lvalue_components(l, succ)
|
||||
let succ = self.write_lvalue(&**l, succ, ACC_WRITE|ACC_READ);
|
||||
let succ = self.propagate_through_expr(&**r, succ);
|
||||
self.propagate_through_lvalue_components(&**l, succ)
|
||||
}
|
||||
|
||||
// Uninteresting cases: just propagate in rev exec order
|
||||
|
||||
ExprVstore(expr, _) => {
|
||||
self.propagate_through_expr(expr, succ)
|
||||
ExprVstore(ref expr, _) => {
|
||||
self.propagate_through_expr(&**expr, succ)
|
||||
}
|
||||
|
||||
ExprVec(ref exprs) => {
|
||||
self.propagate_through_exprs(exprs.as_slice(), succ)
|
||||
}
|
||||
|
||||
ExprRepeat(element, count) => {
|
||||
let succ = self.propagate_through_expr(count, succ);
|
||||
self.propagate_through_expr(element, succ)
|
||||
ExprRepeat(ref element, ref count) => {
|
||||
let succ = self.propagate_through_expr(&**count, succ);
|
||||
self.propagate_through_expr(&**element, succ)
|
||||
}
|
||||
|
||||
ExprStruct(_, ref fields, with_expr) => {
|
||||
let succ = self.propagate_through_opt_expr(with_expr, succ);
|
||||
ExprStruct(_, ref fields, ref with_expr) => {
|
||||
let succ = self.propagate_through_opt_expr(with_expr.clone(), succ);
|
||||
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
|
||||
// will fail, and hence the successors can be ignored
|
||||
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)
|
||||
};
|
||||
let succ = if is_bot {
|
||||
@ -1117,7 +1118,7 @@ impl<'a> Liveness<'a> {
|
||||
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) => {
|
||||
@ -1133,39 +1134,39 @@ impl<'a> Liveness<'a> {
|
||||
self.propagate_through_exprs(exprs.as_slice(), succ)
|
||||
}
|
||||
|
||||
ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
|
||||
let r_succ = self.propagate_through_expr(r, succ);
|
||||
ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
|
||||
let r_succ = self.propagate_through_expr(&**r, succ);
|
||||
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
self.init_from_succ(ln, succ);
|
||||
self.merge_from_succ(ln, r_succ, false);
|
||||
|
||||
self.propagate_through_expr(l, ln)
|
||||
self.propagate_through_expr(&**l, ln)
|
||||
}
|
||||
|
||||
ExprIndex(l, r) |
|
||||
ExprBinary(_, l, r) |
|
||||
ExprBox(l, r) => {
|
||||
self.propagate_through_exprs([l, r], succ)
|
||||
ExprIndex(ref l, ref r) |
|
||||
ExprBinary(_, ref l, ref r) |
|
||||
ExprBox(ref l, ref r) => {
|
||||
self.propagate_through_exprs([l.clone(), r.clone()], succ)
|
||||
}
|
||||
|
||||
ExprAddrOf(_, e) |
|
||||
ExprCast(e, _) |
|
||||
ExprUnary(_, e) |
|
||||
ExprParen(e) => {
|
||||
self.propagate_through_expr(e, succ)
|
||||
ExprAddrOf(_, ref e) |
|
||||
ExprCast(ref e, _) |
|
||||
ExprUnary(_, ref e) |
|
||||
ExprParen(ref e) => {
|
||||
self.propagate_through_expr(&**e, succ)
|
||||
}
|
||||
|
||||
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
|
||||
// propagate_through_lvalue_components()
|
||||
let succ = self.write_lvalue(expr, succ, ACC_WRITE);
|
||||
self.propagate_through_lvalue_components(expr, succ)
|
||||
let succ = self.write_lvalue(&**expr, succ, ACC_WRITE);
|
||||
self.propagate_through_lvalue_components(&**expr, succ)
|
||||
});
|
||||
// Inputs are executed first. Propagate last because of rev order
|
||||
ia.inputs.iter().rev().fold(succ, |succ, &(_, expr)| {
|
||||
self.propagate_through_expr(expr, succ)
|
||||
ia.inputs.iter().rev().fold(succ, |succ, &(_, ref expr)| {
|
||||
self.propagate_through_expr(&**expr, succ)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1173,8 +1174,8 @@ impl<'a> Liveness<'a> {
|
||||
succ
|
||||
}
|
||||
|
||||
ExprBlock(blk) => {
|
||||
self.propagate_through_block(blk, succ)
|
||||
ExprBlock(ref blk) => {
|
||||
self.propagate_through_block(&**blk, succ)
|
||||
}
|
||||
|
||||
ExprMac(..) => {
|
||||
@ -1238,7 +1239,7 @@ impl<'a> Liveness<'a> {
|
||||
|
||||
match expr.node {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -1276,7 +1277,7 @@ impl<'a> Liveness<'a> {
|
||||
|
||||
fn propagate_through_loop(&mut self,
|
||||
expr: &Expr,
|
||||
cond: Option<@Expr>,
|
||||
cond: Option<Gc<Expr>>,
|
||||
body: &Block,
|
||||
succ: LiveNode)
|
||||
-> LiveNode {
|
||||
@ -1353,10 +1354,10 @@ impl<'a> Liveness<'a> {
|
||||
fn check_local(this: &mut Liveness, local: &Local) {
|
||||
match local.init {
|
||||
Some(_) => {
|
||||
this.warn_about_unused_or_dead_vars_in_pat(local.pat);
|
||||
this.warn_about_unused_or_dead_vars_in_pat(&*local.pat);
|
||||
},
|
||||
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);
|
||||
})
|
||||
}
|
||||
@ -1374,28 +1375,28 @@ fn check_arm(this: &mut Liveness, arm: &Arm) {
|
||||
|
||||
fn check_expr(this: &mut Liveness, expr: &Expr) {
|
||||
match expr.node {
|
||||
ExprAssign(l, r) => {
|
||||
this.check_lvalue(l);
|
||||
this.visit_expr(r, ());
|
||||
ExprAssign(ref l, ref r) => {
|
||||
this.check_lvalue(&**l);
|
||||
this.visit_expr(&**r, ());
|
||||
|
||||
visit::walk_expr(this, expr, ());
|
||||
}
|
||||
|
||||
ExprAssignOp(_, l, _) => {
|
||||
this.check_lvalue(l);
|
||||
ExprAssignOp(_, ref l, _) => {
|
||||
this.check_lvalue(&**l);
|
||||
|
||||
visit::walk_expr(this, expr, ());
|
||||
}
|
||||
|
||||
ExprInlineAsm(ref ia) => {
|
||||
for &(_, input) in ia.inputs.iter() {
|
||||
this.visit_expr(input, ());
|
||||
for &(_, ref input) in ia.inputs.iter() {
|
||||
this.visit_expr(&**input, ());
|
||||
}
|
||||
|
||||
// Output operands must be lvalues
|
||||
for &(_, out) in ia.outputs.iter() {
|
||||
this.check_lvalue(out);
|
||||
this.visit_expr(out, ());
|
||||
for &(_, ref out) in ia.outputs.iter() {
|
||||
this.check_lvalue(&**out);
|
||||
this.visit_expr(&**out, ());
|
||||
}
|
||||
|
||||
visit::walk_expr(this, expr, ());
|
||||
@ -1448,8 +1449,8 @@ impl<'a> Liveness<'a> {
|
||||
let ends_with_stmt = match body.expr {
|
||||
None if body.stmts.len() > 0 =>
|
||||
match body.stmts.last().unwrap().node {
|
||||
StmtSemi(e, _) => {
|
||||
let t_stmt = ty::expr_ty(self.ir.tcx, e);
|
||||
StmtSemi(ref e, _) => {
|
||||
let t_stmt = ty::expr_ty(self.ir.tcx, &**e);
|
||||
ty::get(t_stmt).sty == ty::get(t_ret).sty
|
||||
},
|
||||
_ => false
|
||||
@ -1519,7 +1520,7 @@ impl<'a> Liveness<'a> {
|
||||
fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) {
|
||||
for arg in decl.inputs.iter() {
|
||||
pat_util::pat_bindings(&self.ir.tcx.def_map,
|
||||
arg.pat,
|
||||
&*arg.pat,
|
||||
|_bm, p_id, sp, path| {
|
||||
let var = self.variable(p_id, sp);
|
||||
// Ignore unused self.
|
||||
|
@ -440,22 +440,22 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
||||
|
||||
let expr_ty = if_ok!(self.expr_ty(expr));
|
||||
match expr.node {
|
||||
ast::ExprUnary(ast::UnDeref, e_base) => {
|
||||
let base_cmt = if_ok!(self.cat_expr(e_base));
|
||||
ast::ExprUnary(ast::UnDeref, ref e_base) => {
|
||||
let base_cmt = if_ok!(self.cat_expr(&**e_base));
|
||||
Ok(self.cat_deref(expr, base_cmt, 0))
|
||||
}
|
||||
|
||||
ast::ExprField(base, f_name, _) => {
|
||||
let base_cmt = if_ok!(self.cat_expr(base));
|
||||
ast::ExprField(ref base, f_name, _) => {
|
||||
let base_cmt = if_ok!(self.cat_expr(&**base));
|
||||
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) {
|
||||
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))
|
||||
}
|
||||
|
||||
@ -464,8 +464,8 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||
}
|
||||
|
||||
ast::ExprParen(e) => {
|
||||
self.cat_expr(e)
|
||||
ast::ExprParen(ref e) => {
|
||||
self.cat_expr(&**e)
|
||||
}
|
||||
|
||||
ast::ExprAddrOf(..) | ast::ExprCall(..) |
|
||||
@ -999,31 +999,32 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
||||
}
|
||||
};
|
||||
|
||||
for (i, &subpat) in subpats.iter().enumerate() {
|
||||
let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2)
|
||||
for (i, subpat) in subpats.iter().enumerate() {
|
||||
let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
|
||||
|
||||
let subcmt =
|
||||
self.cat_imm_interior(
|
||||
pat, downcast_cmt.clone(), subpat_ty,
|
||||
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::DefStruct(..)) => {
|
||||
for (i, &subpat) in subpats.iter().enumerate() {
|
||||
let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2)
|
||||
for (i, subpat) in subpats.iter().enumerate() {
|
||||
let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
|
||||
let cmt_field =
|
||||
self.cat_imm_interior(
|
||||
pat, cmt.clone(), subpat_ty,
|
||||
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(..)) => {
|
||||
for &subpat in subpats.iter() {
|
||||
if_ok!(self.cat_pattern(cmt.clone(), subpat, |x,y,z| op(x,y,z)));
|
||||
for subpat in subpats.iter() {
|
||||
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)) => {
|
||||
if_ok!(self.cat_pattern(cmt, subpat, op));
|
||||
ast::PatIdent(_, _, Some(ref subpat)) => {
|
||||
if_ok!(self.cat_pattern(cmt, &**subpat, op));
|
||||
}
|
||||
|
||||
ast::PatIdent(_, _, None) => {
|
||||
@ -1045,42 +1046,43 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
||||
ast::PatStruct(_, ref field_pats, _) => {
|
||||
// {f1: p1, ..., fN: pN}
|
||||
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);
|
||||
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) => {
|
||||
// (p1, ..., pN)
|
||||
for (i, &subpat) in subpats.iter().enumerate() {
|
||||
let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2)
|
||||
for (i, subpat) in subpats.iter().enumerate() {
|
||||
let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
|
||||
let subcmt =
|
||||
self.cat_imm_interior(
|
||||
pat, cmt.clone(), subpat_ty,
|
||||
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
|
||||
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) => {
|
||||
let elt_cmt = self.cat_index(pat, cmt, 0);
|
||||
for &before_pat in before.iter() {
|
||||
if_ok!(self.cat_pattern(elt_cmt.clone(), before_pat, |x,y,z| op(x,y,z)));
|
||||
for before_pat in before.iter() {
|
||||
if_ok!(self.cat_pattern(elt_cmt.clone(), &**before_pat,
|
||||
|x,y,z| op(x,y,z)));
|
||||
}
|
||||
for &slice_pat in slice.iter() {
|
||||
let slice_ty = if_ok!(self.pat_ty(slice_pat));
|
||||
for slice_pat in slice.iter() {
|
||||
let slice_ty = if_ok!(self.pat_ty(&**slice_pat));
|
||||
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() {
|
||||
if_ok!(self.cat_pattern(elt_cmt.clone(), after_pat, |x,y,z| op(x,y,z)));
|
||||
for after_pat in after.iter() {
|
||||
if_ok!(self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
//! outside their scopes. This pass will also generate a set of exported items
|
||||
//! which are available for use externally when compiled as a library.
|
||||
|
||||
use std::gc::Gc;
|
||||
use std::mem::replace;
|
||||
|
||||
use metadata::csearch;
|
||||
@ -797,8 +798,8 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
|
||||
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
|
||||
match expr.node {
|
||||
ast::ExprField(base, ident, _) => {
|
||||
match ty::get(ty::expr_ty_adjusted(self.tcx, base)).sty {
|
||||
ast::ExprField(ref base, ident, _) => {
|
||||
match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
|
||||
ty::ty_struct(id, _) => {
|
||||
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");
|
||||
}
|
||||
}
|
||||
let check_struct = |def: &@ast::StructDef| {
|
||||
let check_struct = |def: &Gc<ast::StructDef>| {
|
||||
for f in def.fields.iter() {
|
||||
match f.node.kind {
|
||||
ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
|
||||
@ -1281,7 +1282,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
|
||||
at_outer_type: true,
|
||||
outer_type_is_public_path: false,
|
||||
};
|
||||
visitor.visit_ty(self_, ());
|
||||
visitor.visit_ty(&*self_, ());
|
||||
self_contains_private = visitor.contains_private;
|
||||
self_is_public_path = visitor.outer_type_is_public_path;
|
||||
}
|
||||
@ -1318,7 +1319,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
|
||||
match *trait_ref {
|
||||
None => {
|
||||
for method in methods.iter() {
|
||||
visit::walk_method_helper(self, *method, ())
|
||||
visit::walk_method_helper(self, &**method, ())
|
||||
}
|
||||
}
|
||||
Some(ref tr) => {
|
||||
@ -1345,7 +1346,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
|
||||
if method.explicit_self.node == ast::SelfStatic &&
|
||||
self.exported_items.contains(&method.id) {
|
||||
found_pub_static = true;
|
||||
visit::walk_method_helper(self, *method, ());
|
||||
visit::walk_method_helper(self, &**method, ());
|
||||
}
|
||||
}
|
||||
if found_pub_static {
|
||||
|
@ -70,7 +70,7 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
|
||||
{
|
||||
match tcx.map.find(impl_src.node) {
|
||||
Some(ast_map::NodeItem(item)) => {
|
||||
item_might_be_inlined(item)
|
||||
item_might_be_inlined(&*item)
|
||||
}
|
||||
Some(..) | None => {
|
||||
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) {
|
||||
Some(ast_map::NodeItem(item)) => {
|
||||
match item.node {
|
||||
ast::ItemFn(..) => item_might_be_inlined(item),
|
||||
ast::ItemFn(..) => item_might_be_inlined(&*item),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -273,20 +273,20 @@ impl<'a> ReachableContext<'a> {
|
||||
match *node {
|
||||
ast_map::NodeItem(item) => {
|
||||
match item.node {
|
||||
ast::ItemFn(_, _, _, _, search_block) => {
|
||||
if item_might_be_inlined(item) {
|
||||
visit::walk_block(self, search_block, ())
|
||||
ast::ItemFn(_, _, _, _, ref search_block) => {
|
||||
if item_might_be_inlined(&*item) {
|
||||
visit::walk_block(self, &**search_block, ())
|
||||
}
|
||||
}
|
||||
|
||||
// Statics with insignificant addresses are not reachable
|
||||
// because they're inlined specially into all other crates.
|
||||
ast::ItemStatic(_, _, init) => {
|
||||
ast::ItemStatic(_, _, ref init) => {
|
||||
if attr::contains_name(item.attrs.as_slice(),
|
||||
"address_insignificant") {
|
||||
self.reachable_symbols.remove(&search_item);
|
||||
}
|
||||
visit::walk_expr(self, init, ());
|
||||
visit::walk_expr(self, &**init, ());
|
||||
}
|
||||
|
||||
// These are normal, nothing reachable about these
|
||||
@ -310,14 +310,14 @@ impl<'a> ReachableContext<'a> {
|
||||
// Keep going, nothing to get exported
|
||||
}
|
||||
ast::Provided(ref method) => {
|
||||
visit::walk_block(self, method.body, ())
|
||||
visit::walk_block(self, &*method.body, ())
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_map::NodeMethod(method) => {
|
||||
let did = self.tcx.map.get_parent_did(search_item);
|
||||
if method_might_be_inlined(self.tcx, method, did) {
|
||||
visit::walk_block(self, method.body, ())
|
||||
if method_might_be_inlined(self.tcx, &*method, did) {
|
||||
visit::walk_block(self, &*method.body, ())
|
||||
}
|
||||
}
|
||||
// Nothing to recurse on for these
|
||||
|
@ -28,6 +28,7 @@ use util::nodemap::NodeMap;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::gc::Gc;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::{ast, visit};
|
||||
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.
|
||||
|
||||
match local.init {
|
||||
Some(expr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, expr, blk_id);
|
||||
Some(ref expr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &**expr, blk_id);
|
||||
|
||||
if is_binding_pat(local.pat) || is_borrowed_ty(local.ty) {
|
||||
record_rvalue_scope(visitor, expr, blk_id);
|
||||
if is_binding_pat(&*local.pat) || is_borrowed_ty(&*local.ty) {
|
||||
record_rvalue_scope(visitor, &**expr, blk_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -657,22 +658,22 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
|
||||
ast::PatIdent(ast::BindByRef(_), _, _) => true,
|
||||
|
||||
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) => {
|
||||
pats1.iter().any(|&p| is_binding_pat(p)) ||
|
||||
pats2.iter().any(|&p| is_binding_pat(p)) ||
|
||||
pats3.iter().any(|&p| is_binding_pat(p))
|
||||
pats1.iter().any(|p| is_binding_pat(&**p)) ||
|
||||
pats2.iter().any(|p| is_binding_pat(&**p)) ||
|
||||
pats3.iter().any(|p| is_binding_pat(&**p))
|
||||
}
|
||||
|
||||
ast::PatEnum(_, Some(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) => {
|
||||
is_binding_pat(subpat)
|
||||
ast::PatBox(ref subpat) => {
|
||||
is_binding_pat(&**subpat)
|
||||
}
|
||||
|
||||
_ => false,
|
||||
@ -709,39 +710,39 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
|
||||
*/
|
||||
|
||||
match expr.node {
|
||||
ast::ExprAddrOf(_, subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
|
||||
record_rvalue_scope(visitor, subexpr, blk_id);
|
||||
ast::ExprAddrOf(_, ref subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
|
||||
record_rvalue_scope(visitor, &**subexpr, blk_id);
|
||||
}
|
||||
ast::ExprStruct(_, ref fields, _) => {
|
||||
for field in fields.iter() {
|
||||
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);
|
||||
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::ExprTup(ref subexprs) => {
|
||||
for &subexpr in subexprs.iter() {
|
||||
for subexpr in subexprs.iter() {
|
||||
record_rvalue_scope_if_borrow_expr(
|
||||
visitor, subexpr, blk_id);
|
||||
visitor, &**subexpr, blk_id);
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(ast::UnUniq, subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
|
||||
ast::ExprUnary(ast::UnUniq, ref subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
|
||||
}
|
||||
ast::ExprCast(subexpr, _) |
|
||||
ast::ExprParen(subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id)
|
||||
ast::ExprCast(ref subexpr, _) |
|
||||
ast::ExprParen(ref subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id)
|
||||
}
|
||||
ast::ExprBlock(ref block) => {
|
||||
match block.expr {
|
||||
Some(subexpr) => {
|
||||
Some(ref subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(
|
||||
visitor, subexpr, blk_id);
|
||||
visitor, &**subexpr, blk_id);
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
@ -789,7 +790,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
|
||||
ast::ExprField(ref subexpr, _, _) |
|
||||
ast::ExprIndex(ref subexpr, _) |
|
||||
ast::ExprParen(ref subexpr) => {
|
||||
let subexpr: &'a @Expr = subexpr; // FIXME(#11586)
|
||||
let subexpr: &'a Gc<Expr> = subexpr; // FIXME(#11586)
|
||||
expr = &**subexpr;
|
||||
}
|
||||
_ => {
|
||||
|
@ -34,9 +34,9 @@ use syntax::visit::Visitor;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::gc::Gc;
|
||||
use std::mem::replace;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::string::String;
|
||||
use std::uint;
|
||||
|
||||
// Definition mapping
|
||||
@ -1195,9 +1195,9 @@ impl<'a> Resolver<'a> {
|
||||
name_bindings.define_type
|
||||
(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(
|
||||
variant,
|
||||
&**variant,
|
||||
local_def(item.id),
|
||||
parent.clone(),
|
||||
is_public);
|
||||
@ -3430,7 +3430,7 @@ impl<'a> Resolver<'a> {
|
||||
FunctionRibKind(function_id, body_id) => {
|
||||
if !is_ty_param {
|
||||
def = DefUpvar(def.def_id().node,
|
||||
@def,
|
||||
box(GC) def,
|
||||
function_id,
|
||||
body_id);
|
||||
}
|
||||
@ -3565,7 +3565,7 @@ impl<'a> Resolver<'a> {
|
||||
// resolve the discriminator expr
|
||||
// as a constant
|
||||
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,
|
||||
ref implemented_traits,
|
||||
self_type,
|
||||
ref methods) => {
|
||||
ref implemented_traits,
|
||||
ref self_type,
|
||||
ref methods) => {
|
||||
self.resolve_implementation(item.id,
|
||||
generics,
|
||||
implemented_traits,
|
||||
self_type,
|
||||
&**self_type,
|
||||
methods.as_slice());
|
||||
}
|
||||
|
||||
@ -3647,16 +3647,16 @@ impl<'a> Resolver<'a> {
|
||||
&ty_m.generics.ty_params);
|
||||
|
||||
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,
|
||||
Provided(m.id)),
|
||||
m,
|
||||
&**m,
|
||||
generics.ty_params.len())
|
||||
}
|
||||
}
|
||||
@ -3690,12 +3690,12 @@ impl<'a> Resolver<'a> {
|
||||
generics, foreign_item.id, 0,
|
||||
ItemRibKind),
|
||||
|this| visit::walk_foreign_item(this,
|
||||
*foreign_item,
|
||||
&**foreign_item,
|
||||
()));
|
||||
}
|
||||
ForeignItemStatic(..) => {
|
||||
visit::walk_foreign_item(this,
|
||||
*foreign_item,
|
||||
&**foreign_item,
|
||||
());
|
||||
}
|
||||
}
|
||||
@ -3812,21 +3812,21 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
Some(declaration) => {
|
||||
for argument in declaration.inputs.iter() {
|
||||
this.resolve_pattern(argument.pat,
|
||||
this.resolve_pattern(&*argument.pat,
|
||||
ArgumentIrrefutableMode,
|
||||
None);
|
||||
|
||||
this.resolve_type(argument.ty);
|
||||
this.resolve_type(&*argument.ty);
|
||||
|
||||
debug!("(resolving function) recorded argument");
|
||||
}
|
||||
|
||||
this.resolve_type(declaration.output);
|
||||
this.resolve_type(&*declaration.output);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the function body.
|
||||
this.resolve_block(block);
|
||||
this.resolve_block(&*block);
|
||||
|
||||
debug!("(resolving function) leaving function");
|
||||
});
|
||||
@ -3842,7 +3842,7 @@ impl<'a> Resolver<'a> {
|
||||
self.resolve_type_parameter_bound(type_parameter.id, bound);
|
||||
}
|
||||
match type_parameter.default {
|
||||
Some(ty) => self.resolve_type(ty),
|
||||
Some(ref ty) => self.resolve_type(&**ty),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
@ -3857,10 +3857,10 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
UnboxedFnTyParamBound(ref unboxed_function) => {
|
||||
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(_) => {}
|
||||
}
|
||||
@ -3938,7 +3938,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// Resolve fields.
|
||||
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,
|
||||
opt_trait_reference: &Option<TraitRef>,
|
||||
self_type: &Ty,
|
||||
methods: &[@Method]) {
|
||||
methods: &[Gc<Method>]) {
|
||||
// If applicable, create a rib for the type parameters.
|
||||
let outer_type_parameter_count = generics.ty_params.len();
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics,
|
||||
@ -4015,7 +4015,7 @@ impl<'a> Resolver<'a> {
|
||||
for method in methods.iter() {
|
||||
// We also need a new scope for the method-specific type parameters.
|
||||
this.resolve_method(MethodRibKind(id, Provided(method.id)),
|
||||
*method,
|
||||
&**method,
|
||||
outer_type_parameter_count);
|
||||
}
|
||||
});
|
||||
@ -4032,20 +4032,20 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
fn resolve_local(&mut self, local: &Local) {
|
||||
// Resolve the type.
|
||||
self.resolve_type(local.ty);
|
||||
self.resolve_type(&*local.ty);
|
||||
|
||||
// Resolve the initializer, if necessary.
|
||||
match local.init {
|
||||
None => {
|
||||
// Nothing to do.
|
||||
}
|
||||
Some(initializer) => {
|
||||
self.resolve_expr(initializer);
|
||||
Some(ref initializer) => {
|
||||
self.resolve_expr(&**initializer);
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -4069,9 +4069,9 @@ impl<'a> Resolver<'a> {
|
||||
if arm.pats.len() == 0 {
|
||||
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() {
|
||||
let map_i = self.binding_mode_map(*p);
|
||||
let map_i = self.binding_mode_map(&**p);
|
||||
|
||||
for (&key, &binding_0) in map_0.iter() {
|
||||
match map_i.find(&key) {
|
||||
@ -4114,7 +4114,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
let mut bindings_list = HashMap::new();
|
||||
for pattern in arm.pats.iter() {
|
||||
self.resolve_pattern(*pattern,
|
||||
self.resolve_pattern(&**pattern,
|
||||
RefutableMode,
|
||||
Some(&mut bindings_list));
|
||||
}
|
||||
@ -4124,7 +4124,7 @@ impl<'a> Resolver<'a> {
|
||||
self.check_consistent_bindings(arm);
|
||||
|
||||
visit::walk_expr_opt(self, arm.guard, ());
|
||||
self.resolve_expr(arm.body);
|
||||
self.resolve_expr(&*arm.body);
|
||||
|
||||
self.value_ribs.borrow_mut().pop();
|
||||
}
|
||||
@ -4392,10 +4392,10 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
// Check the types in the path pattern.
|
||||
for &ty in path.segments
|
||||
for ty in path.segments
|
||||
.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.
|
||||
for &ty in path.segments
|
||||
for ty in path.segments
|
||||
.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.
|
||||
for &ty in path.segments
|
||||
for ty in path.segments
|
||||
.iter()
|
||||
.flat_map(|s| s.types.iter()) {
|
||||
self.resolve_type(ty);
|
||||
self.resolve_type(&**ty);
|
||||
}
|
||||
}
|
||||
|
||||
PatLit(expr) => {
|
||||
self.resolve_expr(expr);
|
||||
PatLit(ref expr) => {
|
||||
self.resolve_expr(&**expr);
|
||||
}
|
||||
|
||||
PatRange(first_expr, last_expr) => {
|
||||
self.resolve_expr(first_expr);
|
||||
self.resolve_expr(last_expr);
|
||||
PatRange(ref first_expr, ref last_expr) => {
|
||||
self.resolve_expr(&**first_expr);
|
||||
self.resolve_expr(&**last_expr);
|
||||
}
|
||||
|
||||
PatStruct(ref path, _, _) => {
|
||||
@ -4571,8 +4571,8 @@ impl<'a> Resolver<'a> {
|
||||
namespace: Namespace,
|
||||
check_ribs: bool) -> Option<(Def, LastPrivate)> {
|
||||
// First, resolve the types.
|
||||
for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
|
||||
self.resolve_type(ty);
|
||||
for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
|
||||
self.resolve_type(&**ty);
|
||||
}
|
||||
|
||||
if path.global {
|
||||
@ -4919,8 +4919,8 @@ impl<'a> Resolver<'a> {
|
||||
-> Option<(Path, NodeId, FallbackChecks)> {
|
||||
match t.node {
|
||||
TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
|
||||
TyPtr(mut_ty) => extract_path_and_node_id(mut_ty.ty, OnlyTraitAndStatics),
|
||||
TyRptr(_, mut_ty) => extract_path_and_node_id(mut_ty.ty, allow),
|
||||
TyPtr(mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
|
||||
TyRptr(_, mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
|
||||
// This doesn't handle the remaining `Ty` variants as they are not
|
||||
// that commonly the self_type, it might be interesting to provide
|
||||
// support for those in future.
|
||||
|
@ -226,6 +226,7 @@ use util::ppaux::{Repr, vec_map_to_str};
|
||||
use std::collections::HashMap;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
use syntax::ast;
|
||||
use syntax::ast::Ident;
|
||||
use syntax::ast_util::path_to_ident;
|
||||
@ -237,7 +238,7 @@ use syntax::parse::token::InternedString;
|
||||
// expression.
|
||||
enum Lit {
|
||||
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
|
||||
}
|
||||
|
||||
@ -252,11 +253,11 @@ pub enum VecLenOpt {
|
||||
enum Opt {
|
||||
lit(Lit),
|
||||
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))
|
||||
}
|
||||
|
||||
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 {
|
||||
ExprLit(existing_a_expr) => existing_a_expr,
|
||||
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)) => {
|
||||
let a_expr = lit_to_expr(tcx, &a);
|
||||
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,
|
||||
None => fail!("compare_list_exprs: type mismatch"),
|
||||
}
|
||||
}
|
||||
(&range(a1, a2), &range(b1, b2)) => {
|
||||
let m1 = const_eval::compare_lit_exprs(tcx, a1, b1);
|
||||
let m2 = const_eval::compare_lit_exprs(tcx, a2, b2);
|
||||
(&range(ref a1, ref a2), &range(ref b1, ref b2)) => {
|
||||
let m1 = const_eval::compare_lit_exprs(tcx, &**a1, &**b1);
|
||||
let m2 = const_eval::compare_lit_exprs(tcx, &**a2, &**b2);
|
||||
match (m1, m2) {
|
||||
(Some(val1), Some(val2)) => (val1 == 0 && val2 == 0),
|
||||
_ => 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 mut bcx = bcx;
|
||||
match *o {
|
||||
lit(ExprLit(lit_expr)) => {
|
||||
let lit_datum = unpack_datum!(bcx, expr::trans(bcx, lit_expr));
|
||||
lit(ExprLit(ref 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 = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
|
||||
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) => {
|
||||
return adt::trans_case(bcx, &**repr, disr_val);
|
||||
}
|
||||
range(l1, l2) => {
|
||||
let (l1, _) = consts::const_expr(ccx, l1, true);
|
||||
let (l2, _) = consts::const_expr(ccx, l2, true);
|
||||
range(ref l1, ref l2) => {
|
||||
let (l1, _) = consts::const_expr(ccx, &**l1, true);
|
||||
let (l2, _) = consts::const_expr(ccx, &**l2, true);
|
||||
return range_result(Result::new(bcx, l1), Result::new(bcx, l2));
|
||||
}
|
||||
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.
|
||||
*/
|
||||
struct Match<'a, 'b> {
|
||||
pats: Vec<@ast::Pat>,
|
||||
pats: Vec<Gc<ast::Pat>>,
|
||||
data: &'a ArmData<'a, 'b>,
|
||||
bound_ptrs: Vec<(Ident, ValueRef)>
|
||||
}
|
||||
@ -461,8 +462,8 @@ fn expand_nested_bindings<'a, 'b>(
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) {
|
||||
if !pat_is_binding_or_wild(&bcx.tcx().def_map, p) {
|
||||
fn assert_is_binding_or_wild(bcx: &Block, p: Gc<ast::Pat>) {
|
||||
if !pat_is_binding_or_wild(&bcx.tcx().def_map, &*p) {
|
||||
bcx.sess().span_bug(
|
||||
p.span,
|
||||
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>(
|
||||
bcx: &'b Block<'b>,
|
||||
@ -496,7 +497,7 @@ fn enter_match<'a, 'b>(
|
||||
let mut bound_ptrs = br.bound_ptrs.clone();
|
||||
match this.node {
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -531,7 +532,7 @@ fn enter_default<'a, 'b>(
|
||||
let matches = enter_match(bcx, dm, m, col, val, |p| {
|
||||
match p.node {
|
||||
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
|
||||
}
|
||||
});
|
||||
@ -600,12 +601,12 @@ fn enter_opt<'a, 'b>(
|
||||
let _indenter = indenter();
|
||||
|
||||
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;
|
||||
enter_match(bcx, &tcx.def_map, m, col, val, |p| {
|
||||
let answer = match p.node {
|
||||
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_id = const_def.def_id();
|
||||
if opt_eq(tcx, &lit(ConstLit(const_def_id)), opt) {
|
||||
@ -628,7 +629,7 @@ fn enter_opt<'a, 'b>(
|
||||
}
|
||||
}
|
||||
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) {
|
||||
Some(Vec::new())
|
||||
} else {
|
||||
@ -739,7 +740,7 @@ fn enter_rec_or_struct<'a, 'b>(
|
||||
bcx.val_to_str(val));
|
||||
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| {
|
||||
match p.node {
|
||||
ast::PatStruct(_, ref fpats, _) => {
|
||||
@ -775,7 +776,7 @@ fn enter_tup<'a, 'b>(
|
||||
bcx.val_to_str(val));
|
||||
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| {
|
||||
match p.node {
|
||||
ast::PatTup(ref elts) => {
|
||||
@ -808,7 +809,7 @@ fn enter_tuple_struct<'a, 'b>(
|
||||
bcx.val_to_str(val));
|
||||
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| {
|
||||
match p.node {
|
||||
ast::PatEnum(_, Some(ref elts)) => {
|
||||
@ -839,7 +840,7 @@ fn enter_uniq<'a, 'b>(
|
||||
bcx.val_to_str(val));
|
||||
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| {
|
||||
match p.node {
|
||||
ast::PatBox(sub) => {
|
||||
@ -867,7 +868,7 @@ fn enter_region<'a, 'b>(
|
||||
bcx.val_to_str(val));
|
||||
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| {
|
||||
match p.node {
|
||||
ast::PatRegion(sub) => {
|
||||
@ -1194,14 +1195,14 @@ fn pick_col(m: &[Match]) -> uint {
|
||||
fn score(p: &ast::Pat) -> uint {
|
||||
match p.node {
|
||||
ast::PatLit(_) | ast::PatEnum(_, _) | ast::PatRange(_, _) => 1u,
|
||||
ast::PatIdent(_, _, Some(p)) => score(p),
|
||||
ast::PatIdent(_, _, Some(ref p)) => score(&**p),
|
||||
_ => 0u
|
||||
}
|
||||
}
|
||||
let mut scores = Vec::from_elem(m[0].pats.len(), 0u);
|
||||
for br in m.iter() {
|
||||
for (i, p) in br.pats.iter().enumerate() {
|
||||
*scores.get_mut(i) += score(*p);
|
||||
for (i, ref p) in br.pats.iter().enumerate() {
|
||||
*scores.get_mut(i) += score(&***p);
|
||||
}
|
||||
}
|
||||
let mut max_score = 0u;
|
||||
@ -1454,9 +1455,9 @@ fn compile_submatch<'a, 'b>(
|
||||
Store(bcx, *value_ptr, llmatch);
|
||||
}
|
||||
match data.arm.guard {
|
||||
Some(guard_expr) => {
|
||||
Some(ref guard_expr) => {
|
||||
bcx = compile_guard(bcx,
|
||||
guard_expr,
|
||||
&**guard_expr,
|
||||
m[0].data,
|
||||
m.slice(1, m.len()),
|
||||
vals,
|
||||
@ -1841,7 +1842,7 @@ pub fn trans_match<'a>(
|
||||
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
|
||||
// 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
|
||||
@ -1849,7 +1850,7 @@ fn create_bindings_map(bcx: &Block, pat: @ast::Pat) -> BindingsMap {
|
||||
let ccx = bcx.ccx();
|
||||
let tcx = bcx.tcx();
|
||||
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 variable_ty = node_id_type(bcx, p_id);
|
||||
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();
|
||||
bcx = insert_lllocals(bcx, &arm_data.bindings_map,
|
||||
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);
|
||||
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
|
||||
// it assumes it is matching against a valid value.
|
||||
match simple_identifier(pat) {
|
||||
match simple_identifier(&*pat) {
|
||||
Some(path) => {
|
||||
let var_scope = cleanup::var_scope(tcx, local.id);
|
||||
return mk_binding_alloca(
|
||||
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)));
|
||||
}
|
||||
|
||||
@ -2021,8 +2022,8 @@ pub fn store_local<'a>(bcx: &'a Block<'a>,
|
||||
|
||||
// General path.
|
||||
let init_datum =
|
||||
unpack_datum!(bcx, expr::trans_to_lvalue(bcx, init_expr, "let"));
|
||||
if ty::type_is_bot(expr_ty(bcx, init_expr)) {
|
||||
unpack_datum!(bcx, expr::trans_to_lvalue(bcx, &*init_expr, "let"));
|
||||
if ty::type_is_bot(expr_ty(bcx, &*init_expr)) {
|
||||
create_dummy_locals(bcx, pat)
|
||||
} else {
|
||||
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>,
|
||||
pat: @ast::Pat)
|
||||
pat: Gc<ast::Pat>)
|
||||
-> &'a Block<'a> {
|
||||
// create dummy memory for the variables if we have no
|
||||
// value to store into them immediately
|
||||
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);
|
||||
bcx = mk_binding_alloca(
|
||||
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>,
|
||||
pat: @ast::Pat,
|
||||
pat: Gc<ast::Pat>,
|
||||
arg: Datum<Rvalue>,
|
||||
arg_scope: cleanup::ScopeId)
|
||||
-> &'a Block<'a> {
|
||||
@ -2073,7 +2074,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>,
|
||||
|
||||
let _icx = push_ctxt("match::store_arg");
|
||||
|
||||
match simple_identifier(pat) {
|
||||
match simple_identifier(&*pat) {
|
||||
Some(path) => {
|
||||
// Generate nicer LLVM for the common case of fn a pattern
|
||||
// like `x: T`
|
||||
@ -2137,7 +2138,7 @@ fn mk_binding_alloca<'a,A>(bcx: &'a Block<'a>,
|
||||
|
||||
fn bind_irrefutable_pat<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
pat: @ast::Pat,
|
||||
pat: Gc<ast::Pat>,
|
||||
val: ValueRef,
|
||||
binding_mode: IrrefutablePatternBindingMode,
|
||||
cleanup_scope: cleanup::ScopeId)
|
||||
@ -2176,7 +2177,7 @@ fn bind_irrefutable_pat<'a>(
|
||||
let ccx = bcx.ccx();
|
||||
match pat.node {
|
||||
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
|
||||
// binding will live and place it into the appropriate
|
||||
// map.
|
||||
|
@ -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();
|
||||
|
||||
// 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());
|
||||
|
||||
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));
|
||||
out_datum.val
|
||||
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
// 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());
|
||||
|
||||
let in_datum = unpack_datum!(bcx, expr::trans(bcx, input));
|
||||
let in_datum = unpack_datum!(bcx, expr::trans(bcx, &**input));
|
||||
unpack_result!(bcx, {
|
||||
callee::trans_arg_datum(bcx,
|
||||
expr_ty(bcx, input),
|
||||
expr_ty(bcx, &**input),
|
||||
in_datum,
|
||||
cleanup::CustomScope(temp_scope),
|
||||
callee::DontAutorefArg)
|
||||
|
@ -81,6 +81,7 @@ use std::c_str::ToCStr;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use std::{i8, i16, i32, i64};
|
||||
use std::gc::Gc;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
|
||||
use syntax::ast_util::{local_def, is_local};
|
||||
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) {
|
||||
// Handle let _ = e; just like e;
|
||||
match local.init {
|
||||
Some(init) => {
|
||||
return controlflow::trans_stmt_semi(bcx, init)
|
||||
Some(ref init) => {
|
||||
return controlflow::trans_stmt_semi(bcx, &**init)
|
||||
}
|
||||
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,
|
||||
sp: Span, id: ast::NodeId, vi: &[Rc<ty::VariantInfo>],
|
||||
i: &mut uint) {
|
||||
for &variant in enum_definition.variants.iter() {
|
||||
for variant in enum_definition.variants.iter() {
|
||||
let disr_val = vi[*i].disr_val;
|
||||
*i += 1;
|
||||
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref args) if args.len() > 0 => {
|
||||
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, ¶m_substs::empty(), llfn);
|
||||
}
|
||||
ast::TupleVariantKind(_) => {
|
||||
@ -1621,16 +1622,16 @@ impl<'a> Visitor<()> for TransItemVisitor<'a> {
|
||||
pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
||||
let _icx = push_ctxt("trans_item");
|
||||
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 {
|
||||
let llfndecl = get_item_val(ccx, item.id);
|
||||
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() {
|
||||
let llfn = get_item_val(ccx, item.id);
|
||||
trans_fn(ccx,
|
||||
decl,
|
||||
body,
|
||||
&**decl,
|
||||
&**body,
|
||||
llfn,
|
||||
¶m_substs::empty(),
|
||||
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
|
||||
// items in blocks and such.
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
v.visit_block(body, ());
|
||||
v.visit_block(&**body, ());
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
ast::ItemStatic(_, m, expr) => {
|
||||
ast::ItemStatic(_, m, ref expr) => {
|
||||
// Recurse on the expression to catch items in blocks
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
v.visit_expr(expr, ());
|
||||
v.visit_expr(&**expr, ());
|
||||
consts::trans_const(ccx, m, item.id);
|
||||
// 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
|
||||
@ -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.
|
||||
match struct_def.ctor_id {
|
||||
// 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) {
|
||||
let _icx = push_ctxt("trans_mod");
|
||||
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 v = match i.node {
|
||||
ast::ItemStatic(_, _, expr) => {
|
||||
ast::ItemStatic(_, _, ref expr) => {
|
||||
// If this static came from an external crate, then
|
||||
// we need to get the symbol from csearch instead of
|
||||
// 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
|
||||
// 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);
|
||||
let mut inlineable = inlineable;
|
||||
|
||||
@ -2118,13 +2119,13 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
||||
get_item_val()");
|
||||
}
|
||||
ast::Provided(m) => {
|
||||
register_method(ccx, id, m)
|
||||
register_method(ccx, id, &*m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast_map::NodeMethod(m) => {
|
||||
register_method(ccx, id, m)
|
||||
register_method(ccx, id, &*m)
|
||||
}
|
||||
|
||||
ast_map::NodeForeignItem(ni) => {
|
||||
@ -2134,13 +2135,13 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
||||
ast::ForeignItemFn(..) => {
|
||||
let abi = ccx.tcx.map.get_foreign_abi(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,
|
||||
name.get().as_slice(),
|
||||
Some(ni.span))
|
||||
}
|
||||
ast::ForeignItemStatic(..) => {
|
||||
foreign::register_static(ccx, ni)
|
||||
foreign::register_static(ccx, &*ni)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ use syntax::ast;
|
||||
use synabi = syntax::abi;
|
||||
use syntax::ast_map;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub struct MethodData {
|
||||
pub llfn: ValueRef,
|
||||
pub llself: ValueRef,
|
||||
@ -649,7 +651,7 @@ pub fn trans_call_inner<'a>(
|
||||
|
||||
let mut llargs = Vec::new();
|
||||
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.")
|
||||
};
|
||||
bcx = trans_args(bcx, args, callee_ty, &mut llargs,
|
||||
@ -683,7 +685,7 @@ pub fn trans_call_inner<'a>(
|
||||
pub enum CallArgs<'a> {
|
||||
// Supply value of arguments as a list of expressions that must be
|
||||
// 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
|
||||
// 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 {
|
||||
ArgExprs(arg_exprs) => {
|
||||
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 {
|
||||
continue;
|
||||
}
|
||||
let arg_ty = if i >= num_formal_args {
|
||||
assert!(variadic);
|
||||
expr_ty_adjusted(cx, arg_expr)
|
||||
expr_ty_adjusted(cx, &**arg_expr)
|
||||
} else {
|
||||
*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, {
|
||||
trans_arg_datum(bcx, arg_ty, arg_datum,
|
||||
arg_cleanup_scope,
|
||||
|
@ -34,8 +34,8 @@ use middle::ty;
|
||||
use util::ppaux::{Repr, ty_to_str};
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::gc::Gc;
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
use libc::c_uint;
|
||||
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,
|
||||
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 unit_ty = ty::sequence_element_type(cx.tcx(), vec_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.
|
||||
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
|
||||
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.
|
||||
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
is_local: bool) -> (ValueRef, bool) {
|
||||
let map_list = |exprs: &[@ast::Expr]| {
|
||||
exprs.iter().map(|&e| const_expr(cx, e, is_local))
|
||||
let map_list = |exprs: &[Gc<ast::Expr>]| {
|
||||
exprs.iter().map(|e| const_expr(cx, &**e, is_local))
|
||||
.fold((Vec::new(), true),
|
||||
|(l, all_inlineable), (val, inlineable)| {
|
||||
(l.append_one(val), all_inlineable && inlineable)
|
||||
@ -302,18 +302,18 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
unsafe {
|
||||
let _icx = push_ctxt("const_expr");
|
||||
return match e.node {
|
||||
ast::ExprLit(lit) => {
|
||||
(consts::const_lit(cx, e, (*lit).clone()), true)
|
||||
ast::ExprLit(ref lit) => {
|
||||
(consts::const_lit(cx, e, (**lit).clone()), true)
|
||||
}
|
||||
ast::ExprBinary(b, e1, e2) => {
|
||||
let (te1, _) = const_expr(cx, e1, is_local);
|
||||
let (te2, _) = const_expr(cx, e2, is_local);
|
||||
ast::ExprBinary(b, ref e1, ref e2) => {
|
||||
let (te1, _) = const_expr(cx, &**e1, is_local);
|
||||
let (te2, _) = const_expr(cx, &**e2, is_local);
|
||||
|
||||
let te2 = base::cast_shift_const_rhs(b, te1, te2);
|
||||
|
||||
/* Neither type is bottom, and we expect them to be unified
|
||||
* 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 signed = ty::type_is_signed(ty);
|
||||
return (match b {
|
||||
@ -387,9 +387,9 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
},
|
||||
}, true)
|
||||
},
|
||||
ast::ExprUnary(u, e) => {
|
||||
let (te, _) = const_expr(cx, e, is_local);
|
||||
let ty = ty::expr_ty(cx.tcx(), e);
|
||||
ast::ExprUnary(u, ref e) => {
|
||||
let (te, _) = const_expr(cx, &**e, is_local);
|
||||
let ty = ty::expr_ty(cx.tcx(), &**e);
|
||||
let is_float = ty::type_is_fp(ty);
|
||||
return (match u {
|
||||
ast::UnBox | ast::UnUniq | ast::UnDeref => {
|
||||
@ -414,20 +414,20 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
ast::ExprField(base, field, _) => {
|
||||
let bt = ty::expr_ty_adjusted(cx.tcx(), base);
|
||||
ast::ExprField(ref base, field, _) => {
|
||||
let bt = ty::expr_ty_adjusted(cx.tcx(), &**base);
|
||||
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| {
|
||||
let ix = ty::field_idx_strict(cx.tcx(), field.name, field_tys);
|
||||
(adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
|
||||
})
|
||||
}
|
||||
|
||||
ast::ExprIndex(base, index) => {
|
||||
let bt = ty::expr_ty_adjusted(cx.tcx(), base);
|
||||
let (bv, inlineable) = const_expr(cx, base, is_local);
|
||||
let iv = match const_eval::eval_const_expr(cx.tcx(), index) {
|
||||
ast::ExprIndex(ref base, ref index) => {
|
||||
let bt = ty::expr_ty_adjusted(cx.tcx(), &**base);
|
||||
let (bv, inlineable) = const_expr(cx, &**base, is_local);
|
||||
let iv = match const_eval::eval_const_expr(cx.tcx(), &**index) {
|
||||
const_eval::const_int(i) => i as u64,
|
||||
const_eval::const_uint(u) => u,
|
||||
_ => 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)
|
||||
}
|
||||
ast::ExprCast(base, _) => {
|
||||
ast::ExprCast(ref base, _) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
let llty = type_of::type_of(cx, ety);
|
||||
let basety = ty::expr_ty(cx.tcx(), base);
|
||||
let (v, inlineable) = const_expr(cx, base, is_local);
|
||||
let basety = ty::expr_ty(cx.tcx(), &**base);
|
||||
let (v, inlineable) = const_expr(cx, &**base, is_local);
|
||||
return (match (expr::cast_type_kind(basety),
|
||||
expr::cast_type_kind(ety)) {
|
||||
|
||||
@ -520,8 +520,8 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
}
|
||||
}, inlineable)
|
||||
}
|
||||
ast::ExprAddrOf(ast::MutImmutable, sub) => {
|
||||
let (e, _) = const_expr(cx, sub, is_local);
|
||||
ast::ExprAddrOf(ast::MutImmutable, ref sub) => {
|
||||
let (e, _) = const_expr(cx, &**sub, is_local);
|
||||
(const_addr_of(cx, e), false)
|
||||
}
|
||||
ast::ExprTup(ref es) => {
|
||||
@ -536,7 +536,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
let tcx = cx.tcx();
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
@ -544,7 +544,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
let (cs, inlineable) = vec::unzip(field_tys.iter().enumerate()
|
||||
.map(|(ix, &field_ty)| {
|
||||
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 => {
|
||||
match base_val {
|
||||
Some((bv, inlineable)) => {
|
||||
@ -567,12 +567,12 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
is_local);
|
||||
(v, inlineable)
|
||||
}
|
||||
ast::ExprVstore(sub, store @ ast::ExprVstoreSlice) |
|
||||
ast::ExprVstore(sub, store @ ast::ExprVstoreMutSlice) => {
|
||||
ast::ExprVstore(ref sub, store @ ast::ExprVstoreSlice) |
|
||||
ast::ExprVstore(ref sub, store @ ast::ExprVstoreMutSlice) => {
|
||||
match sub.node {
|
||||
ast::ExprLit(ref lit) => {
|
||||
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") }
|
||||
}
|
||||
}
|
||||
@ -595,16 +595,16 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::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 unit_ty = ty::sequence_element_type(cx.tcx(), vec_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_uint(i) => i as uint,
|
||||
_ => 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) {
|
||||
C_struct(cx, vs.as_slice(), false)
|
||||
} 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")
|
||||
}
|
||||
}
|
||||
ast::ExprParen(e) => { const_expr(cx, e, is_local) }
|
||||
ast::ExprParen(ref e) => { const_expr(cx, &**e, is_local) }
|
||||
ast::ExprBlock(ref block) => {
|
||||
match block.expr {
|
||||
Some(ref expr) => const_expr(cx, &**expr, is_local),
|
||||
|
@ -31,6 +31,8 @@ use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn trans_stmt<'a>(cx: &'a Block<'a>,
|
||||
s: &ast::Stmt)
|
||||
-> &'a Block<'a> {
|
||||
@ -48,18 +50,18 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>,
|
||||
fcx.push_ast_cleanup_scope(id);
|
||||
|
||||
match s.node {
|
||||
ast::StmtExpr(e, _) | ast::StmtSemi(e, _) => {
|
||||
bcx = trans_stmt_semi(bcx, e);
|
||||
ast::StmtExpr(ref e, _) | ast::StmtSemi(ref e, _) => {
|
||||
bcx = trans_stmt_semi(bcx, &**e);
|
||||
}
|
||||
ast::StmtDecl(d, _) => {
|
||||
match d.node {
|
||||
ast::DeclLocal(ref local) => {
|
||||
bcx = init_local(bcx, *local);
|
||||
bcx = init_local(bcx, &**local);
|
||||
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")
|
||||
@ -92,7 +94,7 @@ pub fn trans_block<'a>(bcx: &'a Block<'a>,
|
||||
fcx.push_ast_cleanup_scope(b.id);
|
||||
|
||||
for s in b.stmts.iter() {
|
||||
bcx = trans_stmt(bcx, *s);
|
||||
bcx = trans_stmt(bcx, &**s);
|
||||
}
|
||||
|
||||
if dest != expr::Ignore {
|
||||
@ -103,8 +105,8 @@ pub fn trans_block<'a>(bcx: &'a Block<'a>,
|
||||
}
|
||||
|
||||
match b.expr {
|
||||
Some(e) => {
|
||||
bcx = expr::trans_into(bcx, e, dest);
|
||||
Some(ref e) => {
|
||||
bcx = expr::trans_into(bcx, &**e, dest);
|
||||
}
|
||||
None => {
|
||||
assert!(dest == expr::Ignore || bcx.unreachable.get());
|
||||
@ -120,7 +122,7 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
|
||||
if_id: ast::NodeId,
|
||||
cond: &ast::Expr,
|
||||
thn: ast::P<ast::Block>,
|
||||
els: Option<@ast::Expr>,
|
||||
els: Option<Gc<ast::Expr>>,
|
||||
dest: expr::Dest)
|
||||
-> &'a Block<'a> {
|
||||
debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
|
||||
@ -137,21 +139,21 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
|
||||
match els {
|
||||
Some(elexpr) => {
|
||||
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
|
||||
trans.visit_expr(elexpr, ());
|
||||
trans.visit_expr(&*elexpr, ());
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
// if true { .. } [else { .. }]
|
||||
bcx = trans_block(bcx, thn, dest);
|
||||
bcx = trans_block(bcx, &*thn, dest);
|
||||
debuginfo::clear_source_location(bcx.fcx);
|
||||
} else {
|
||||
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
|
||||
trans.visit_block(thn, ());
|
||||
trans.visit_block(&*thn, ());
|
||||
|
||||
match els {
|
||||
// if false { .. } else { .. }
|
||||
Some(elexpr) => {
|
||||
bcx = expr::trans_into(bcx, elexpr, dest);
|
||||
bcx = expr::trans_into(bcx, &*elexpr, dest);
|
||||
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 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);
|
||||
|
||||
let next_bcx;
|
||||
match els {
|
||||
Some(elexpr) => {
|
||||
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,
|
||||
[then_bcx_out, else_bcx_out]);
|
||||
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>,
|
||||
e: Option<@ast::Expr>)
|
||||
e: Option<Gc<ast::Expr>>)
|
||||
-> &'a Block<'a> {
|
||||
let _icx = push_ctxt("trans_ret");
|
||||
let fcx = bcx.fcx;
|
||||
@ -330,7 +332,7 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
|
||||
};
|
||||
match e {
|
||||
Some(x) => {
|
||||
bcx = expr::trans_into(bcx, x, dest);
|
||||
bcx = expr::trans_into(bcx, &*x, dest);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -143,14 +143,14 @@ use middle::ty;
|
||||
use middle::pat_util;
|
||||
use util::ppaux;
|
||||
|
||||
use libc::{c_uint, c_ulonglong, c_longlong};
|
||||
use std::c_str::{CString, ToCStr};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use libc::{c_uint, c_ulonglong, c_longlong};
|
||||
use std::gc::Gc;
|
||||
use std::ptr;
|
||||
use std::string::String;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::atomics;
|
||||
use syntax::codemap::{Span, Pos};
|
||||
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 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 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 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) {
|
||||
Some(v) => v,
|
||||
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 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)
|
||||
};
|
||||
|
||||
@ -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<_>>();
|
||||
populate_scope_map(cx,
|
||||
arg_pats.as_slice(),
|
||||
top_level_block,
|
||||
&*top_level_block,
|
||||
fn_metadata,
|
||||
&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
|
||||
// shadowing.
|
||||
fn populate_scope_map(cx: &CrateContext,
|
||||
arg_pats: &[@ast::Pat],
|
||||
arg_pats: &[Gc<ast::Pat>],
|
||||
fn_entry_block: &ast::Block,
|
||||
fn_metadata: DISubprogram,
|
||||
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
|
||||
// shadowing.
|
||||
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);
|
||||
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.
|
||||
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);
|
||||
|
||||
match statement.node {
|
||||
ast::StmtDecl(decl, _) => walk_decl(cx, decl, scope_stack, scope_map),
|
||||
ast::StmtExpr(exp, _) |
|
||||
ast::StmtSemi(exp, _) => walk_expr(cx, exp, scope_stack, scope_map),
|
||||
ast::StmtDecl(ref decl, _) =>
|
||||
walk_decl(cx, &**decl, 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)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
pat: @ast::Pat,
|
||||
pat: Gc<ast::Pat>,
|
||||
scope_stack: &mut Vec<ScopeStackEntry> ,
|
||||
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
|
||||
// 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);
|
||||
|
||||
@ -2741,25 +2743,25 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
ast::PatTup(ref sub_pats) => {
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
for &sub_pat in sub_pats.iter() {
|
||||
walk_pattern(cx, sub_pat, scope_stack, scope_map);
|
||||
for sub_pat in sub_pats.iter() {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
walk_expr(cx, exp1, scope_stack, scope_map);
|
||||
walk_expr(cx, exp2, scope_stack, scope_map);
|
||||
walk_expr(cx, &**exp1, 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) => {
|
||||
@ -2798,72 +2800,74 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
ast::ExprAgain(_) |
|
||||
ast::ExprPath(_) => {}
|
||||
|
||||
ast::ExprVstore(sub_exp, _) |
|
||||
ast::ExprCast(sub_exp, _) |
|
||||
ast::ExprAddrOf(_, sub_exp) |
|
||||
ast::ExprField(sub_exp, _, _) |
|
||||
ast::ExprParen(sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
|
||||
ast::ExprVstore(ref sub_exp, _) |
|
||||
ast::ExprCast(ref sub_exp, _) |
|
||||
ast::ExprAddrOf(_, ref sub_exp) |
|
||||
ast::ExprField(ref sub_exp, _, _) |
|
||||
ast::ExprParen(ref sub_exp) =>
|
||||
walk_expr(cx, &**sub_exp, scope_stack, scope_map),
|
||||
|
||||
ast::ExprBox(place, sub_expr) => {
|
||||
walk_expr(cx, place, scope_stack, scope_map);
|
||||
walk_expr(cx, sub_expr, scope_stack, scope_map);
|
||||
ast::ExprBox(ref place, ref sub_expr) => {
|
||||
walk_expr(cx, &**place, scope_stack, scope_map);
|
||||
walk_expr(cx, &**sub_expr, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
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 => ()
|
||||
},
|
||||
|
||||
ast::ExprUnary(_, sub_exp) => {
|
||||
walk_expr(cx, sub_exp, scope_stack, scope_map);
|
||||
ast::ExprUnary(_, ref sub_exp) => {
|
||||
walk_expr(cx, &**sub_exp, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
ast::ExprAssignOp(_, lhs, rhs) |
|
||||
ast::ExprIndex(lhs, rhs) |
|
||||
ast::ExprBinary(_, lhs, rhs) => {
|
||||
walk_expr(cx, lhs, scope_stack, scope_map);
|
||||
walk_expr(cx, rhs, scope_stack, scope_map);
|
||||
ast::ExprAssignOp(_, ref lhs, ref rhs) |
|
||||
ast::ExprIndex(ref lhs, ref rhs) |
|
||||
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
||||
walk_expr(cx, &**lhs, scope_stack, scope_map);
|
||||
walk_expr(cx, &**rhs, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
ast::ExprVec(ref init_expressions) |
|
||||
ast::ExprTup(ref init_expressions) => {
|
||||
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::ExprRepeat(sub_exp1, sub_exp2) => {
|
||||
walk_expr(cx, sub_exp1, scope_stack, scope_map);
|
||||
walk_expr(cx, sub_exp2, scope_stack, scope_map);
|
||||
ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
|
||||
ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
|
||||
walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
|
||||
walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
ast::ExprIf(cond_exp, then_block, ref opt_else_exp) => {
|
||||
walk_expr(cx, cond_exp, scope_stack, scope_map);
|
||||
ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
|
||||
walk_expr(cx, &**cond_exp, scope_stack, scope_map);
|
||||
|
||||
with_new_scope(cx,
|
||||
then_block.span,
|
||||
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 {
|
||||
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) => {
|
||||
walk_expr(cx, cond_exp, scope_stack, scope_map);
|
||||
ast::ExprWhile(ref cond_exp, ref loop_body) => {
|
||||
walk_expr(cx, &**cond_exp, scope_stack, scope_map);
|
||||
|
||||
with_new_scope(cx,
|
||||
loop_body.span,
|
||||
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.");
|
||||
}
|
||||
|
||||
ast::ExprLoop(block, _) |
|
||||
ast::ExprBlock(block) => {
|
||||
ast::ExprLoop(ref block, _) |
|
||||
ast::ExprBlock(ref block) => {
|
||||
with_new_scope(cx,
|
||||
block.span,
|
||||
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::ExprProc(decl, block) => {
|
||||
ast::ExprFnBlock(ref decl, ref block) |
|
||||
ast::ExprProc(ref decl, ref block) => {
|
||||
with_new_scope(cx,
|
||||
block.span,
|
||||
scope_stack,
|
||||
scope_map,
|
||||
|cx, scope_stack, scope_map| {
|
||||
for &ast::Arg { pat: pattern, .. } in decl.inputs.iter() {
|
||||
walk_pattern(cx, pattern, scope_stack, scope_map);
|
||||
for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
|
||||
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) => {
|
||||
walk_expr(cx, fn_exp, scope_stack, scope_map);
|
||||
ast::ExprCall(ref fn_exp, ref args) => {
|
||||
walk_expr(cx, &**fn_exp, scope_stack, scope_map);
|
||||
|
||||
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) => {
|
||||
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) => {
|
||||
walk_expr(cx, discriminant_exp, scope_stack, scope_map);
|
||||
ast::ExprMatch(ref discriminant_exp, ref arms) => {
|
||||
walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
|
||||
|
||||
// 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
|
||||
@ -2937,21 +2941,21 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
}
|
||||
|
||||
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) => {
|
||||
for &ast::Field { expr: exp, .. } in fields.iter() {
|
||||
walk_expr(cx, exp, scope_stack, scope_map);
|
||||
for &ast::Field { expr: ref exp, .. } in fields.iter() {
|
||||
walk_expr(cx, &**exp, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
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 => ()
|
||||
}
|
||||
}
|
||||
@ -2959,13 +2963,13 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
|
||||
outputs: ref outputs,
|
||||
.. }) => {
|
||||
// inputs, outputs: ~[(String, @expr)]
|
||||
for &(_, exp) in inputs.iter() {
|
||||
walk_expr(cx, exp, scope_stack, scope_map);
|
||||
// inputs, outputs: ~[(String, Gc<expr>)]
|
||||
for &(_, ref exp) in inputs.iter() {
|
||||
walk_expr(cx, &**exp, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
for &(_, exp) in outputs.iter() {
|
||||
walk_expr(cx, exp, scope_stack, scope_map);
|
||||
for &(_, ref exp) in outputs.iter() {
|
||||
walk_expr(cx, &**exp, scope_stack, scope_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,8 @@ use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::print::pprust::{expr_to_str};
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
// Destinations
|
||||
|
||||
// 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");
|
||||
|
||||
match expr.node {
|
||||
ast::ExprParen(e) => {
|
||||
trans(bcx, e)
|
||||
ast::ExprParen(ref e) => {
|
||||
trans(bcx, &**e)
|
||||
}
|
||||
ast::ExprPath(_) => {
|
||||
trans_def(bcx, expr, bcx.def(expr.id))
|
||||
}
|
||||
ast::ExprField(base, ident, _) => {
|
||||
trans_rec_field(bcx, base, ident)
|
||||
ast::ExprField(ref base, ident, _) => {
|
||||
trans_rec_field(bcx, &**base, ident)
|
||||
}
|
||||
ast::ExprIndex(base, idx) => {
|
||||
trans_index(bcx, expr, base, idx)
|
||||
ast::ExprIndex(ref base, ref 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);
|
||||
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);
|
||||
DatumBlock::new(bcx, datum)
|
||||
}
|
||||
ast::ExprBox(_, contents) => {
|
||||
// Special case for `box T`. (The other case, for GC, is handled
|
||||
// in `trans_rvalue_dps_unadjusted`.)
|
||||
ast::ExprBox(_, ref contents) => {
|
||||
// Special case for `Box<T>` and `Gc<T>`
|
||||
let box_ty = expr_ty(bcx, expr);
|
||||
let contents_ty = expr_ty(bcx, contents);
|
||||
trans_uniq_expr(bcx, box_ty, contents, contents_ty)
|
||||
let contents_ty = expr_ty(bcx, &**contents);
|
||||
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::ExprBinary(op, lhs, rhs) => {
|
||||
trans_binary(bcx, expr, op, lhs, rhs)
|
||||
ast::ExprLit(ref lit) => trans_immediate_lit(bcx, expr, (**lit).clone()),
|
||||
ast::ExprBinary(op, ref lhs, ref rhs) => {
|
||||
trans_binary(bcx, expr, op, &**lhs, &**rhs)
|
||||
}
|
||||
ast::ExprUnary(op, x) => {
|
||||
trans_unary(bcx, expr, op, x)
|
||||
ast::ExprUnary(op, ref x) => {
|
||||
trans_unary(bcx, expr, op, &**x)
|
||||
}
|
||||
ast::ExprAddrOf(_, x) => {
|
||||
trans_addr_of(bcx, expr, x)
|
||||
ast::ExprAddrOf(_, ref x) => {
|
||||
trans_addr_of(bcx, expr, &**x)
|
||||
}
|
||||
ast::ExprCast(val, _) => {
|
||||
ast::ExprCast(ref val, _) => {
|
||||
// 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(
|
||||
@ -581,8 +591,8 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
}
|
||||
|
||||
match expr.node {
|
||||
ast::ExprParen(e) => {
|
||||
trans_into(bcx, e, Ignore)
|
||||
ast::ExprParen(ref e) => {
|
||||
trans_into(bcx, &**e, Ignore)
|
||||
}
|
||||
ast::ExprBreak(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) => {
|
||||
controlflow::trans_ret(bcx, ex)
|
||||
}
|
||||
ast::ExprWhile(cond, body) => {
|
||||
controlflow::trans_while(bcx, expr.id, cond, body)
|
||||
ast::ExprWhile(ref cond, ref body) => {
|
||||
controlflow::trans_while(bcx, expr.id, &**cond, &**body)
|
||||
}
|
||||
ast::ExprLoop(body, _) => {
|
||||
controlflow::trans_loop(bcx, expr.id, body)
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
controlflow::trans_loop(bcx, expr.id, &**body)
|
||||
}
|
||||
ast::ExprAssign(dst, src) => {
|
||||
let src_datum = unpack_datum!(bcx, trans(bcx, src));
|
||||
let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign"));
|
||||
ast::ExprAssign(ref dst, ref src) => {
|
||||
let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
|
||||
let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
|
||||
|
||||
if ty::type_needs_drop(bcx.tcx(), dst_datum.ty) {
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, dst, src) => {
|
||||
trans_assign_op(bcx, expr, op, dst, src)
|
||||
ast::ExprAssignOp(op, ref dst, ref src) => {
|
||||
trans_assign_op(bcx, expr, op, &**dst, src.clone())
|
||||
}
|
||||
ast::ExprInlineAsm(ref 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;
|
||||
|
||||
match expr.node {
|
||||
ast::ExprParen(e) => {
|
||||
trans_into(bcx, e, dest)
|
||||
ast::ExprParen(ref e) => {
|
||||
trans_into(bcx, &**e, dest)
|
||||
}
|
||||
ast::ExprPath(_) => {
|
||||
trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
|
||||
}
|
||||
ast::ExprIf(cond, thn, els) => {
|
||||
controlflow::trans_if(bcx, expr.id, cond, thn, els, dest)
|
||||
ast::ExprIf(ref cond, ref thn, els) => {
|
||||
controlflow::trans_if(bcx, expr.id, &**cond, thn.clone(), els, dest)
|
||||
}
|
||||
ast::ExprMatch(discr, ref arms) => {
|
||||
_match::trans_match(bcx, expr, discr, arms.as_slice(), dest)
|
||||
ast::ExprMatch(ref discr, ref arms) => {
|
||||
_match::trans_match(bcx, expr, &**discr, arms.as_slice(), dest)
|
||||
}
|
||||
ast::ExprBlock(blk) => {
|
||||
controlflow::trans_block(bcx, blk, dest)
|
||||
ast::ExprBlock(ref blk) => {
|
||||
controlflow::trans_block(bcx, &**blk, dest)
|
||||
}
|
||||
ast::ExprStruct(_, ref fields, base) => {
|
||||
trans_rec_or_struct(bcx,
|
||||
@ -679,7 +689,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
}
|
||||
ast::ExprTup(ref args) => {
|
||||
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();
|
||||
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(contents, ast::ExprVstoreMutSlice) => {
|
||||
ast::ExprVstore(ref contents, ast::ExprVstoreSlice) |
|
||||
ast::ExprVstore(ref contents, ast::ExprVstoreMutSlice) => {
|
||||
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)
|
||||
}
|
||||
ast::ExprVec(..) | ast::ExprRepeat(..) => {
|
||||
tvec::trans_fixed_vstore(bcx, expr, expr, dest)
|
||||
}
|
||||
ast::ExprFnBlock(decl, body) |
|
||||
ast::ExprProc(decl, body) => {
|
||||
ast::ExprFnBlock(ref decl, ref body) |
|
||||
ast::ExprProc(ref decl, ref body) => {
|
||||
let expr_ty = expr_ty(bcx, expr);
|
||||
let store = ty::ty_closure_store(expr_ty);
|
||||
debug!("translating block function {} with type {}",
|
||||
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) {
|
||||
let callee_datum = unpack_datum!(bcx, trans(bcx, f));
|
||||
let callee_datum = unpack_datum!(bcx, trans(bcx, &**f));
|
||||
trans_overloaded_call(bcx,
|
||||
expr,
|
||||
callee_datum,
|
||||
@ -725,7 +735,7 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
} else {
|
||||
callee::trans_call(bcx,
|
||||
expr,
|
||||
f,
|
||||
&**f,
|
||||
callee::ArgExprs(args.as_slice()),
|
||||
dest)
|
||||
}
|
||||
@ -733,35 +743,35 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
callee::trans_method_call(bcx,
|
||||
expr,
|
||||
*args.get(0),
|
||||
&**args.get(0),
|
||||
callee::ArgExprs(args.as_slice()),
|
||||
dest)
|
||||
}
|
||||
ast::ExprBinary(_, lhs, rhs) => {
|
||||
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
||||
// if not overloaded, would be RvalueDatumExpr
|
||||
let lhs = unpack_datum!(bcx, trans(bcx, lhs));
|
||||
let rhs_datum = unpack_datum!(bcx, trans(bcx, rhs));
|
||||
let lhs = unpack_datum!(bcx, trans(bcx, &**lhs));
|
||||
let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs));
|
||||
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs,
|
||||
Some((rhs_datum, rhs.id)), Some(dest)).bcx
|
||||
}
|
||||
ast::ExprUnary(_, subexpr) => {
|
||||
ast::ExprUnary(_, ref subexpr) => {
|
||||
// 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),
|
||||
arg, None, Some(dest)).bcx
|
||||
}
|
||||
ast::ExprIndex(base, idx) => {
|
||||
ast::ExprIndex(ref base, ref idx) => {
|
||||
// if not overloaded, would be RvalueDatumExpr
|
||||
let base = unpack_datum!(bcx, trans(bcx, base));
|
||||
let idx_datum = unpack_datum!(bcx, trans(bcx, idx));
|
||||
let base = unpack_datum!(bcx, trans(bcx, &**base));
|
||||
let idx_datum = unpack_datum!(bcx, trans(bcx, &**idx));
|
||||
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base,
|
||||
Some((idx_datum, idx.id)), Some(dest)).bcx
|
||||
}
|
||||
ast::ExprCast(val, _) => {
|
||||
ast::ExprCast(ref val, _) => {
|
||||
// DPS output mode means this is a trait cast:
|
||||
match ty::get(node_id_type(bcx, expr.id)).sty {
|
||||
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)
|
||||
}
|
||||
_ => {
|
||||
@ -770,13 +780,8 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, dst, src) => {
|
||||
trans_assign_op(bcx, expr, op, dst, src)
|
||||
}
|
||||
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)
|
||||
ast::ExprAssignOp(op, ref dst, ref src) => {
|
||||
trans_assign_op(bcx, expr, op, &**dst, src.clone())
|
||||
}
|
||||
_ => {
|
||||
bcx.tcx().sess.span_bug(
|
||||
@ -975,7 +980,7 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
|
||||
fn trans_rec_or_struct<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
fields: &[ast::Field],
|
||||
base: Option<@ast::Expr>,
|
||||
base: Option<Gc<ast::Expr>>,
|
||||
expr_span: codemap::Span,
|
||||
id: ast::NodeId,
|
||||
dest: Dest)
|
||||
@ -1037,7 +1042,7 @@ fn trans_rec_or_struct<'a>(
|
||||
*/
|
||||
struct StructBaseInfo {
|
||||
/// 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.
|
||||
fields: Vec<(uint, ty::t)> }
|
||||
|
||||
@ -1055,7 +1060,7 @@ fn trans_adt<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
repr: &adt::Repr,
|
||||
discr: ty::Disr,
|
||||
fields: &[(uint, @ast::Expr)],
|
||||
fields: &[(uint, Gc<ast::Expr>)],
|
||||
optbase: Option<StructBaseInfo>,
|
||||
dest: Dest)
|
||||
-> &'a Block<'a> {
|
||||
@ -1064,12 +1069,12 @@ fn trans_adt<'a>(
|
||||
let mut bcx = bcx;
|
||||
let addr = match dest {
|
||||
Ignore => {
|
||||
for &(_i, e) in fields.iter() {
|
||||
bcx = trans_into(bcx, e, Ignore);
|
||||
for &(_i, ref e) in fields.iter() {
|
||||
bcx = trans_into(bcx, &**e, Ignore);
|
||||
}
|
||||
for sbi in optbase.iter() {
|
||||
// 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;
|
||||
}
|
||||
@ -1082,10 +1087,10 @@ fn trans_adt<'a>(
|
||||
|
||||
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 e_ty = expr_ty_adjusted(bcx, e);
|
||||
bcx = trans_into(bcx, e, SaveIn(dest));
|
||||
let e_ty = expr_ty_adjusted(bcx, &**e);
|
||||
bcx = trans_into(bcx, &**e, SaveIn(dest));
|
||||
fcx.schedule_drop_mem(cleanup::CustomScope(custom_cleanup_scope),
|
||||
dest, e_ty);
|
||||
}
|
||||
@ -1093,7 +1098,7 @@ fn trans_adt<'a>(
|
||||
for base in optbase.iter() {
|
||||
// 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?
|
||||
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() {
|
||||
let datum = base_datum.get_element(
|
||||
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();
|
||||
}
|
||||
|
||||
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 _|_
|
||||
// and the other not.
|
||||
fn trans_eager_binop<'a>(
|
||||
@ -1480,16 +1460,16 @@ fn trans_overloaded_call<'a>(
|
||||
mut bcx: &'a Block<'a>,
|
||||
expr: &ast::Expr,
|
||||
callee: Datum<Expr>,
|
||||
args: &[@ast::Expr],
|
||||
args: &[Gc<ast::Expr>],
|
||||
dest: Option<Dest>)
|
||||
-> &'a Block<'a> {
|
||||
// Evaluate and tuple the arguments.
|
||||
let tuple_type = ty::mk_tup(bcx.tcx(),
|
||||
args.iter()
|
||||
.map(|e| expr_ty(bcx, *e))
|
||||
.map(|e| expr_ty(bcx, &**e))
|
||||
.collect());
|
||||
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();
|
||||
let argument_scope = bcx.fcx.push_custom_cleanup_scope();
|
||||
let tuple_datum =
|
||||
@ -1701,7 +1681,7 @@ fn trans_assign_op<'a>(
|
||||
expr: &ast::Expr,
|
||||
op: ast::BinOp,
|
||||
dst: &ast::Expr,
|
||||
src: @ast::Expr)
|
||||
src: Gc<ast::Expr>)
|
||||
-> &'a Block<'a> {
|
||||
let _icx = push_ctxt("trans_assign_op");
|
||||
let mut bcx = bcx;
|
||||
@ -1718,7 +1698,7 @@ fn trans_assign_op<'a>(
|
||||
let dst = Load(bcx, dst_datum.val);
|
||||
|
||||
// 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 = rhs_datum.to_llscalarish(bcx);
|
||||
|
||||
|
@ -443,8 +443,8 @@ pub fn trans_native_call<'a>(
|
||||
|
||||
pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
|
||||
let _icx = push_ctxt("foreign::trans_foreign_mod");
|
||||
for &foreign_item in foreign_mod.items.iter() {
|
||||
let lname = link_name(foreign_item);
|
||||
for foreign_item in foreign_mod.items.iter() {
|
||||
let lname = link_name(&**foreign_item);
|
||||
|
||||
match foreign_item.node {
|
||||
ast::ForeignItemFn(..) => {
|
||||
|
@ -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.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
|
||||
// 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 \
|
||||
non-enum, non-struct parent")
|
||||
}
|
||||
trans_item(ccx, item);
|
||||
trans_item(ccx, &*item);
|
||||
local_def(my_id)
|
||||
}
|
||||
csearch::found_parent(_, _) => {
|
||||
@ -131,7 +131,7 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
|
||||
if num_type_params == 0 {
|
||||
let llfn = get_item_val(ccx, mth.id);
|
||||
trans_fn(ccx, mth.decl, mth.body, llfn,
|
||||
trans_fn(ccx, &*mth.decl, &*mth.body, llfn,
|
||||
¶m_substs::empty(), mth.id, []);
|
||||
}
|
||||
local_def(mth.id)
|
||||
|
@ -35,6 +35,7 @@ use util::common::indenter;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::gc::Gc;
|
||||
use syntax::abi::Rust;
|
||||
use syntax::parse::token;
|
||||
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,
|
||||
name: ast::Ident,
|
||||
methods: &[@ast::Method],
|
||||
methods: &[Gc<ast::Method>],
|
||||
generics: &ast::Generics,
|
||||
id: ast::NodeId) {
|
||||
let _icx = push_ctxt("meth::trans_impl");
|
||||
@ -60,18 +61,18 @@ pub fn trans_impl(ccx: &CrateContext,
|
||||
if !generics.ty_params.is_empty() {
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
for method in methods.iter() {
|
||||
visit::walk_method_helper(&mut v, *method, ());
|
||||
visit::walk_method_helper(&mut v, &**method, ());
|
||||
}
|
||||
return;
|
||||
}
|
||||
for method in methods.iter() {
|
||||
if method.generics.ty_params.len() == 0u {
|
||||
let llfn = get_item_val(ccx, method.id);
|
||||
trans_fn(ccx, method.decl, method.body,
|
||||
trans_fn(ccx, &*method.decl, &*method.body,
|
||||
llfn, ¶m_substs::empty(), method.id, []);
|
||||
} else {
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
visit::walk_method_helper(&mut v, *method, ());
|
||||
visit::walk_method_helper(&mut v, &**method, ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,12 +201,12 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast_map::NodeItem(i) => {
|
||||
match *i {
|
||||
ast::Item {
|
||||
node: ast::ItemFn(decl, _, _, _, body),
|
||||
node: ast::ItemFn(ref decl, _, _, _, ref body),
|
||||
..
|
||||
} => {
|
||||
let d = mk_lldecl();
|
||||
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
|
||||
}
|
||||
_ => {
|
||||
@ -215,12 +215,12 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
}
|
||||
}
|
||||
ast_map::NodeForeignItem(i) => {
|
||||
let simple = intrinsic::get_simple_intrinsic(ccx, i);
|
||||
let simple = intrinsic::get_simple_intrinsic(ccx, &*i);
|
||||
match simple {
|
||||
Some(decl) => decl,
|
||||
None => {
|
||||
let d = mk_lldecl();
|
||||
intrinsic::trans_intrinsic(ccx, d, i, &psubsts, ref_id);
|
||||
intrinsic::trans_intrinsic(ccx, d, &*i, &psubsts, ref_id);
|
||||
d
|
||||
}
|
||||
}
|
||||
@ -235,7 +235,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
trans_enum_variant(ccx,
|
||||
parent,
|
||||
v,
|
||||
&*v,
|
||||
args.as_slice(),
|
||||
this_tv.disr_val,
|
||||
&psubsts,
|
||||
@ -249,7 +249,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast_map::NodeMethod(mth) => {
|
||||
let d = mk_lldecl();
|
||||
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
|
||||
}
|
||||
ast_map::NodeTraitMethod(method) => {
|
||||
@ -257,7 +257,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast::Provided(mth) => {
|
||||
let d = mk_lldecl();
|
||||
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
|
||||
}
|
||||
_ => {
|
||||
|
@ -351,7 +351,7 @@ pub fn write_content<'a>(
|
||||
match dest {
|
||||
Ignore => {
|
||||
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]);
|
||||
debug!("writing index {:?} with lleltptr={:?}",
|
||||
i, bcx.val_to_str(lleltptr));
|
||||
bcx = expr::trans_into(bcx, *element,
|
||||
bcx = expr::trans_into(bcx, &**element,
|
||||
SaveIn(lleltptr));
|
||||
fcx.schedule_drop_mem(
|
||||
cleanup::CustomScope(temp_scope),
|
||||
@ -373,13 +373,13 @@ pub fn write_content<'a>(
|
||||
}
|
||||
return bcx;
|
||||
}
|
||||
ast::ExprRepeat(element, count_expr) => {
|
||||
ast::ExprRepeat(ref element, ref count_expr) => {
|
||||
match dest {
|
||||
Ignore => {
|
||||
return expr::trans_into(bcx, element, Ignore);
|
||||
return expr::trans_into(bcx, &**element, Ignore);
|
||||
}
|
||||
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 {
|
||||
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
|
||||
// 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));
|
||||
|
||||
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::ExprRepeat(_, count_expr) => {
|
||||
ty::eval_repeat_count(bcx.tcx(), count_expr)
|
||||
ast::ExprRepeat(_, ref count_expr) => {
|
||||
ty::eval_repeat_count(bcx.tcx(), &**count_expr)
|
||||
}
|
||||
_ => bcx.tcx().sess.span_bug(content_expr.span,
|
||||
"unexpected vec content")
|
||||
|
@ -18,7 +18,7 @@ use middle::lint;
|
||||
use middle::const_eval;
|
||||
use middle::def;
|
||||
use middle::dependency_format;
|
||||
use middle::lang_items::{ExchangeHeapLangItem, OpaqueStructLangItem};
|
||||
use middle::lang_items::OpaqueStructLangItem;
|
||||
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
|
||||
use middle::freevars;
|
||||
use middle::resolve;
|
||||
@ -42,6 +42,7 @@ use std::cmp;
|
||||
use std::fmt::Show;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, sip, Writer};
|
||||
use std::gc::Gc;
|
||||
use std::iter::AdditiveIterator;
|
||||
use std::mem;
|
||||
use std::ops;
|
||||
@ -348,8 +349,8 @@ pub struct ctxt {
|
||||
|
||||
/// These two caches are used by const_eval when decoding external statics
|
||||
/// and variants that are found.
|
||||
pub extern_const_statics: RefCell<DefIdMap<Option<@ast::Expr>>>,
|
||||
pub extern_const_variants: RefCell<DefIdMap<Option<@ast::Expr>>>,
|
||||
pub extern_const_statics: RefCell<DefIdMap<Option<Gc<ast::Expr>>>>,
|
||||
pub extern_const_variants: RefCell<DefIdMap<Option<Gc<ast::Expr>>>>,
|
||||
|
||||
pub method_map: typeck::MethodMap,
|
||||
pub vtable_map: typeck::vtable_map,
|
||||
@ -3108,21 +3109,21 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
||||
}
|
||||
|
||||
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) {
|
||||
Some(&def) => def,
|
||||
None => fail!("no def for place"),
|
||||
};
|
||||
let def_id = definition.def_id();
|
||||
match tcx.lang_items.items.get(ExchangeHeapLangItem as uint) {
|
||||
&Some(item_def_id) if def_id == item_def_id => {
|
||||
RvalueDatumExpr
|
||||
}
|
||||
&Some(_) | &None => RvalueDpsExpr,
|
||||
if tcx.lang_items.exchange_heap() == Some(def_id) ||
|
||||
tcx.lang_items.managed_heap() == Some(def_id) {
|
||||
RvalueDatumExpr
|
||||
} else {
|
||||
RvalueDpsExpr
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprParen(e) => expr_kind(tcx, e),
|
||||
ast::ExprParen(ref e) => expr_kind(tcx, &**e),
|
||||
|
||||
ast::ExprMac(..) => {
|
||||
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_box(_) => "@-ptr".to_string(),
|
||||
ty_box(_) => "Gc-ptr".to_string(),
|
||||
ty_uniq(_) => "box".to_string(),
|
||||
ty_vec(_, _) => "vector".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 {
|
||||
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)) => {
|
||||
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);
|
||||
Rc::new(VariantInfo::from_ast_variant(cx, variant,
|
||||
Rc::new(VariantInfo::from_ast_variant(cx, &*variant,
|
||||
discriminant))
|
||||
}).collect())
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
let mut substs = subst::Substs {
|
||||
@ -451,6 +451,53 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
|
||||
supplied to `Box<T>`");
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -485,12 +532,12 @@ pub fn trait_ref_for_unboxed_function<AC:AstConv,
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|input| {
|
||||
ast_ty_to_ty(this, rscope, input.ty)
|
||||
ast_ty_to_ty(this, rscope, &*input.ty)
|
||||
}).collect::<Vec<_>>();
|
||||
let input_tuple = ty::mk_tup(this.tcx(), input_types);
|
||||
let output_type = ast_ty_to_ty(this,
|
||||
rscope,
|
||||
unboxed_function.decl.output);
|
||||
&*unboxed_function.decl.output);
|
||||
let substs = subst::Substs {
|
||||
self_ty: None,
|
||||
tps: vec!(input_tuple, output_type),
|
||||
@ -517,8 +564,8 @@ fn mk_pointer<AC:AstConv,
|
||||
debug!("mk_pointer(ptr_ty={:?})", ptr_ty);
|
||||
|
||||
match a_seq_ty.ty.node {
|
||||
ast::TyVec(ty) => {
|
||||
let mut mt = ast_ty_to_mt(this, rscope, ty);
|
||||
ast::TyVec(ref ty) => {
|
||||
let mut mt = ast_ty_to_mt(this, rscope, &**ty);
|
||||
if a_seq_ty.mutbl == ast::MutMutable {
|
||||
mt.mutbl = ast::MutMutable;
|
||||
}
|
||||
@ -543,7 +590,7 @@ fn mk_pointer<AC:AstConv,
|
||||
substs
|
||||
} = trait_ref_for_unboxed_function(this,
|
||||
rscope,
|
||||
*unboxed_function);
|
||||
&**unboxed_function);
|
||||
return ty::mk_trait(this.tcx(),
|
||||
def_id,
|
||||
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
|
||||
@ -643,12 +690,12 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
ast::TyVec(ty) => {
|
||||
tcx.sess.span_err(ast_ty.span, "bare `[]` is not a type");
|
||||
// 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)
|
||||
}
|
||||
ast::TyPtr(ref 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
|
||||
})
|
||||
}
|
||||
@ -660,7 +707,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
}
|
||||
ast::TyTup(ref fields) => {
|
||||
let flds = fields.iter()
|
||||
.map(|&t| ast_ty_to_ty(this, rscope, t))
|
||||
.map(|t| ast_ty_to_ty(this, rscope, &**t))
|
||||
.collect();
|
||||
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");
|
||||
}
|
||||
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) => {
|
||||
|
||||
@ -694,7 +741,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
f.onceness,
|
||||
bounds,
|
||||
store,
|
||||
f.decl,
|
||||
&*f.decl,
|
||||
None);
|
||||
ty::mk_closure(tcx, fn_decl)
|
||||
}
|
||||
@ -712,7 +759,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
f.onceness,
|
||||
bounds,
|
||||
ty::UniqTraitStore,
|
||||
f.decl,
|
||||
&*f.decl,
|
||||
None);
|
||||
ty::mk_closure(tcx, fn_decl)
|
||||
}
|
||||
@ -783,14 +830,14 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
}
|
||||
}
|
||||
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) => {
|
||||
match *r {
|
||||
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)),
|
||||
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)),
|
||||
_ => {
|
||||
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 {
|
||||
ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
|
||||
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 {
|
||||
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 {
|
||||
@ -949,7 +996,7 @@ pub fn ty_of_closure<AC:AstConv>(
|
||||
let output_ty = match decl.output.node {
|
||||
ast::TyInfer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(),
|
||||
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 {
|
||||
|
@ -23,6 +23,7 @@ use middle::typeck::infer;
|
||||
use middle::typeck::require_same_types;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::gc::Gc;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::parse::token;
|
||||
@ -43,10 +44,10 @@ pub fn check_match(fcx: &FnCtxt,
|
||||
for arm in arms.iter() {
|
||||
let mut pcx = pat_ctxt {
|
||||
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
|
||||
@ -64,9 +65,9 @@ pub fn check_match(fcx: &FnCtxt,
|
||||
let mut guard_err = false;
|
||||
let mut guard_bot = false;
|
||||
match arm.guard {
|
||||
Some(e) => {
|
||||
check_expr_has_type(fcx, e, ty::mk_bool());
|
||||
let e_ty = fcx.expr_ty(e);
|
||||
Some(ref e) => {
|
||||
check_expr_has_type(fcx, &**e, ty::mk_bool());
|
||||
let e_ty = fcx.expr_ty(&**e);
|
||||
if ty::type_is_error(e_ty) {
|
||||
guard_err = true;
|
||||
}
|
||||
@ -76,7 +77,7 @@ pub fn check_match(fcx: &FnCtxt,
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
check_expr(fcx, arm.body);
|
||||
check_expr(fcx, &*arm.body);
|
||||
let bty = fcx.node_ty(arm.body.id);
|
||||
saw_err = saw_err || ty::type_is_error(bty);
|
||||
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,
|
||||
subpats: &Option<Vec<@ast::Pat>>, expected: ty::t) {
|
||||
subpats: &Option<Vec<Gc<ast::Pat>>>, expected: ty::t) {
|
||||
|
||||
// Typecheck the path.
|
||||
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 {
|
||||
for pats in subpats.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 {
|
||||
for pats in subpats.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_field.id,
|
||||
substitutions);
|
||||
check_pat(pcx, field.pat, field_type);
|
||||
check_pat(pcx, &*field.pat, field_type);
|
||||
found_fields.insert(index);
|
||||
}
|
||||
None => {
|
||||
// Check the pattern anyway, so that attempts to look
|
||||
// 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,
|
||||
format!("struct `{}` does not have a field named `{}`",
|
||||
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 => {
|
||||
fcx.write_ty(pat.id, expected);
|
||||
}
|
||||
ast::PatLit(lt) => {
|
||||
check_expr_has_type(fcx, lt, expected);
|
||||
fcx.write_ty(pat.id, fcx.expr_ty(lt));
|
||||
ast::PatLit(ref lt) => {
|
||||
check_expr_has_type(fcx, &**lt, expected);
|
||||
fcx.write_ty(pat.id, fcx.expr_ty(&**lt));
|
||||
}
|
||||
ast::PatRange(begin, end) => {
|
||||
check_expr_has_type(fcx, begin, expected);
|
||||
check_expr_has_type(fcx, end, expected);
|
||||
ast::PatRange(ref begin, ref end) => {
|
||||
check_expr_has_type(fcx, &**begin, expected);
|
||||
check_expr_has_type(fcx, &**end, expected);
|
||||
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 =
|
||||
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 ending type: {:?}", e_ty);
|
||||
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,
|
||||
"only char and numeric types are allowed in range");
|
||||
} else {
|
||||
match valid_range_bounds(fcx.ccx, begin, end) {
|
||||
match valid_range_bounds(fcx.ccx, &**begin, &**end) {
|
||||
Some(false) => {
|
||||
tcx.sess.span_err(begin.span,
|
||||
"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);
|
||||
|
||||
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 {
|
||||
ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => {
|
||||
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);
|
||||
}
|
||||
_ => {
|
||||
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
|
||||
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) => {
|
||||
check_pointer_pat(pcx, Send, inner, pat.id, pat.span, expected);
|
||||
ast::PatBox(ref inner) => {
|
||||
check_pointer_pat(pcx, Send, &**inner, pat.id, pat.span, expected);
|
||||
}
|
||||
ast::PatRegion(inner) => {
|
||||
check_pointer_pat(pcx, Borrowed, inner, pat.id, pat.span, expected);
|
||||
ast::PatRegion(ref inner) => {
|
||||
check_pointer_pat(pcx, Borrowed, &**inner, pat.id, pat.span, expected);
|
||||
}
|
||||
ast::PatVec(ref before, slice, ref after) => {
|
||||
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));
|
||||
|
||||
let check_err = || {
|
||||
for &elt in before.iter() {
|
||||
check_pat(pcx, elt, ty::mk_err());
|
||||
for elt in before.iter() {
|
||||
check_pat(pcx, &**elt, ty::mk_err());
|
||||
}
|
||||
for &elt in slice.iter() {
|
||||
check_pat(pcx, elt, ty::mk_err());
|
||||
for elt in slice.iter() {
|
||||
check_pat(pcx, &**elt, ty::mk_err());
|
||||
}
|
||||
for &elt in after.iter() {
|
||||
check_pat(pcx, elt, ty::mk_err());
|
||||
for elt in after.iter() {
|
||||
check_pat(pcx, &**elt, ty::mk_err());
|
||||
}
|
||||
// See [Note-Type-error-reporting] in middle/typeck/infer/mod.rs
|
||||
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() {
|
||||
check_pat(pcx, *elt, elt_type);
|
||||
check_pat(pcx, &**elt, elt_type);
|
||||
}
|
||||
match slice {
|
||||
Some(slice_pat) => {
|
||||
Some(ref slice_pat) => {
|
||||
let slice_ty = ty::mk_slice(tcx,
|
||||
region_var,
|
||||
ty::mt {ty: elt_type, mutbl: mutbl});
|
||||
check_pat(pcx, slice_pat, slice_ty);
|
||||
check_pat(pcx, &**slice_pat, slice_ty);
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
for elt in after.iter() {
|
||||
check_pat(pcx, *elt, elt_type);
|
||||
check_pat(pcx, &**elt, elt_type);
|
||||
}
|
||||
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,
|
||||
pointer_kind: PointerKind,
|
||||
inner: &ast::Pat,
|
||||
|
@ -79,8 +79,6 @@ type parameter).
|
||||
|
||||
use middle::const_eval;
|
||||
use middle::def;
|
||||
use middle::lang_items::{ExchangeHeapLangItem, GcLangItem};
|
||||
use middle::lang_items::{ManagedHeapLangItem};
|
||||
use middle::lint::UnreachableCode;
|
||||
use middle::pat_util::pat_id_map;
|
||||
use middle::pat_util;
|
||||
@ -121,7 +119,7 @@ use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::mem::replace;
|
||||
use std::rc::Rc;
|
||||
use std::vec::Vec;
|
||||
use std::gc::Gc;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{Provided, Required};
|
||||
use syntax::ast;
|
||||
@ -382,11 +380,11 @@ impl<'a> Visitor<()> for GatherLocalsVisitor<'a> {
|
||||
fn visit_local(&mut self, local: &ast::Local, _: ()) {
|
||||
let o_ty = match local.ty.node {
|
||||
ast::TyInfer => None,
|
||||
_ => Some(self.fcx.to_ty(local.ty))
|
||||
_ => Some(self.fcx.to_ty(&*local.ty))
|
||||
};
|
||||
self.assign(local.id, o_ty);
|
||||
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.inh.locals.borrow().get_copy(&local.id)));
|
||||
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()) {
|
||||
// Create type variables for each argument.
|
||||
pat_util::pat_bindings(&tcx.def_map,
|
||||
input.pat,
|
||||
&*input.pat,
|
||||
|_bm, pat_id, _sp, _path| {
|
||||
visit.assign(pat_id, None);
|
||||
});
|
||||
@ -486,9 +484,9 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>,
|
||||
// Check the pattern.
|
||||
let pcx = pat_ctxt {
|
||||
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, ());
|
||||
@ -499,11 +497,11 @@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>,
|
||||
// We unify the tail expr's type with the
|
||||
// function result type, if there is a tail expr.
|
||||
match body.expr {
|
||||
Some(tail_expr) => {
|
||||
Some(ref tail_expr) => {
|
||||
// Special case: we print a special error if there appears
|
||||
// to be do-block/for-loop confusion
|
||||
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| {
|
||||
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());
|
||||
}
|
||||
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();
|
||||
|
||||
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, _) => {
|
||||
check_enum_variants(ccx,
|
||||
it.span,
|
||||
enum_definition.variants.as_slice(),
|
||||
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 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(),
|
||||
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) => {
|
||||
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));
|
||||
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 {
|
||||
@ -694,7 +692,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
}
|
||||
Provided(m) => {
|
||||
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) => {
|
||||
if m.abi == abi::RustIntrinsic {
|
||||
for item in m.items.iter() {
|
||||
check_intrinsic_type(ccx, *item);
|
||||
check_intrinsic_type(ccx, &**item);
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
|
||||
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,
|
||||
@ -778,7 +776,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
|
||||
impl_generics: &ty::Generics,
|
||||
ast_trait_ref: &ast::TraitRef,
|
||||
impl_trait_ref: &ty::TraitRef,
|
||||
impl_methods: &[@ast::Method]) {
|
||||
impl_methods: &[Gc<ast::Method>]) {
|
||||
// Locate trait methods
|
||||
let tcx = ccx.tcx;
|
||||
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.
|
||||
fn try_overloaded_call(fcx: &FnCtxt,
|
||||
call_expression: &ast::Expr,
|
||||
callee: @ast::Expr,
|
||||
callee: Gc<ast::Expr>,
|
||||
callee_type: ty::t,
|
||||
args: &[@ast::Expr])
|
||||
args: &[Gc<ast::Expr>])
|
||||
-> bool {
|
||||
// Try `FnOnce`, then `FnMut`, then `Fn`.
|
||||
for &(maybe_function_trait, method_name) in [
|
||||
@ -1454,7 +1452,7 @@ fn check_method_argument_types(fcx: &FnCtxt,
|
||||
sp: Span,
|
||||
method_fn_ty: ty::t,
|
||||
callee_expr: &ast::Expr,
|
||||
args: &[@ast::Expr],
|
||||
args: &[Gc<ast::Expr>],
|
||||
deref_args: DerefArgs,
|
||||
tuple_arguments: TupleArgumentsFlag)
|
||||
-> ty::t {
|
||||
@ -1501,7 +1499,7 @@ fn check_argument_types(fcx: &FnCtxt,
|
||||
sp: Span,
|
||||
fn_inputs: &[ty::t],
|
||||
callee_expr: &ast::Expr,
|
||||
args: &[@ast::Expr],
|
||||
args: &[Gc<ast::Expr>],
|
||||
deref_args: DerefArgs,
|
||||
variadic: bool,
|
||||
tuple_arguments: TupleArgumentsFlag) {
|
||||
@ -1654,7 +1652,7 @@ fn check_argument_types(fcx: &FnCtxt,
|
||||
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.
|
||||
if variadic {
|
||||
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
|
||||
// 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 {
|
||||
ty::ty_float(ast::TyF32) => {
|
||||
fcx.type_error_message(arg.span,
|
||||
@ -2040,7 +2039,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fn check_call(fcx: &FnCtxt,
|
||||
call_expr: &ast::Expr,
|
||||
f: &ast::Expr,
|
||||
args: &[@ast::Expr]) {
|
||||
args: &[Gc<ast::Expr>]) {
|
||||
// Store the type of `f` as the type of the callee
|
||||
let fn_ty = fcx.expr_ty(f);
|
||||
|
||||
@ -2091,21 +2090,21 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fn check_method_call(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
method_name: ast::SpannedIdent,
|
||||
args: &[@ast::Expr],
|
||||
args: &[Gc<ast::Expr>],
|
||||
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,
|
||||
// so treat the receiver as mutable just in case - only explicit
|
||||
// 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
|
||||
let expr_t = structurally_resolved_type(fcx,
|
||||
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 fn_ty = match method::lookup(fcx, expr, rcvr,
|
||||
let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
|
||||
let fn_ty = match method::lookup(fcx, expr, &*rcvr,
|
||||
method_name.node.name,
|
||||
expr_t, tps.as_slice(),
|
||||
DontDerefArgs,
|
||||
@ -2136,7 +2135,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
// Check for potential static matches (missing self parameters)
|
||||
method::lookup(fcx,
|
||||
expr,
|
||||
rcvr,
|
||||
&*rcvr,
|
||||
method_name.node.name,
|
||||
expr_t,
|
||||
tps.as_slice(),
|
||||
@ -2166,18 +2165,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fn check_then_else(fcx: &FnCtxt,
|
||||
cond_expr: &ast::Expr,
|
||||
then_blk: &ast::Block,
|
||||
opt_else_expr: Option<@ast::Expr>,
|
||||
opt_else_expr: Option<Gc<ast::Expr>>,
|
||||
id: ast::NodeId,
|
||||
sp: Span,
|
||||
expected: Option<ty::t>) {
|
||||
check_expr_has_type(fcx, cond_expr, ty::mk_bool());
|
||||
|
||||
let branches_ty = match opt_else_expr {
|
||||
Some(else_expr) => {
|
||||
Some(ref else_expr) => {
|
||||
check_block_with_expected(fcx, then_blk, expected);
|
||||
let then_ty = fcx.node_ty(then_blk.id);
|
||||
check_expr_with_opt_hint(fcx, else_expr, expected);
|
||||
let else_ty = fcx.expr_ty(else_expr);
|
||||
check_expr_with_opt_hint(fcx, &**else_expr, expected);
|
||||
let else_ty = fcx.expr_ty(&**else_expr);
|
||||
infer::common_supertype(fcx.infcx(),
|
||||
infer::IfExpression(sp),
|
||||
true,
|
||||
@ -2207,7 +2206,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
self_t: ty::t,
|
||||
opname: ast::Name,
|
||||
trait_did: Option<ast::DefId>,
|
||||
args: &[@ast::Expr],
|
||||
args: &[Gc<ast::Expr>],
|
||||
autoderef_receiver: AutoderefReceiverFlag,
|
||||
unbound_method: ||) -> ty::t {
|
||||
let method = match trait_did {
|
||||
@ -2253,8 +2252,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fn check_binop(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
op: ast::BinOp,
|
||||
lhs: @ast::Expr,
|
||||
rhs: @ast::Expr,
|
||||
lhs: Gc<ast::Expr>,
|
||||
rhs: Gc<ast::Expr>,
|
||||
is_binop_assignment: IsBinopAssignment) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
@ -2262,16 +2261,16 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
BinopAssignment => PreferMutLvalue,
|
||||
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
|
||||
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) {
|
||||
// Shift is a special case: rhs can be any integral type
|
||||
check_expr(fcx, rhs);
|
||||
let rhs_t = fcx.expr_ty(rhs);
|
||||
check_expr(fcx, &*rhs);
|
||||
let rhs_t = fcx.expr_ty(&*rhs);
|
||||
require_integral(fcx, rhs.span, rhs_t);
|
||||
fcx.write_ty(expr.id, lhs_t);
|
||||
return;
|
||||
@ -2280,7 +2279,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
if ty::is_binopable(tcx, lhs_t, op) {
|
||||
let tvar = fcx.infcx().next_ty_var();
|
||||
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 {
|
||||
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe |
|
||||
@ -2345,7 +2344,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
},
|
||||
lhs_t,
|
||||
None);
|
||||
check_expr(fcx, rhs);
|
||||
check_expr(fcx, &*rhs);
|
||||
ty::mk_err()
|
||||
};
|
||||
|
||||
@ -2357,10 +2356,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
|
||||
fn check_user_binop(fcx: &FnCtxt,
|
||||
ex: &ast::Expr,
|
||||
lhs_expr: @ast::Expr,
|
||||
lhs_expr: Gc<ast::Expr>,
|
||||
lhs_resolved_t: ty::t,
|
||||
op: ast::BinOp,
|
||||
rhs: @ast::Expr) -> ty::t {
|
||||
rhs: Gc<ast::Expr>) -> ty::t {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
let lang = &tcx.lang_items;
|
||||
let (name, trait_did) = match op {
|
||||
@ -2381,7 +2380,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ast::BiEq => ("eq", lang.eq_trait()),
|
||||
ast::BiNe => ("ne", lang.eq_trait()),
|
||||
ast::BiAnd | ast::BiOr => {
|
||||
check_expr(fcx, rhs);
|
||||
check_expr(fcx, &*rhs);
|
||||
return ty::mk_err();
|
||||
}
|
||||
};
|
||||
@ -2400,7 +2399,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
mname: &str,
|
||||
trait_did: Option<ast::DefId>,
|
||||
ex: &ast::Expr,
|
||||
rhs_expr: @ast::Expr,
|
||||
rhs_expr: Gc<ast::Expr>,
|
||||
rhs_t: ty::t) -> ty::t {
|
||||
lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
|
||||
trait_did, [rhs_expr], DontAutoderefReceiver, || {
|
||||
@ -2513,7 +2512,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
};
|
||||
|
||||
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 => {}
|
||||
}
|
||||
|
||||
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,
|
||||
expr,
|
||||
base,
|
||||
@ -2647,7 +2646,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
// an error, so we can continue typechecking
|
||||
check_expr_coercable_to_type(
|
||||
fcx,
|
||||
field.expr,
|
||||
&*field.expr,
|
||||
expected_field_type);
|
||||
}
|
||||
|
||||
@ -2688,7 +2687,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
span: codemap::Span,
|
||||
class_id: ast::DefId,
|
||||
fields: &[ast::Field],
|
||||
base_expr: Option<@ast::Expr>) {
|
||||
base_expr: Option<Gc<ast::Expr>>) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
// 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 {
|
||||
None => {}
|
||||
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)) {
|
||||
struct_type = ty::mk_bot();
|
||||
}
|
||||
@ -2793,8 +2792,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
let mut any_bot = false;
|
||||
let t: ty::t = fcx.infcx().next_ty_var();
|
||||
for e in args.iter() {
|
||||
check_expr_has_type(fcx, *e, t);
|
||||
let arg_t = fcx.expr_ty(*e);
|
||||
check_expr_has_type(fcx, &**e, t);
|
||||
let arg_t = fcx.expr_ty(&**e);
|
||||
if ty::type_is_error(arg_t) {
|
||||
any_error = true;
|
||||
}
|
||||
@ -2807,29 +2806,29 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
} else if any_bot {
|
||||
ty::mk_bot()
|
||||
} 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: t, mutbl: mutability},
|
||||
None),
|
||||
mutbl: mutability })
|
||||
}
|
||||
}
|
||||
ast::ExprRepeat(element, count_expr) => {
|
||||
check_expr_with_hint(fcx, count_expr, ty::mk_uint());
|
||||
let _ = ty::eval_repeat_count(fcx, count_expr);
|
||||
ast::ExprRepeat(ref element, ref count_expr) => {
|
||||
check_expr_with_hint(fcx, &**count_expr, ty::mk_uint());
|
||||
let _ = ty::eval_repeat_count(fcx, &**count_expr);
|
||||
let mutability = match vst {
|
||||
ast::ExprVstoreMutSlice => ast::MutMutable,
|
||||
_ => ast::MutImmutable,
|
||||
};
|
||||
let t = fcx.infcx().next_ty_var();
|
||||
check_expr_has_type(fcx, element, t);
|
||||
let arg_t = fcx.expr_ty(element);
|
||||
check_expr_has_type(fcx, &**element, t);
|
||||
let arg_t = fcx.expr_ty(&**element);
|
||||
if ty::type_is_error(arg_t) {
|
||||
ty::mk_err()
|
||||
} else if ty::type_is_bot(arg_t) {
|
||||
ty::mk_bot()
|
||||
} 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: t, mutbl: mutability},
|
||||
None),
|
||||
@ -2851,9 +2850,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fcx.write_ty(id, typ);
|
||||
}
|
||||
|
||||
ast::ExprBox(place, subexpr) => {
|
||||
check_expr(fcx, place);
|
||||
check_expr(fcx, subexpr);
|
||||
ast::ExprBox(ref place, ref subexpr) => {
|
||||
check_expr(fcx, &**place);
|
||||
check_expr(fcx, &**subexpr);
|
||||
|
||||
let mut checked = false;
|
||||
match place.node {
|
||||
@ -2862,52 +2861,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
// places: the exchange heap and the managed heap.
|
||||
let definition = lookup_def(fcx, path.span, place.id);
|
||||
let def_id = definition.def_id();
|
||||
match tcx.lang_items
|
||||
.items
|
||||
.get(ExchangeHeapLangItem as uint) {
|
||||
&Some(item_def_id) if def_id == item_def_id => {
|
||||
fcx.write_ty(id, ty::mk_uniq(tcx,
|
||||
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 => {}
|
||||
}
|
||||
if tcx.lang_items.exchange_heap() == Some(def_id) {
|
||||
fcx.write_ty(id, ty::mk_uniq(tcx,
|
||||
fcx.expr_ty(&**subexpr)));
|
||||
checked = true
|
||||
} else if tcx.lang_items.managed_heap() == Some(def_id) {
|
||||
fcx.write_ty(id, ty::mk_box(tcx,
|
||||
fcx.expr_ty(&**subexpr)));
|
||||
checked = true
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -2921,15 +2882,15 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprLit(lit) => {
|
||||
let typ = check_lit(fcx, lit);
|
||||
ast::ExprLit(ref lit) => {
|
||||
let typ = check_lit(fcx, &**lit);
|
||||
fcx.write_ty(id, typ);
|
||||
}
|
||||
ast::ExprBinary(op, lhs, rhs) => {
|
||||
check_binop(fcx, expr, op, lhs, rhs, SimpleBinop);
|
||||
ast::ExprBinary(op, ref lhs, ref rhs) => {
|
||||
check_binop(fcx, expr, op, lhs.clone(), rhs.clone(), SimpleBinop);
|
||||
|
||||
let lhs_ty = fcx.expr_ty(lhs);
|
||||
let rhs_ty = fcx.expr_ty(rhs);
|
||||
let lhs_ty = fcx.expr_ty(&**lhs);
|
||||
let rhs_ty = fcx.expr_ty(&**rhs);
|
||||
if ty::type_is_error(lhs_ty) ||
|
||||
ty::type_is_error(rhs_ty) {
|
||||
fcx.write_error(id);
|
||||
@ -2939,15 +2900,15 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, lhs, rhs) => {
|
||||
check_binop(fcx, expr, op, lhs, rhs, BinopAssignment);
|
||||
ast::ExprAssignOp(op, ref lhs, ref rhs) => {
|
||||
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);
|
||||
demand::suptype(fcx, expr.span, result_t, lhs_t);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@ -2959,7 +2920,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fcx.write_nil(expr.id);
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(unop, oprnd) => {
|
||||
ast::ExprUnary(unop, ref oprnd) => {
|
||||
let exp_inner = unpack_expected(fcx, expected, |sty| {
|
||||
match unop {
|
||||
ast::UnBox | ast::UnUniq => match *sty {
|
||||
@ -2974,8 +2935,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ast::UnDeref => lvalue_pref,
|
||||
_ => NoPreference
|
||||
};
|
||||
check_expr_with_opt_hint_and_lvalue_pref(fcx, oprnd, exp_inner, lvalue_pref);
|
||||
let mut oprnd_t = fcx.expr_ty(oprnd);
|
||||
check_expr_with_opt_hint_and_lvalue_pref(fcx, &**oprnd, exp_inner, lvalue_pref);
|
||||
let mut oprnd_t = fcx.expr_ty(&**oprnd);
|
||||
if !ty::type_is_error(oprnd_t) && !ty::type_is_bot(oprnd_t) {
|
||||
match unop {
|
||||
ast::UnBox => {
|
||||
@ -2990,7 +2951,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
Some(mt) => mt.ty,
|
||||
None => match try_overloaded_deref(fcx, expr.span,
|
||||
Some(MethodCall::expr(expr.id)),
|
||||
Some(&*oprnd), oprnd_t, lvalue_pref) {
|
||||
Some(&**oprnd), oprnd_t, lvalue_pref) {
|
||||
Some(mt) => mt.ty,
|
||||
None => {
|
||||
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) {
|
||||
oprnd_t = check_user_unop(fcx, "!", "not",
|
||||
tcx.lang_items.not_trait(),
|
||||
expr, oprnd, oprnd_t);
|
||||
expr, oprnd.clone(), oprnd_t);
|
||||
}
|
||||
}
|
||||
ast::UnNeg => {
|
||||
@ -3035,14 +2996,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ty::type_is_fp(oprnd_t)) {
|
||||
oprnd_t = check_user_unop(fcx, "-", "neg",
|
||||
tcx.lang_items.neg_trait(),
|
||||
expr, oprnd, oprnd_t);
|
||||
expr, oprnd.clone(), oprnd_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fcx.write_ty(id, oprnd_t);
|
||||
}
|
||||
ast::ExprAddrOf(mutbl, oprnd) => {
|
||||
ast::ExprAddrOf(mutbl, ref oprnd) => {
|
||||
let hint = unpack_expected(
|
||||
fcx, expected,
|
||||
|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::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
|
||||
// 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(
|
||||
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) {
|
||||
ty::mk_err()
|
||||
} 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);
|
||||
}
|
||||
ast::ExprInlineAsm(ref ia) => {
|
||||
for &(_, input) in ia.inputs.iter() {
|
||||
check_expr(fcx, input);
|
||||
for &(_, ref input) in ia.inputs.iter() {
|
||||
check_expr(fcx, &**input);
|
||||
}
|
||||
for &(_, out) in ia.outputs.iter() {
|
||||
check_expr(fcx, out);
|
||||
for &(_, ref out) in ia.outputs.iter() {
|
||||
check_expr(fcx, &**out);
|
||||
}
|
||||
fcx.write_nil(id);
|
||||
}
|
||||
ast::ExprMac(_) => tcx.sess.bug("unexpanded macro"),
|
||||
ast::ExprBreak(_) => { 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;
|
||||
match expr_opt {
|
||||
match *expr_opt {
|
||||
None => match fcx.mk_eqty(false, infer::Misc(expr.span),
|
||||
ret_ty, ty::mk_nil()) {
|
||||
Ok(_) => { /* fall through */ }
|
||||
@ -3111,27 +3072,27 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
"`return;` in function returning non-nil");
|
||||
}
|
||||
},
|
||||
Some(e) => {
|
||||
check_expr_has_type(fcx, e, ret_ty);
|
||||
Some(ref e) => {
|
||||
check_expr_has_type(fcx, &**e, ret_ty);
|
||||
}
|
||||
}
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
ast::ExprParen(a) => {
|
||||
check_expr_with_opt_hint_and_lvalue_pref(fcx, a, expected, lvalue_pref);
|
||||
fcx.write_ty(id, fcx.expr_ty(a));
|
||||
ast::ExprParen(ref a) => {
|
||||
check_expr_with_opt_hint_and_lvalue_pref(fcx, &**a, expected, lvalue_pref);
|
||||
fcx.write_ty(id, fcx.expr_ty(&**a));
|
||||
}
|
||||
ast::ExprAssign(lhs, rhs) => {
|
||||
check_expr_with_lvalue_pref(fcx, lhs, PreferMutLvalue);
|
||||
ast::ExprAssign(ref lhs, ref rhs) => {
|
||||
check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
let lhs_ty = fcx.expr_ty(lhs);
|
||||
check_expr_has_type(fcx, rhs, lhs_ty);
|
||||
let rhs_ty = fcx.expr_ty(rhs);
|
||||
let lhs_ty = fcx.expr_ty(&**lhs);
|
||||
check_expr_has_type(fcx, &**rhs, lhs_ty);
|
||||
let rhs_ty = fcx.expr_ty(&**rhs);
|
||||
|
||||
if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) {
|
||||
fcx.write_error(id);
|
||||
@ -3141,14 +3102,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fcx.write_nil(id);
|
||||
}
|
||||
}
|
||||
ast::ExprIf(cond, then_blk, opt_else_expr) => {
|
||||
check_then_else(fcx, 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.clone(),
|
||||
id, expr.span, expected);
|
||||
}
|
||||
ast::ExprWhile(cond, body) => {
|
||||
check_expr_has_type(fcx, cond, ty::mk_bool());
|
||||
check_block_no_value(fcx, body);
|
||||
let cond_ty = fcx.expr_ty(cond);
|
||||
ast::ExprWhile(ref cond, ref body) => {
|
||||
check_expr_has_type(fcx, &**cond, ty::mk_bool());
|
||||
check_block_no_value(fcx, &**body);
|
||||
let cond_ty = fcx.expr_ty(&**cond);
|
||||
let body_ty = fcx.node_ty(body.id);
|
||||
if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) {
|
||||
fcx.write_error(id);
|
||||
@ -3162,19 +3123,19 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
ast::ExprForLoop(..) =>
|
||||
fail!("non-desugared expr_for_loop"),
|
||||
ast::ExprLoop(body, _) => {
|
||||
check_block_no_value(fcx, (body));
|
||||
if !may_break(tcx, expr.id, body) {
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
check_block_no_value(fcx, &**body);
|
||||
if !may_break(tcx, expr.id, body.clone()) {
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
else {
|
||||
fcx.write_nil(id);
|
||||
}
|
||||
}
|
||||
ast::ExprMatch(discrim, ref arms) => {
|
||||
_match::check_match(fcx, expr, discrim, arms.as_slice());
|
||||
ast::ExprMatch(ref discrim, ref arms) => {
|
||||
_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,
|
||||
fcx.infcx(),
|
||||
expr.span,
|
||||
@ -3182,34 +3143,34 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
check_expr_fn(fcx,
|
||||
expr,
|
||||
ty::RegionTraitStore(region, ast::MutMutable),
|
||||
decl,
|
||||
body,
|
||||
&**decl,
|
||||
body.clone(),
|
||||
expected);
|
||||
}
|
||||
ast::ExprProc(decl, body) => {
|
||||
ast::ExprProc(ref decl, ref body) => {
|
||||
check_expr_fn(fcx,
|
||||
expr,
|
||||
ty::UniqTraitStore,
|
||||
decl,
|
||||
body,
|
||||
&**decl,
|
||||
body.clone(),
|
||||
expected);
|
||||
}
|
||||
ast::ExprBlock(b) => {
|
||||
check_block_with_expected(fcx, b, expected);
|
||||
ast::ExprBlock(ref b) => {
|
||||
check_block_with_expected(fcx, &**b, expected);
|
||||
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
|
||||
// that they appear in call position.
|
||||
check_expr(fcx, f);
|
||||
let f_ty = fcx.expr_ty(f);
|
||||
check_expr(fcx, &**f);
|
||||
let f_ty = fcx.expr_ty(&**f);
|
||||
|
||||
if !try_overloaded_call(fcx, expr, f, f_ty, args.as_slice()) {
|
||||
check_call(fcx, expr, f, args.as_slice());
|
||||
if !try_overloaded_call(fcx, expr, f.clone(), f_ty, args.as_slice()) {
|
||||
check_call(fcx, expr, &**f, args.as_slice());
|
||||
let (args_bot, args_err) = args.iter().fold((false, false),
|
||||
|(rest_bot, rest_err), a| {
|
||||
// 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_err || ty::type_is_error(a_ty))});
|
||||
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) => {
|
||||
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),
|
||||
|(rest_bot, rest_err), a| {
|
||||
(rest_bot || ty::type_is_bot(a),
|
||||
@ -3233,10 +3194,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
}
|
||||
ast::ExprCast(e, t) => {
|
||||
check_expr(fcx, e);
|
||||
let t_1 = fcx.to_ty(t);
|
||||
let t_e = fcx.expr_ty(e);
|
||||
ast::ExprCast(ref e, ref t) => {
|
||||
check_expr(fcx, &**e);
|
||||
let t_1 = fcx.to_ty(&**t);
|
||||
let t_e = fcx.expr_ty(&**e);
|
||||
|
||||
debug!("t_1={}", fcx.infcx().ty_to_str(t_1));
|
||||
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 */
|
||||
}
|
||||
_ => {
|
||||
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)
|
||||
@ -3359,18 +3320,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ast::ExprVec(ref args) => {
|
||||
let t: ty::t = fcx.infcx().next_ty_var();
|
||||
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},
|
||||
Some(args.len()));
|
||||
fcx.write_ty(id, typ);
|
||||
}
|
||||
ast::ExprRepeat(element, count_expr) => {
|
||||
check_expr_with_hint(fcx, count_expr, ty::mk_uint());
|
||||
let count = ty::eval_repeat_count(fcx, count_expr);
|
||||
ast::ExprRepeat(ref element, ref count_expr) => {
|
||||
check_expr_with_hint(fcx, &**count_expr, ty::mk_uint());
|
||||
let count = ty::eval_repeat_count(fcx, &**count_expr);
|
||||
let t: ty::t = fcx.infcx().next_ty_var();
|
||||
check_expr_has_type(fcx, element, t);
|
||||
let element_ty = fcx.expr_ty(element);
|
||||
check_expr_has_type(fcx, &**element, t);
|
||||
let element_ty = fcx.expr_ty(&**element);
|
||||
if ty::type_is_error(element_ty) {
|
||||
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)),
|
||||
_ => None
|
||||
};
|
||||
check_expr_with_opt_hint(fcx, *e, opt_hint);
|
||||
let t = fcx.expr_ty(*e);
|
||||
check_expr_with_opt_hint(fcx, &**e, opt_hint);
|
||||
let t = fcx.expr_ty(&**e);
|
||||
err_field = err_field || ty::type_is_error(t);
|
||||
bot_field = bot_field || ty::type_is_bot(t);
|
||||
t
|
||||
@ -3431,14 +3392,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ExprField(base, field, ref tys) => {
|
||||
check_field(fcx, expr, lvalue_pref, base, field.name, tys.as_slice());
|
||||
ast::ExprField(ref base, ref field, ref tys) => {
|
||||
check_field(fcx, expr, lvalue_pref, &**base, field.name, tys.as_slice());
|
||||
}
|
||||
ast::ExprIndex(base, idx) => {
|
||||
check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
|
||||
check_expr(fcx, idx);
|
||||
let raw_base_t = fcx.expr_ty(base);
|
||||
let idx_t = fcx.expr_ty(idx);
|
||||
ast::ExprIndex(ref base, ref idx) => {
|
||||
check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
|
||||
check_expr(fcx, &**idx);
|
||||
let raw_base_t = fcx.expr_ty(&**base);
|
||||
let idx_t = fcx.expr_ty(&**idx);
|
||||
if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
|
||||
fcx.write_ty(id, raw_base_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));
|
||||
match field_ty {
|
||||
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_autoderef_adjustment(base.id, autoderefs);
|
||||
}
|
||||
@ -3462,7 +3423,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
resolved,
|
||||
token::intern("index"),
|
||||
tcx.lang_items.index_trait(),
|
||||
[base, idx],
|
||||
[base.clone(), idx.clone()],
|
||||
AutoderefReceiver,
|
||||
|| {
|
||||
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);
|
||||
|
||||
match local.init {
|
||||
Some(init) => {
|
||||
check_decl_initializer(fcx, local.id, init);
|
||||
let init_ty = fcx.expr_ty(init);
|
||||
Some(ref init) => {
|
||||
check_decl_initializer(fcx, local.id, &**init);
|
||||
let init_ty = fcx.expr_ty(&**init);
|
||||
if ty::type_is_error(init_ty) || ty::type_is_bot(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 {
|
||||
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);
|
||||
if ty::type_is_error(pat_ty) || ty::type_is_bot(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;
|
||||
match decl.node {
|
||||
ast::DeclLocal(ref l) => {
|
||||
check_decl_local(fcx, *l);
|
||||
check_decl_local(fcx, &**l);
|
||||
let l_t = fcx.node_ty(l.id);
|
||||
saw_bot = saw_bot || ty::type_is_bot(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::StmtExpr(expr, id) => {
|
||||
ast::StmtExpr(ref expr, id) => {
|
||||
node_id = id;
|
||||
// Check with expected type of ()
|
||||
check_expr_has_type(fcx, expr, ty::mk_nil());
|
||||
let expr_ty = fcx.expr_ty(expr);
|
||||
check_expr_has_type(fcx, &**expr, ty::mk_nil());
|
||||
let expr_ty = fcx.expr_ty(&**expr);
|
||||
saw_bot = saw_bot || ty::type_is_bot(expr_ty);
|
||||
saw_err = saw_err || ty::type_is_error(expr_ty);
|
||||
}
|
||||
ast::StmtSemi(expr, id) => {
|
||||
ast::StmtSemi(ref expr, id) => {
|
||||
node_id = id;
|
||||
check_expr(fcx, expr);
|
||||
let expr_ty = fcx.expr_ty(expr);
|
||||
check_expr(fcx, &**expr);
|
||||
let expr_ty = fcx.expr_ty(&**expr);
|
||||
saw_bot |= ty::type_is_bot(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_err = false;
|
||||
for s in blk.stmts.iter() {
|
||||
check_stmt(fcx, *s);
|
||||
let s_id = ast_util::stmt_id(*s);
|
||||
check_stmt(fcx, &**s);
|
||||
let s_id = ast_util::stmt_id(&**s);
|
||||
let s_ty = fcx.node_ty(s_id);
|
||||
if last_was_bot && !warned && match s.node {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
@ -3670,8 +3631,8 @@ pub fn check_block_with_expected(fcx: &FnCtxt,
|
||||
e.span,
|
||||
"unreachable expression".to_string());
|
||||
}
|
||||
check_expr_with_opt_hint(fcx, e, expected);
|
||||
let ety = fcx.expr_ty(e);
|
||||
check_expr_with_opt_hint(fcx, &*e, expected);
|
||||
let ety = fcx.expr_ty(&*e);
|
||||
fcx.write_ty(blk.id, ety);
|
||||
if any_err {
|
||||
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 {
|
||||
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 fcx = blank_fn_ctxt(ccx, &inh, rty, e.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
|
||||
// that the expression is in a form that eval_const_expr can
|
||||
// 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_uint(val)) => current_disr_val = val as Disr,
|
||||
Ok(_) => {
|
||||
@ -3936,7 +3897,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
||||
}
|
||||
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));
|
||||
prev_disr_val = Some(current_disr_val);
|
||||
|
||||
@ -4134,7 +4095,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||
let mut pushed = false;
|
||||
for (i, ty) in pth.segments.iter()
|
||||
.flat_map(|segment| segment.types.iter())
|
||||
.map(|&ast_type| fcx.to_ty(ast_type))
|
||||
.map(|ast_type| fcx.to_ty(&**ast_type))
|
||||
.enumerate() {
|
||||
match self_parameter_index {
|
||||
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 {
|
||||
// First: is there an unlabeled break immediately
|
||||
// inside the loop?
|
||||
(loop_query(b, |e| {
|
||||
(loop_query(&*b, |e| {
|
||||
match *e {
|
||||
ast::ExprBreak(_) => true,
|
||||
_ => false
|
||||
|
@ -141,6 +141,7 @@ use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
|
||||
// If mem categorization results in an error, it's because the type
|
||||
// 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) {
|
||||
// see above
|
||||
for &p in arm.pats.iter() {
|
||||
constrain_bindings_in_pat(p, rcx);
|
||||
for p in arm.pats.iter() {
|
||||
constrain_bindings_in_pat(&**p, rcx);
|
||||
}
|
||||
|
||||
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) {
|
||||
// see above
|
||||
constrain_bindings_in_pat(l.pat, rcx);
|
||||
constrain_bindings_in_pat(&*l.pat, rcx);
|
||||
link_local(rcx, l);
|
||||
visit::walk_local(rcx, l, ());
|
||||
}
|
||||
@ -441,9 +442,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
}
|
||||
|
||||
match expr.node {
|
||||
ast::ExprCall(callee, ref args) => {
|
||||
ast::ExprCall(ref callee, ref args) => {
|
||||
if !has_method_map {
|
||||
constrain_callee(rcx, callee.id, expr, callee);
|
||||
constrain_callee(rcx, callee.id, expr, &**callee);
|
||||
constrain_call(rcx,
|
||||
Some(callee.id),
|
||||
expr,
|
||||
@ -462,45 +463,47 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprAssign(lhs, _) => {
|
||||
adjust_borrow_kind_for_assignment_lhs(rcx, lhs);
|
||||
ast::ExprAssign(ref lhs, _) => {
|
||||
adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprAssignOp(_, lhs, rhs) => {
|
||||
ast::ExprAssignOp(_, ref lhs, ref rhs) => {
|
||||
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, ());
|
||||
}
|
||||
|
||||
ast::ExprIndex(lhs, rhs) |
|
||||
ast::ExprBinary(_, lhs, rhs) if has_method_map => {
|
||||
ast::ExprIndex(ref lhs, ref rhs) |
|
||||
ast::ExprBinary(_, ref lhs, ref rhs) if has_method_map => {
|
||||
// As `expr_method_call`, but the call is via an
|
||||
// overloaded op. Note that we (sadly) currently use an
|
||||
// implicit "by ref" sort of passing style here. This
|
||||
// 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, ());
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, lhs) if has_method_map => {
|
||||
ast::ExprUnary(_, ref lhs) if has_method_map => {
|
||||
// As above.
|
||||
constrain_call(rcx, None, expr, Some(lhs), [], true);
|
||||
constrain_call(rcx, None, expr, Some(lhs.clone()), [], true);
|
||||
|
||||
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
|
||||
let method_call = MethodCall::expr(expr.id);
|
||||
let base_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) {
|
||||
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)
|
||||
}
|
||||
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, ());
|
||||
}
|
||||
|
||||
ast::ExprIndex(vec_expr, _) => {
|
||||
ast::ExprIndex(ref vec_expr, _) => {
|
||||
// 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);
|
||||
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprCast(source, _) => {
|
||||
ast::ExprCast(ref source, _) => {
|
||||
// Determine if we are casting `source` to a trait
|
||||
// instance. If so, we have to be sure that the type of
|
||||
// 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 {
|
||||
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(
|
||||
rcx,
|
||||
trait_region,
|
||||
@ -556,8 +559,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprAddrOf(m, base) => {
|
||||
link_addr_of(rcx, expr, m, base);
|
||||
ast::ExprAddrOf(m, ref base) => {
|
||||
link_addr_of(rcx, expr, m, &**base);
|
||||
|
||||
// Require that when you write a `&expr` expression, 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, ());
|
||||
}
|
||||
|
||||
ast::ExprMatch(discr, ref arms) => {
|
||||
link_match(rcx, discr, arms.as_slice());
|
||||
ast::ExprMatch(ref discr, ref arms) => {
|
||||
link_match(rcx, &**discr, arms.as_slice());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ast::ExprLoop(body, _) => {
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
let repeating_scope = rcx.set_repeating_scope(body.id);
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
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);
|
||||
rcx.visit_expr(cond, ());
|
||||
rcx.visit_expr(&**cond, ());
|
||||
|
||||
rcx.set_repeating_scope(body.id);
|
||||
rcx.visit_block(body, ());
|
||||
rcx.visit_block(&**body, ());
|
||||
|
||||
rcx.set_repeating_scope(repeating_scope);
|
||||
}
|
||||
@ -785,8 +788,8 @@ fn constrain_call(rcx: &mut Rcx,
|
||||
// operator
|
||||
fn_expr_id: Option<ast::NodeId>,
|
||||
call_expr: &ast::Expr,
|
||||
receiver: Option<@ast::Expr>,
|
||||
arg_exprs: &[@ast::Expr],
|
||||
receiver: Option<Gc<ast::Expr>>,
|
||||
arg_exprs: &[Gc<ast::Expr>],
|
||||
implicitly_ref_args: bool) {
|
||||
//! Invoked on every call site (i.e., normal calls, method calls,
|
||||
//! 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_region = ty::ReScope(callee_scope);
|
||||
|
||||
for &arg_expr in arg_exprs.iter() {
|
||||
for arg_expr in arg_exprs.iter() {
|
||||
debug!("Argument");
|
||||
|
||||
// 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
|
||||
// should be ported to use adjustments
|
||||
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
|
||||
for &r in receiver.iter() {
|
||||
for r in receiver.iter() {
|
||||
debug!("Receiver");
|
||||
constrain_regions_in_type_of_node(
|
||||
rcx, r.id, callee_region, infer::CallRcvr(r.span));
|
||||
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()");
|
||||
let init_expr = match local.init {
|
||||
None => { return; }
|
||||
Some(expr) => expr,
|
||||
Some(ref expr) => expr,
|
||||
};
|
||||
let mc = mc::MemCategorizationContext::new(rcx);
|
||||
let discr_cmt = ignore_err!(mc.cat_expr(init_expr));
|
||||
link_pattern(rcx, mc, discr_cmt, local.pat);
|
||||
let discr_cmt = ignore_err!(mc.cat_expr(&**init_expr));
|
||||
link_pattern(rcx, mc, discr_cmt, &*local.pat);
|
||||
}
|
||||
|
||||
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));
|
||||
debug!("discr_cmt={}", discr_cmt.repr(rcx.tcx()));
|
||||
for arm in arms.iter() {
|
||||
for &root_pat in arm.pats.iter() {
|
||||
link_pattern(rcx, mc, discr_cmt.clone(), root_pat);
|
||||
for root_pat in arm.pats.iter() {
|
||||
link_pattern(rcx, mc, discr_cmt.clone(), &**root_pat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1098,8 +1101,8 @@ fn link_pattern(rcx: &Rcx,
|
||||
}
|
||||
|
||||
// `[_, ..slice, _]` pattern
|
||||
ast::PatVec(_, Some(slice_pat), _) => {
|
||||
match mc.cat_slice_pattern(sub_cmt, slice_pat) {
|
||||
ast::PatVec(_, Some(ref slice_pat), _) => {
|
||||
match mc.cat_slice_pattern(sub_cmt, &**slice_pat) {
|
||||
Ok((slice_cmt, slice_mutbl, slice_r)) => {
|
||||
link_region(rcx, sub_pat.span, slice_r,
|
||||
ty::BorrowKind::from_mutbl(slice_mutbl),
|
||||
|
@ -666,10 +666,10 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
ast::ExprCast(src, _) => {
|
||||
ast::ExprCast(ref src, _) => {
|
||||
debug!("vtable resolution on expr {}", ex.repr(fcx.tcx()));
|
||||
let target_ty = fcx.expr_ty(ex);
|
||||
resolve_object_cast(src, target_ty);
|
||||
resolve_object_cast(&**src, target_ty);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
@ -53,10 +53,10 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
|
||||
let mut wbcx = WritebackCx::new(fcx);
|
||||
wbcx.visit_block(blk, ());
|
||||
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
|
||||
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),
|
||||
arg.pat.id);
|
||||
}
|
||||
|
@ -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.
|
||||
visit::walk_mod(self, module_, ());
|
||||
}
|
||||
ItemImpl(_, None, ast_ty, _) => {
|
||||
if !self.cc.ast_type_is_defined_in_local_crate(ast_ty) {
|
||||
ItemImpl(_, None, ref ast_ty, _) => {
|
||||
if !self.cc.ast_type_is_defined_in_local_crate(&**ast_ty) {
|
||||
// This is an error.
|
||||
let session = &self.cc.crate_context.tcx.sess;
|
||||
session.span_err(item.span,
|
||||
|
@ -50,6 +50,8 @@ use util::ppaux::Repr;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
|
||||
use syntax::abi;
|
||||
use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound};
|
||||
use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
|
||||
@ -117,10 +119,10 @@ impl<'a> AstConv for CrateCtxt<'a> {
|
||||
}
|
||||
|
||||
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)) => {
|
||||
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 => {
|
||||
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 {
|
||||
ast::TupleVariantKind(ref args) if args.len() > 0 => {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -170,7 +172,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
|
||||
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(
|
||||
|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(
|
||||
ccx, trait_id, &trait_ty_generics,
|
||||
&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) => {
|
||||
ty_method_of_trait_method(
|
||||
ccx, trait_id, &trait_ty_generics,
|
||||
&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,
|
||||
v: &ast::StructField,
|
||||
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);
|
||||
/* add the field to the tcache */
|
||||
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,
|
||||
container: MethodContainer,
|
||||
ms: &[@ast::Method],
|
||||
ms: &[Gc<ast::Method>],
|
||||
untransformed_rcvr_ty: ty::t,
|
||||
rcvr_ty_generics: &ty::Generics,
|
||||
rcvr_ast_generics: &ast::Generics,
|
||||
@ -503,7 +505,7 @@ fn convert_methods(ccx: &CrateCtxt,
|
||||
num_rcvr_ty_params);
|
||||
let mty = Rc::new(ty_of_method(ccx,
|
||||
container,
|
||||
*m,
|
||||
&**m,
|
||||
untransformed_rcvr_ty,
|
||||
rcvr_ast_generics,
|
||||
rcvr_visibility));
|
||||
@ -542,7 +544,7 @@ fn convert_methods(ccx: &CrateCtxt,
|
||||
{
|
||||
let fty = astconv::ty_of_method(ccx, m.id, m.fn_style,
|
||||
untransformed_rcvr_ty,
|
||||
m.explicit_self, m.decl);
|
||||
m.explicit_self, &*m.decl);
|
||||
|
||||
// if the method specifies a visibility, use that, otherwise
|
||||
// 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) => {
|
||||
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);
|
||||
|
||||
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.
|
||||
match struct_def.super_struct {
|
||||
Some(ty) => {
|
||||
let supserty = ccx.to_ty(&ExplicitRscope, ty);
|
||||
let supserty = ccx.to_ty(&ExplicitRscope, &*ty);
|
||||
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) => {
|
||||
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) {
|
||||
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",
|
||||
trait_id.node).as_slice())
|
||||
@ -910,7 +912,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
|
||||
}
|
||||
match it.node {
|
||||
ast::ItemStatic(t, _, _) => {
|
||||
let typ = ccx.to_ty(&ExplicitRscope, t);
|
||||
let typ = ccx.to_ty(&ExplicitRscope, &*t);
|
||||
let tpt = no_params(typ);
|
||||
|
||||
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,
|
||||
fn_style,
|
||||
abi,
|
||||
decl);
|
||||
&*decl);
|
||||
let tpt = ty_param_bounds_and_ty {
|
||||
generics: ty_generics,
|
||||
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 ty = ccx.to_ty(&ExplicitRscope, t);
|
||||
let ty = ccx.to_ty(&ExplicitRscope, &*t);
|
||||
ty_param_bounds_and_ty {
|
||||
generics: ty_generics_for_type(ccx, generics),
|
||||
ty: ty
|
||||
@ -992,7 +994,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
|
||||
match it.node {
|
||||
ast::ForeignItemFn(fn_decl, ref generics) => {
|
||||
ty_of_foreign_fn_decl(ccx,
|
||||
fn_decl,
|
||||
&*fn_decl,
|
||||
local_def(it.id),
|
||||
generics,
|
||||
abi)
|
||||
@ -1003,7 +1005,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
|
||||
type_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.span));
|
||||
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;
|
||||
|
||||
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))
|
||||
.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(
|
||||
ccx.tcx,
|
||||
|
@ -1140,7 +1140,7 @@ impl<'a> Rebuilder<'a> {
|
||||
}
|
||||
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 {
|
||||
@ -1155,7 +1155,7 @@ impl<'a> Rebuilder<'a> {
|
||||
}
|
||||
_ => fail!("expect ast::TyRptr or ast::TyPath")
|
||||
};
|
||||
let new_ty = @ast::Ty {
|
||||
let new_ty = box(GC) ast::Ty {
|
||||
id: to.id,
|
||||
node: new_ty_node,
|
||||
span: to.span
|
||||
|
@ -479,13 +479,13 @@ impl<'a> Visitor<()> for ConstraintContext<'a> {
|
||||
// `ty::VariantInfo::from_ast_variant()` ourselves
|
||||
// here, mainly so as to mask the differences between
|
||||
// struct-like enums and so forth.
|
||||
for &ast_variant in enum_definition.variants.iter() {
|
||||
for ast_variant in enum_definition.variants.iter() {
|
||||
let variant =
|
||||
ty::VariantInfo::from_ast_variant(tcx,
|
||||
ast_variant,
|
||||
&**ast_variant,
|
||||
/*discriminant*/ 0);
|
||||
for &arg_ty in variant.args.iter() {
|
||||
self.add_constraints_from_ty(arg_ty, self.covariant);
|
||||
for arg_ty in variant.args.iter() {
|
||||
self.add_constraints_from_ty(*arg_ty, self.covariant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,6 @@ pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
|
||||
p: p,
|
||||
flag: false,
|
||||
};
|
||||
visit::walk_block(&mut v, b, ());
|
||||
visit::walk_block(&mut v, &*b, ());
|
||||
return v.flag;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use middle::ty;
|
||||
use middle::typeck;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::string::String;
|
||||
use std::gc::Gc;
|
||||
use syntax::abi;
|
||||
use syntax::ast_map;
|
||||
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 {
|
||||
(&**self).repr(tcx)
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ use rustc::middle::ty;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::u32;
|
||||
use std::gc::Gc;
|
||||
|
||||
use core;
|
||||
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 {
|
||||
(**self).clean()
|
||||
}
|
||||
@ -428,12 +429,12 @@ impl attr::AttrMetaMethods for Attribute {
|
||||
_ => 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 {
|
||||
fn name(&self) -> InternedString { (**self).name() }
|
||||
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)]
|
||||
@ -864,7 +865,7 @@ pub struct Argument {
|
||||
impl Clean<Argument> for ast::Arg {
|
||||
fn clean(&self) -> Argument {
|
||||
Argument {
|
||||
name: name_from_pat(self.pat),
|
||||
name: name_from_pat(&*self.pat),
|
||||
type_: (self.ty.clean()),
|
||||
id: self.id
|
||||
}
|
||||
@ -1745,7 +1746,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
|
||||
remaining,
|
||||
b.clone());
|
||||
let path = syntax::codemap::dummy_spanned(path);
|
||||
ret.push(convert(&ast::ViewItemUse(@path)));
|
||||
ret.push(convert(&ast::ViewItemUse(box(GC) path)));
|
||||
}
|
||||
}
|
||||
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, \
|
||||
which is not allowed in function arguments"),
|
||||
PatTup(..) => "(tuple arg NYI)".to_string(),
|
||||
PatBox(p) => name_from_pat(p),
|
||||
PatRegion(p) => name_from_pat(p),
|
||||
PatBox(p) => name_from_pat(&*p),
|
||||
PatRegion(p) => name_from_pat(&*p),
|
||||
PatLit(..) => {
|
||||
warn!("tried to get argument name from PatLit, \
|
||||
which is silly in function arguments");
|
||||
|
@ -95,7 +95,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
|
||||
let mut cfg = build_configuration(&sess);
|
||||
for cfg_ in cfgs.move_iter() {
|
||||
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);
|
||||
@ -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)
|
||||
-> (clean::Crate, CrateAnalysis) {
|
||||
let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs);
|
||||
let ctxt = @ctxt;
|
||||
let ctxt = box(GC) ctxt;
|
||||
super::ctxtkey.replace(Some(ctxt));
|
||||
|
||||
let krate = {
|
||||
let mut v = RustdocVisitor::new(ctxt, Some(&analysis));
|
||||
let mut v = RustdocVisitor::new(&*ctxt, Some(&analysis));
|
||||
v.visit(&ctxt.krate);
|
||||
v.clean()
|
||||
};
|
||||
|
@ -16,6 +16,8 @@ use syntax::codemap::Span;
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Ident, NodeId};
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub struct Module {
|
||||
pub name: Option<Ident>,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
@ -133,7 +135,7 @@ pub struct Typedef {
|
||||
pub struct Static {
|
||||
pub type_: ast::P<ast::Ty>,
|
||||
pub mutability: ast::Mutability,
|
||||
pub expr: @ast::Expr,
|
||||
pub expr: Gc<ast::Expr>,
|
||||
pub name: Ident,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub vis: ast::Visibility,
|
||||
@ -156,7 +158,7 @@ pub struct Impl {
|
||||
pub generics: ast::Generics,
|
||||
pub trait_: Option<ast::TraitRef>,
|
||||
pub for_: ast::P<ast::Ty>,
|
||||
pub methods: Vec<@ast::Method>,
|
||||
pub methods: Vec<Gc<ast::Method>>,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub where: Span,
|
||||
pub vis: ast::Visibility,
|
||||
|
@ -37,6 +37,7 @@ extern crate log;
|
||||
use std::io;
|
||||
use std::io::{File, MemWriter};
|
||||
use std::str;
|
||||
use std::gc::Gc;
|
||||
use serialize::{json, Decodable, Encodable};
|
||||
|
||||
// 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",
|
||||
];
|
||||
|
||||
local_data_key!(pub ctxtkey: @core::DocContext)
|
||||
local_data_key!(pub ctxtkey: Gc<core::DocContext>)
|
||||
local_data_key!(pub analysiskey: core::CrateAnalysis)
|
||||
|
||||
type Output = (clean::Crate, Vec<plugins::PluginJson> );
|
||||
|
@ -64,13 +64,13 @@ pub fn run(input: &str,
|
||||
let mut cfg = config::build_configuration(&sess);
|
||||
cfg.extend(cfgs.move_iter().map(|cfg_| {
|
||||
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_2_configure_and_expand(&sess, krate,
|
||||
&from_str("rustdoc-test").unwrap());
|
||||
|
||||
let ctx = @core::DocContext {
|
||||
let ctx = box(GC) core::DocContext {
|
||||
krate: krate,
|
||||
maybe_typed: core::NotTyped(sess),
|
||||
src: input_path,
|
||||
@ -82,7 +82,7 @@ pub fn run(input: &str,
|
||||
};
|
||||
super::ctxtkey.replace(Some(ctx));
|
||||
|
||||
let mut v = RustdocVisitor::new(ctx, None);
|
||||
let mut v = RustdocVisitor::new(&*ctx, None);
|
||||
v.visit(&ctx.krate);
|
||||
let krate = v.clean();
|
||||
let (krate, _) = passes::unindent_comments(krate);
|
||||
|
@ -18,6 +18,8 @@ use syntax::ast_map;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
use core;
|
||||
use doctree::*;
|
||||
|
||||
@ -54,10 +56,10 @@ impl<'a> RustdocVisitor<'a> {
|
||||
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 {
|
||||
debug!("Visiting struct");
|
||||
let struct_type = struct_type_from_def(sd);
|
||||
let struct_type = struct_type_from_def(&*sd);
|
||||
Struct {
|
||||
id: item.id,
|
||||
struct_type: struct_type,
|
||||
@ -125,7 +127,7 @@ impl<'a> RustdocVisitor<'a> {
|
||||
om.vis = vis;
|
||||
om.id = id;
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(*i, &mut om);
|
||||
self.visit_item(&**i, &mut om);
|
||||
}
|
||||
om
|
||||
}
|
||||
@ -159,9 +161,9 @@ impl<'a> RustdocVisitor<'a> {
|
||||
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,
|
||||
please_inline: bool) -> Option<@ast::ViewPath> {
|
||||
please_inline: bool) -> Option<Gc<ast::ViewPath>> {
|
||||
match path.node {
|
||||
ast::ViewPathSimple(_, _, id) => {
|
||||
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 }
|
||||
return Some(@::syntax::codemap::Spanned {
|
||||
return Some(box(GC) ::syntax::codemap::Spanned {
|
||||
node: ast::ViewPathList(p.clone(), mine, b.clone()),
|
||||
span: path.span,
|
||||
})
|
||||
@ -213,13 +215,13 @@ impl<'a> RustdocVisitor<'a> {
|
||||
self.visit_view_item(vi, om);
|
||||
}
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(*i, om);
|
||||
self.visit_item(&**i, om);
|
||||
}
|
||||
}
|
||||
_ => { fail!("glob not mapped to a module"); }
|
||||
}
|
||||
} else {
|
||||
self.visit_item(it, om);
|
||||
self.visit_item(&*it, om);
|
||||
}
|
||||
true
|
||||
}
|
||||
@ -245,8 +247,8 @@ impl<'a> RustdocVisitor<'a> {
|
||||
om.enums.push(self.visit_enum_def(item, ed, gen)),
|
||||
ast::ItemStruct(sd, ref gen) =>
|
||||
om.structs.push(self.visit_struct_def(item, sd, gen)),
|
||||
ast::ItemFn(fd, ref pur, ref abi, ref gen, _) =>
|
||||
om.fns.push(self.visit_fn(item, fd, pur, abi, gen)),
|
||||
ast::ItemFn(ref fd, ref pur, ref abi, ref gen, _) =>
|
||||
om.fns.push(self.visit_fn(item, &**fd, pur, abi, gen)),
|
||||
ast::ItemTy(ty, ref gen) => {
|
||||
let t = Typedef {
|
||||
ty: ty,
|
||||
|
@ -16,6 +16,7 @@ Core encoding and decoding interfaces.
|
||||
|
||||
use std::path;
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
|
||||
pub trait Encoder<E> {
|
||||
// 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> {
|
||||
(**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 {
|
||||
fn decode(d: &mut D) -> Result<@T, E> {
|
||||
Ok(@try!(Decodable::decode(d)))
|
||||
impl<E, D:Decoder<E>,T:Decodable<D, E> + 'static> Decodable<D, E> for Gc<T> {
|
||||
fn decode(d: &mut D) -> Result<Gc<T>, E> {
|
||||
Ok(box(GC) try!(Decodable::decode(d)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,52 +18,32 @@ collector is task-local so `Gc<T>` is not sendable.
|
||||
|
||||
#![allow(experimental)]
|
||||
|
||||
use kinds::marker;
|
||||
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
|
||||
#[lang="gc"]
|
||||
#[cfg(not(test))]
|
||||
#[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>` \
|
||||
with a non-owning `Weak<T>` pointer. A tracing garbage collector is planned."]
|
||||
pub struct Gc<T> {
|
||||
#[cfg(stage0)]
|
||||
ptr: @T,
|
||||
#[cfg(not(stage0))]
|
||||
_ptr: *T,
|
||||
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> {
|
||||
/// Clone the pointer only
|
||||
#[inline]
|
||||
fn clone(&self) -> Gc<T> {
|
||||
Gc{ ptr: self.ptr, marker: marker::NoSend }
|
||||
}
|
||||
fn clone(&self) -> Gc<T> { *self }
|
||||
}
|
||||
|
||||
/// An value that represents the task-local managed heap.
|
||||
@ -73,8 +53,54 @@ impl<T> Clone for Gc<T> {
|
||||
#[cfg(not(test))]
|
||||
pub static GC: () = ();
|
||||
|
||||
#[cfg(test)]
|
||||
pub static GC: () = ();
|
||||
impl<T: PartialEq + 'static> PartialEq for Gc<T> {
|
||||
#[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)]
|
||||
mod tests {
|
||||
|
@ -135,6 +135,8 @@ extern crate rustrt;
|
||||
#[cfg(test)] pub use realstd::ops;
|
||||
#[cfg(test)] pub use realstd::cmp;
|
||||
#[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
|
||||
@ -219,6 +221,7 @@ pub mod rand;
|
||||
|
||||
pub mod ascii;
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub mod gc;
|
||||
|
||||
/* Common traits */
|
||||
|
@ -21,15 +21,16 @@ use std::fmt;
|
||||
use std::fmt::Show;
|
||||
use std::option::Option;
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
|
||||
/// 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)]
|
||||
/// Construct a P<T> from a T value.
|
||||
pub fn P<T: 'static>(value: T) -> P<T> {
|
||||
@value
|
||||
box(GC) value
|
||||
}
|
||||
|
||||
// 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,
|
||||
// used to drive conditional compilation
|
||||
pub type CrateConfig = Vec<@MetaItem> ;
|
||||
pub type CrateConfig = Vec<Gc<MetaItem>>;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Crate {
|
||||
@ -232,7 +233,7 @@ pub type MetaItem = Spanned<MetaItem_>;
|
||||
#[deriving(Clone, Encodable, Decodable, Eq, Hash)]
|
||||
pub enum MetaItem_ {
|
||||
MetaWord(InternedString),
|
||||
MetaList(InternedString, Vec<@MetaItem> ),
|
||||
MetaList(InternedString, Vec<Gc<MetaItem>>),
|
||||
MetaNameValue(InternedString, Lit),
|
||||
}
|
||||
|
||||
@ -264,8 +265,8 @@ impl PartialEq for MetaItem_ {
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Block {
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub stmts: Vec<@Stmt>,
|
||||
pub expr: Option<@Expr>,
|
||||
pub stmts: Vec<Gc<Stmt>>,
|
||||
pub expr: Option<Gc<Expr>>,
|
||||
pub id: NodeId,
|
||||
pub rules: BlockCheckMode,
|
||||
pub span: Span,
|
||||
@ -281,7 +282,7 @@ pub struct Pat {
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct FieldPat {
|
||||
pub ident: Ident,
|
||||
pub pat: @Pat,
|
||||
pub pat: Gc<Pat>,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
@ -301,18 +302,18 @@ pub enum Pat_ {
|
||||
// which it is. The resolver determines this, and
|
||||
// records this pattern's NodeId in an auxiliary
|
||||
// set (of "pat_idents that refer to nullary enums")
|
||||
PatIdent(BindingMode, Path, Option<@Pat>),
|
||||
PatEnum(Path, Option<Vec<@Pat> >), /* "none" means a * pattern where
|
||||
PatIdent(BindingMode, Path, Option<Gc<Pat>>),
|
||||
PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
|
||||
* we don't bind the fields to names */
|
||||
PatStruct(Path, Vec<FieldPat> , bool),
|
||||
PatTup(Vec<@Pat> ),
|
||||
PatBox(@Pat),
|
||||
PatRegion(@Pat), // reference pattern
|
||||
PatLit(@Expr),
|
||||
PatRange(@Expr, @Expr),
|
||||
PatStruct(Path, Vec<FieldPat>, bool),
|
||||
PatTup(Vec<Gc<Pat>>),
|
||||
PatBox(Gc<Pat>),
|
||||
PatRegion(Gc<Pat>), // reference pattern
|
||||
PatLit(Gc<Expr>),
|
||||
PatRange(Gc<Expr>, Gc<Expr>),
|
||||
// [a, b, ..i, y, z] is represented as
|
||||
// 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),
|
||||
}
|
||||
|
||||
@ -365,13 +366,13 @@ pub type Stmt = Spanned<Stmt_>;
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Stmt_ {
|
||||
// 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):
|
||||
StmtExpr(@Expr, NodeId),
|
||||
StmtExpr(Gc<Expr>, NodeId),
|
||||
|
||||
// expr with trailing semi-colon (may have any type):
|
||||
StmtSemi(@Expr, NodeId),
|
||||
StmtSemi(Gc<Expr>, NodeId),
|
||||
|
||||
// bool: is there a trailing sem-colon?
|
||||
StmtMac(Mac, bool),
|
||||
@ -391,8 +392,8 @@ pub enum LocalSource {
|
||||
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Local {
|
||||
pub ty: P<Ty>,
|
||||
pub pat: @Pat,
|
||||
pub init: Option<@Expr>,
|
||||
pub pat: Gc<Pat>,
|
||||
pub init: Option<Gc<Expr>>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub source: LocalSource,
|
||||
@ -403,23 +404,23 @@ pub type Decl = Spanned<Decl_>;
|
||||
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Decl_ {
|
||||
// a local (let) binding:
|
||||
DeclLocal(@Local),
|
||||
DeclLocal(Gc<Local>),
|
||||
// an item binding:
|
||||
DeclItem(@Item),
|
||||
DeclItem(Gc<Item>),
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Arm {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub pats: Vec<@Pat>,
|
||||
pub guard: Option<@Expr>,
|
||||
pub body: @Expr,
|
||||
pub pats: Vec<Gc<Pat>>,
|
||||
pub guard: Option<Gc<Expr>>,
|
||||
pub body: Gc<Expr>,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Field {
|
||||
pub ident: SpannedIdent,
|
||||
pub expr: @Expr,
|
||||
pub expr: Gc<Expr>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
@ -446,56 +447,56 @@ pub struct Expr {
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Expr_ {
|
||||
ExprVstore(@Expr, ExprVstore),
|
||||
ExprVstore(Gc<Expr>, ExprVstore),
|
||||
// First expr is the place; second expr is the value.
|
||||
ExprBox(@Expr, @Expr),
|
||||
ExprVec(Vec<@Expr>),
|
||||
ExprCall(@Expr, Vec<@Expr>),
|
||||
ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<@Expr>),
|
||||
ExprTup(Vec<@Expr>),
|
||||
ExprBinary(BinOp, @Expr, @Expr),
|
||||
ExprUnary(UnOp, @Expr),
|
||||
ExprLit(@Lit),
|
||||
ExprCast(@Expr, P<Ty>),
|
||||
ExprIf(@Expr, P<Block>, Option<@Expr>),
|
||||
ExprWhile(@Expr, P<Block>),
|
||||
ExprBox(Gc<Expr>, Gc<Expr>),
|
||||
ExprVec(Vec<Gc<Expr>>),
|
||||
ExprCall(Gc<Expr>, Vec<Gc<Expr>>),
|
||||
ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<Gc<Expr>>),
|
||||
ExprTup(Vec<Gc<Expr>>),
|
||||
ExprBinary(BinOp, Gc<Expr>, Gc<Expr>),
|
||||
ExprUnary(UnOp, Gc<Expr>),
|
||||
ExprLit(Gc<Lit>),
|
||||
ExprCast(Gc<Expr>, P<Ty>),
|
||||
ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
|
||||
ExprWhile(Gc<Expr>, P<Block>),
|
||||
// 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)
|
||||
// FIXME #6993: change to Option<Name>
|
||||
ExprLoop(P<Block>, Option<Ident>),
|
||||
ExprMatch(@Expr, Vec<Arm>),
|
||||
ExprMatch(Gc<Expr>, Vec<Arm>),
|
||||
ExprFnBlock(P<FnDecl>, P<Block>),
|
||||
ExprProc(P<FnDecl>, P<Block>),
|
||||
ExprBlock(P<Block>),
|
||||
|
||||
ExprAssign(@Expr, @Expr),
|
||||
ExprAssignOp(BinOp, @Expr, @Expr),
|
||||
ExprField(@Expr, Ident, Vec<P<Ty>>),
|
||||
ExprIndex(@Expr, @Expr),
|
||||
ExprAssign(Gc<Expr>, Gc<Expr>),
|
||||
ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
|
||||
ExprField(Gc<Expr>, Ident, Vec<P<Ty>>),
|
||||
ExprIndex(Gc<Expr>, Gc<Expr>),
|
||||
|
||||
/// Expression that looks like a "name". For example,
|
||||
/// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
|
||||
/// of a function call.
|
||||
ExprPath(Path),
|
||||
|
||||
ExprAddrOf(Mutability, @Expr),
|
||||
ExprAddrOf(Mutability, Gc<Expr>),
|
||||
ExprBreak(Option<Ident>),
|
||||
ExprAgain(Option<Ident>),
|
||||
ExprRet(Option<@Expr>),
|
||||
ExprRet(Option<Gc<Expr>>),
|
||||
|
||||
ExprInlineAsm(InlineAsm),
|
||||
|
||||
ExprMac(Mac),
|
||||
|
||||
// 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.
|
||||
ExprRepeat(@Expr /* element */, @Expr /* count */),
|
||||
ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
|
||||
|
||||
// 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
|
||||
@ -667,7 +668,7 @@ pub struct TypeMethod {
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum TraitMethod {
|
||||
Required(TypeMethod),
|
||||
Provided(@Method),
|
||||
Provided(Gc<Method>),
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
@ -782,16 +783,16 @@ pub enum Ty_ {
|
||||
TyBox(P<Ty>),
|
||||
TyUniq(P<Ty>),
|
||||
TyVec(P<Ty>),
|
||||
TyFixedLengthVec(P<Ty>, @Expr),
|
||||
TyFixedLengthVec(P<Ty>, Gc<Expr>),
|
||||
TyPtr(MutTy),
|
||||
TyRptr(Option<Lifetime>, MutTy),
|
||||
TyClosure(@ClosureTy, Option<Lifetime>),
|
||||
TyProc(@ClosureTy),
|
||||
TyBareFn(@BareFnTy),
|
||||
TyUnboxedFn(@UnboxedFnTy),
|
||||
TyClosure(Gc<ClosureTy>, Option<Lifetime>),
|
||||
TyProc(Gc<ClosureTy>),
|
||||
TyBareFn(Gc<BareFnTy>),
|
||||
TyUnboxedFn(Gc<UnboxedFnTy>),
|
||||
TyTup(Vec<P<Ty>> ),
|
||||
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
|
||||
// specified. This can appear anywhere in a type.
|
||||
TyInfer,
|
||||
@ -808,8 +809,8 @@ pub struct InlineAsm {
|
||||
pub asm: InternedString,
|
||||
pub asm_str_style: StrStyle,
|
||||
pub clobbers: InternedString,
|
||||
pub inputs: Vec<(InternedString, @Expr)>,
|
||||
pub outputs: Vec<(InternedString, @Expr)>,
|
||||
pub inputs: Vec<(InternedString, Gc<Expr>)>,
|
||||
pub outputs: Vec<(InternedString, Gc<Expr>)>,
|
||||
pub volatile: bool,
|
||||
pub alignstack: bool,
|
||||
pub dialect: AsmDialect
|
||||
@ -818,7 +819,7 @@ pub struct InlineAsm {
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Arg {
|
||||
pub ty: P<Ty>,
|
||||
pub pat: @Pat,
|
||||
pub pat: Gc<Pat>,
|
||||
pub id: NodeId,
|
||||
}
|
||||
|
||||
@ -832,7 +833,7 @@ impl Arg {
|
||||
node: TyInfer,
|
||||
span: DUMMY_SP,
|
||||
}),
|
||||
pat: @Pat {
|
||||
pat: box(GC) Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatIdent(BindByValue(mutability), path, None),
|
||||
span: span
|
||||
@ -903,14 +904,14 @@ pub struct Mod {
|
||||
/// to the last token in the external file.
|
||||
pub inner: Span,
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub items: Vec<@Item>,
|
||||
pub items: Vec<Gc<Item>>,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct ForeignMod {
|
||||
pub abi: Abi,
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub items: Vec<@ForeignItem>,
|
||||
pub items: Vec<Gc<ForeignItem>>,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
@ -922,7 +923,7 @@ pub struct VariantArg {
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum VariantKind {
|
||||
TupleVariantKind(Vec<VariantArg>),
|
||||
StructVariantKind(@StructDef),
|
||||
StructVariantKind(Gc<StructDef>),
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
@ -936,7 +937,7 @@ pub struct Variant_ {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub kind: VariantKind,
|
||||
pub id: NodeId,
|
||||
pub disr_expr: Option<@Expr>,
|
||||
pub disr_expr: Option<Gc<Expr>>,
|
||||
pub vis: Visibility,
|
||||
}
|
||||
|
||||
@ -984,7 +985,7 @@ pub enum ViewItem_ {
|
||||
// (containing arbitrary characters) from which to fetch the crate sources
|
||||
// For example, extern crate whatever = "github.com/mozilla/rust"
|
||||
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
|
||||
ViewItemUse(@ViewPath),
|
||||
ViewItemUse(Gc<ViewPath>),
|
||||
}
|
||||
|
||||
// Meta-data associated with an item
|
||||
@ -1007,7 +1008,7 @@ pub struct AttrId(pub uint);
|
||||
pub struct Attribute_ {
|
||||
pub id: AttrId,
|
||||
pub style: AttrStyle,
|
||||
pub value: @MetaItem,
|
||||
pub value: Gc<MetaItem>,
|
||||
pub is_sugared_doc: bool,
|
||||
}
|
||||
|
||||
@ -1105,18 +1106,18 @@ pub struct Item {
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Item_ {
|
||||
ItemStatic(P<Ty>, Mutability, @Expr),
|
||||
ItemStatic(P<Ty>, Mutability, Gc<Expr>),
|
||||
ItemFn(P<FnDecl>, FnStyle, Abi, Generics, P<Block>),
|
||||
ItemMod(Mod),
|
||||
ItemForeignMod(ForeignMod),
|
||||
ItemTy(P<Ty>, Generics),
|
||||
ItemEnum(EnumDef, Generics),
|
||||
ItemStruct(@StructDef, Generics),
|
||||
ItemStruct(Gc<StructDef>, Generics),
|
||||
ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
|
||||
ItemImpl(Generics,
|
||||
Option<TraitRef>, // (optional) trait this impl implements
|
||||
P<Ty>, // self
|
||||
Vec<@Method> ),
|
||||
Vec<Gc<Method>>),
|
||||
// a macro invocation (which includes macro definition)
|
||||
ItemMac(Mac),
|
||||
}
|
||||
@ -1142,9 +1143,9 @@ pub enum ForeignItem_ {
|
||||
// that we trans.
|
||||
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum InlinedItem {
|
||||
IIItem(@Item),
|
||||
IIMethod(DefId /* impl id */, bool /* is provided */, @Method),
|
||||
IIForeign(@ForeignItem),
|
||||
IIItem(Gc<Item>),
|
||||
IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
|
||||
IIForeign(Gc<ForeignItem>),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -20,9 +20,9 @@ use util::small_vector::SmallVector;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::gc::Gc;
|
||||
use std::iter;
|
||||
use std::slice;
|
||||
use std::string::String;
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
pub enum PathElem {
|
||||
@ -94,22 +94,22 @@ pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> String {
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub enum Node {
|
||||
NodeItem(@Item),
|
||||
NodeForeignItem(@ForeignItem),
|
||||
NodeTraitMethod(@TraitMethod),
|
||||
NodeMethod(@Method),
|
||||
NodeItem(Gc<Item>),
|
||||
NodeForeignItem(Gc<ForeignItem>),
|
||||
NodeTraitMethod(Gc<TraitMethod>),
|
||||
NodeMethod(Gc<Method>),
|
||||
NodeVariant(P<Variant>),
|
||||
NodeExpr(@Expr),
|
||||
NodeStmt(@Stmt),
|
||||
NodeArg(@Pat),
|
||||
NodeLocal(@Pat),
|
||||
NodePat(@Pat),
|
||||
NodeExpr(Gc<Expr>),
|
||||
NodeStmt(Gc<Stmt>),
|
||||
NodeArg(Gc<Pat>),
|
||||
NodeLocal(Gc<Pat>),
|
||||
NodePat(Gc<Pat>),
|
||||
NodeBlock(P<Block>),
|
||||
|
||||
/// 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.
|
||||
@ -119,19 +119,19 @@ enum MapEntry {
|
||||
NotPresent,
|
||||
|
||||
// All the node types, with a parent ID.
|
||||
EntryItem(NodeId, @Item),
|
||||
EntryForeignItem(NodeId, @ForeignItem),
|
||||
EntryTraitMethod(NodeId, @TraitMethod),
|
||||
EntryMethod(NodeId, @Method),
|
||||
EntryItem(NodeId, Gc<Item>),
|
||||
EntryForeignItem(NodeId, Gc<ForeignItem>),
|
||||
EntryTraitMethod(NodeId, Gc<TraitMethod>),
|
||||
EntryMethod(NodeId, Gc<Method>),
|
||||
EntryVariant(NodeId, P<Variant>),
|
||||
EntryExpr(NodeId, @Expr),
|
||||
EntryStmt(NodeId, @Stmt),
|
||||
EntryArg(NodeId, @Pat),
|
||||
EntryLocal(NodeId, @Pat),
|
||||
EntryPat(NodeId, @Pat),
|
||||
EntryExpr(NodeId, Gc<Expr>),
|
||||
EntryStmt(NodeId, Gc<Stmt>),
|
||||
EntryArg(NodeId, Gc<Pat>),
|
||||
EntryLocal(NodeId, Gc<Pat>),
|
||||
EntryPat(NodeId, Gc<Pat>),
|
||||
EntryBlock(NodeId, P<Block>),
|
||||
EntryStructCtor(NodeId, @StructDef),
|
||||
EntryLifetime(NodeId, @Lifetime),
|
||||
EntryStructCtor(NodeId, Gc<StructDef>),
|
||||
EntryLifetime(NodeId, Gc<Lifetime>),
|
||||
|
||||
// Roots for node trees.
|
||||
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) {
|
||||
Some(NodeItem(item)) => item,
|
||||
_ => 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) {
|
||||
Some(NodeItem(i)) => {
|
||||
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) {
|
||||
Some(NodeForeignItem(item)) => item,
|
||||
_ => 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)
|
||||
}
|
||||
|
||||
fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
|
||||
fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
|
||||
let parent = self.parent;
|
||||
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);
|
||||
|
||||
match i.node {
|
||||
@ -476,16 +476,17 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
}
|
||||
}
|
||||
ItemForeignMod(ref nm) => {
|
||||
for &nitem in nm.items.iter() {
|
||||
self.insert(nitem.id, EntryForeignItem(self.parent, nitem));
|
||||
for nitem in nm.items.iter() {
|
||||
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.
|
||||
match struct_def.ctor_id {
|
||||
Some(ctor_id) => {
|
||||
self.insert(ctor_id, EntryStructCtor(self.parent,
|
||||
struct_def));
|
||||
struct_def.clone()));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
@ -499,11 +500,11 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
match *tm {
|
||||
Required(ref m) => {
|
||||
self.insert(m.id, EntryTraitMethod(self.parent,
|
||||
@(*tm).clone()));
|
||||
box(GC) (*tm).clone()));
|
||||
}
|
||||
Provided(m) => {
|
||||
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)
|
||||
}
|
||||
|
||||
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);
|
||||
match pat.node {
|
||||
PatIdent(..) => {
|
||||
@ -532,7 +533,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
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);
|
||||
|
||||
self.insert(expr.id, EntryExpr(self.parent, expr));
|
||||
@ -540,9 +541,9 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
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");
|
||||
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)
|
||||
}
|
||||
|
||||
@ -555,10 +556,10 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
m
|
||||
}
|
||||
|
||||
fn fold_method(&mut self, m: @Method) -> @Method {
|
||||
fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
|
||||
let parent = self.parent;
|
||||
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);
|
||||
self.parent = parent;
|
||||
m
|
||||
@ -580,7 +581,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
|
||||
fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -643,7 +644,7 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
|
||||
IIItem(_) => {}
|
||||
IIMethod(impl_did, is_provided, m) => {
|
||||
let entry = if is_provided {
|
||||
EntryTraitMethod(cx.parent, @Provided(m))
|
||||
EntryTraitMethod(cx.parent, box(GC) Provided(m))
|
||||
} else {
|
||||
EntryMethod(cx.parent, m)
|
||||
};
|
||||
@ -701,28 +702,28 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
|
||||
token::get_ident(variant.node.name),
|
||||
map.path_to_str(id), id)).to_string()
|
||||
}
|
||||
Some(NodeExpr(expr)) => {
|
||||
Some(NodeExpr(ref expr)) => {
|
||||
(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={})",
|
||||
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={})",
|
||||
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={})",
|
||||
pprust::pat_to_str(pat), id)).to_string()
|
||||
pprust::pat_to_str(&**pat), id)).to_string()
|
||||
}
|
||||
Some(NodePat(pat)) => {
|
||||
(format!("pat {} (id={})", pprust::pat_to_str(pat), id)).to_string()
|
||||
Some(NodePat(ref pat)) => {
|
||||
(format!("pat {} (id={})", pprust::pat_to_str(&**pat), id)).to_string()
|
||||
}
|
||||
Some(NodeBlock(block)) => {
|
||||
Some(NodeBlock(ref block)) => {
|
||||
(format!("block {} (id={})",
|
||||
pprust::block_to_str(block), id)).to_string()
|
||||
pprust::block_to_str(&**block), id)).to_string()
|
||||
}
|
||||
Some(NodeStructCtor(_)) => {
|
||||
(format!("struct_ctor {} (id={})",
|
||||
@ -730,7 +731,7 @@ fn node_id_to_str(map: &Map, id: NodeId) -> String {
|
||||
}
|
||||
Some(NodeLifetime(ref l)) => {
|
||||
(format!("lifetime {} (id={})",
|
||||
pprust::lifetime_to_str(*l), id)).to_string()
|
||||
pprust::lifetime_to_str(&**l), id)).to_string()
|
||||
}
|
||||
None => {
|
||||
(format!("unknown node (id={})", id)).to_string()
|
||||
|
@ -21,7 +21,7 @@ use visit;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp;
|
||||
use std::string::String;
|
||||
use std::gc::Gc;
|
||||
use std::u32;
|
||||
|
||||
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 {
|
||||
match op {
|
||||
UnBox => "@",
|
||||
UnBox => "box(GC) ",
|
||||
UnUniq => "box() ",
|
||||
UnDeref => "*",
|
||||
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 };
|
||||
}
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
pub fn block_from_expr(e: @Expr) -> P<Block> {
|
||||
pub fn block_from_expr(e: Gc<Expr>) -> P<Block> {
|
||||
P(Block {
|
||||
view_items: 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 {
|
||||
@ast::Pat { id: id,
|
||||
pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> Gc<Pat> {
|
||||
box(GC) ast::Pat { id: id,
|
||||
node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None),
|
||||
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) {
|
||||
Some(/* FIXME (#2543) */ a.pats.clone())
|
||||
} else {
|
||||
@ -254,7 +254,7 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
|
||||
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| {
|
||||
match m.vis {
|
||||
Public => true,
|
||||
@ -285,7 +285,7 @@ pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
|
||||
}
|
||||
|
||||
pub fn split_trait_methods(trait_methods: &[TraitMethod])
|
||||
-> (Vec<TypeMethod> , Vec<@Method> ) {
|
||||
-> (Vec<TypeMethod> , Vec<Gc<Method>> ) {
|
||||
let mut reqd = Vec::new();
|
||||
let mut provd = Vec::new();
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn is_item_impl(item: @ast::Item) -> bool {
|
||||
pub fn is_item_impl(item: Gc<ast::Item>) -> bool {
|
||||
match item.node {
|
||||
ItemImpl(..) => true,
|
||||
_ => false
|
||||
@ -623,20 +623,20 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
|
||||
}
|
||||
|
||||
match pat.node {
|
||||
PatIdent(_, _, Some(p)) => walk_pat(p, it),
|
||||
PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
|
||||
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) => {
|
||||
s.iter().advance(|&p| walk_pat(p, |p| it(p)))
|
||||
s.iter().advance(|p| walk_pat(&**p, |p| it(p)))
|
||||
}
|
||||
PatBox(s) | PatRegion(s) => {
|
||||
walk_pat(s, it)
|
||||
PatBox(ref s) | PatRegion(ref s) => {
|
||||
walk_pat(&**s, it)
|
||||
}
|
||||
PatVec(ref before, ref slice, ref after) => {
|
||||
before.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)))
|
||||
before.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)))
|
||||
}
|
||||
PatMac(_) => fail!("attempted to analyze unexpanded pattern"),
|
||||
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
|
||||
/// 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 {
|
||||
ast::PatIdent(..) => true,
|
||||
_ => 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.
|
||||
pub fn lit_is_str(lit: @Lit) -> bool {
|
||||
pub fn lit_is_str(lit: Gc<Lit>) -> bool {
|
||||
match lit.node {
|
||||
LitStr(..) => true,
|
||||
_ => false,
|
||||
|
@ -22,6 +22,7 @@ use crateid::CrateId;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::BitvSet;
|
||||
use std::gc::Gc;
|
||||
|
||||
local_data_key!(used_attrs: BitvSet)
|
||||
|
||||
@ -52,7 +53,7 @@ pub trait AttrMetaMethods {
|
||||
*/
|
||||
fn value_str(&self) -> Option<InternedString>;
|
||||
/// 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 {
|
||||
@ -67,7 +68,7 @@ impl AttrMetaMethods for Attribute {
|
||||
fn value_str(&self) -> Option<InternedString> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
MetaList(_, ref l) => Some(l.as_slice()),
|
||||
_ => None
|
||||
@ -102,23 +103,23 @@ impl AttrMetaMethods for MetaItem {
|
||||
}
|
||||
|
||||
// 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 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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait AttributeMethods {
|
||||
fn meta(&self) -> @MetaItem;
|
||||
fn meta(&self) -> Gc<MetaItem>;
|
||||
fn desugar_doc(&self) -> Attribute;
|
||||
}
|
||||
|
||||
impl AttributeMethods for Attribute {
|
||||
/// Extract the MetaItem from inside this Attribute.
|
||||
fn meta(&self) -> @MetaItem {
|
||||
fn meta(&self) -> Gc<MetaItem> {
|
||||
self.node.value
|
||||
}
|
||||
|
||||
@ -146,22 +147,23 @@ impl AttributeMethods for Attribute {
|
||||
/* Constructors */
|
||||
|
||||
pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
|
||||
-> @MetaItem {
|
||||
-> Gc<MetaItem> {
|
||||
let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr));
|
||||
mk_name_value_item(name, value_lit)
|
||||
}
|
||||
|
||||
pub fn mk_name_value_item(name: InternedString, value: ast::Lit)
|
||||
-> @MetaItem {
|
||||
@dummy_spanned(MetaNameValue(name, value))
|
||||
-> Gc<MetaItem> {
|
||||
box(GC) dummy_spanned(MetaNameValue(name, value))
|
||||
}
|
||||
|
||||
pub fn mk_list_item(name: InternedString, items: Vec<@MetaItem> ) -> @MetaItem {
|
||||
@dummy_spanned(MetaList(name, items))
|
||||
pub fn mk_list_item(name: InternedString,
|
||||
items: Vec<Gc<MetaItem>>) -> Gc<MetaItem> {
|
||||
box(GC) dummy_spanned(MetaList(name, items))
|
||||
}
|
||||
|
||||
pub fn mk_word_item(name: InternedString) -> @MetaItem {
|
||||
@dummy_spanned(MetaWord(name))
|
||||
pub fn mk_word_item(name: InternedString) -> Gc<MetaItem> {
|
||||
box(GC) dummy_spanned(MetaWord(name))
|
||||
}
|
||||
|
||||
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.
|
||||
pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute {
|
||||
pub fn mk_attr_inner(id: AttrId, item: Gc<MetaItem>) -> Attribute {
|
||||
dummy_spanned(Attribute_ {
|
||||
id: id,
|
||||
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.
|
||||
pub fn mk_attr_outer(id: AttrId, item: @MetaItem) -> Attribute {
|
||||
pub fn mk_attr_outer(id: AttrId, item: Gc<MetaItem>) -> Attribute {
|
||||
dummy_spanned(Attribute_ {
|
||||
id: id,
|
||||
style: ast::AttrOuter,
|
||||
@ -200,7 +202,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
|
||||
let attr = Attribute_ {
|
||||
id: id,
|
||||
style: style,
|
||||
value: @spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
|
||||
value: box(GC) spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
|
||||
lit)),
|
||||
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
|
||||
/// comparison. This is slightly subtle, and relies on ignoring the
|
||||
/// span included in the `==` comparison a plain MetaItem.
|
||||
pub fn contains(haystack: &[@ast::MetaItem],
|
||||
needle: @ast::MetaItem) -> bool {
|
||||
pub fn contains(haystack: &[Gc<ast::MetaItem>],
|
||||
needle: Gc<ast::MetaItem>) -> bool {
|
||||
debug!("attr::contains (name={})", needle.name());
|
||||
haystack.iter().any(|item| {
|
||||
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())
|
||||
}
|
||||
|
||||
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> {
|
||||
items.iter()
|
||||
.rev()
|
||||
@ -245,12 +247,12 @@ pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str)
|
||||
|
||||
/* 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
|
||||
// human-readable strings.
|
||||
let mut v = items.iter()
|
||||
.map(|&mi| (mi.name(), mi))
|
||||
.collect::<Vec<(InternedString, @MetaItem)> >();
|
||||
.collect::<Vec<(InternedString, Gc<MetaItem>)> >();
|
||||
|
||||
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)| {
|
||||
match m.node {
|
||||
MetaList(ref n, ref mis) => {
|
||||
@Spanned {
|
||||
box(GC) Spanned {
|
||||
node: MetaList((*n).clone(),
|
||||
sort_meta_items(mis.as_slice())),
|
||||
.. /*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
|
||||
* 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();
|
||||
for attr in attrs.iter().filter(|at| at.check_name("link")) {
|
||||
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="b")]`) == false
|
||||
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.
|
||||
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();
|
||||
for meta in metas.iter() {
|
||||
let name = meta.name();
|
||||
|
@ -23,8 +23,8 @@ source code snippets, etc.
|
||||
|
||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
use std::rc::Rc;
|
||||
use std::string::String;
|
||||
|
||||
pub trait Pos {
|
||||
fn from_uint(n: uint) -> Self;
|
||||
@ -91,7 +91,7 @@ pub struct Span {
|
||||
pub hi: BytePos,
|
||||
/// Information about where the macro came from, if this piece of
|
||||
/// 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 };
|
||||
|
@ -20,7 +20,6 @@ use parse;
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
|
||||
|
||||
enum State {
|
||||
Asm,
|
||||
Outputs,
|
||||
@ -214,7 +213,7 @@ pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
out));
|
||||
}
|
||||
|
||||
MacExpr::new(@ast::Expr {
|
||||
MacExpr::new(box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprInlineAsm(ast::InlineAsm {
|
||||
asm: token::intern_and_get_ident(asm.get()),
|
||||
|
@ -20,6 +20,7 @@ use parse::token::{InternedString, intern, str_to_ident};
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::gc::Gc;
|
||||
|
||||
// new-style macro! tt code:
|
||||
//
|
||||
@ -35,10 +36,10 @@ pub struct MacroDef {
|
||||
}
|
||||
|
||||
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 =
|
||||
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 expander: MacroExpanderFn,
|
||||
@ -104,15 +105,15 @@ pub trait MacResult {
|
||||
None
|
||||
}
|
||||
/// Create an expression.
|
||||
fn make_expr(&self) -> Option<@ast::Expr> {
|
||||
fn make_expr(&self) -> Option<Gc<ast::Expr>> {
|
||||
None
|
||||
}
|
||||
/// Create zero or more items.
|
||||
fn make_items(&self) -> Option<SmallVector<@ast::Item>> {
|
||||
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
|
||||
None
|
||||
}
|
||||
/// Create a pattern.
|
||||
fn make_pat(&self) -> Option<@ast::Pat> {
|
||||
fn make_pat(&self) -> Option<Gc<ast::Pat>> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -120,58 +121,58 @@ pub trait MacResult {
|
||||
///
|
||||
/// By default this attempts to create an expression statement,
|
||||
/// returning None if that fails.
|
||||
fn make_stmt(&self) -> Option<@ast::Stmt> {
|
||||
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
|
||||
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.
|
||||
pub struct MacExpr {
|
||||
e: @ast::Expr
|
||||
e: Gc<ast::Expr>,
|
||||
}
|
||||
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>
|
||||
}
|
||||
}
|
||||
impl MacResult for MacExpr {
|
||||
fn make_expr(&self) -> Option<@ast::Expr> {
|
||||
fn make_expr(&self) -> Option<Gc<ast::Expr>> {
|
||||
Some(self.e)
|
||||
}
|
||||
}
|
||||
/// A convenience type for macros that return a single pattern.
|
||||
pub struct MacPat {
|
||||
p: @ast::Pat
|
||||
p: Gc<ast::Pat>,
|
||||
}
|
||||
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>
|
||||
}
|
||||
}
|
||||
impl MacResult for MacPat {
|
||||
fn make_pat(&self) -> Option<@ast::Pat> {
|
||||
fn make_pat(&self) -> Option<Gc<ast::Pat>> {
|
||||
Some(self.p)
|
||||
}
|
||||
}
|
||||
/// A convenience type for macros that return a single item.
|
||||
pub struct MacItem {
|
||||
i: @ast::Item
|
||||
i: Gc<ast::Item>
|
||||
}
|
||||
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>
|
||||
}
|
||||
}
|
||||
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))
|
||||
}
|
||||
fn make_stmt(&self) -> Option<@ast::Stmt> {
|
||||
Some(@codemap::respan(
|
||||
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
|
||||
Some(box(GC) codemap::respan(
|
||||
self.i.span,
|
||||
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)))
|
||||
}
|
||||
}
|
||||
@ -202,17 +203,17 @@ impl DummyResult {
|
||||
}
|
||||
|
||||
/// A plain dummy expression.
|
||||
pub fn raw_expr(sp: Span) -> @ast::Expr {
|
||||
@ast::Expr {
|
||||
pub fn raw_expr(sp: Span) -> Gc<ast::Expr> {
|
||||
box(GC) ast::Expr {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
/// A plain dummy pattern.
|
||||
pub fn raw_pat(sp: Span) -> @ast::Pat {
|
||||
@ast::Pat {
|
||||
pub fn raw_pat(sp: Span) -> Gc<ast::Pat> {
|
||||
box(GC) ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::PatWild,
|
||||
span: sp,
|
||||
@ -221,21 +222,21 @@ impl 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))
|
||||
}
|
||||
fn make_pat(&self) -> Option<@ast::Pat> {
|
||||
fn make_pat(&self) -> Option<Gc<ast::Pat>> {
|
||||
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 {
|
||||
None
|
||||
} else {
|
||||
Some(SmallVector::zero())
|
||||
}
|
||||
}
|
||||
fn make_stmt(&self) -> Option<@ast::Stmt> {
|
||||
Some(@codemap::respan(self.span,
|
||||
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
|
||||
Some(box(GC) codemap::respan(self.span,
|
||||
ast::StmtExpr(DummyResult::raw_expr(self.span),
|
||||
ast::DUMMY_NODE_ID)))
|
||||
}
|
||||
@ -397,7 +398,7 @@ pub fn syntax_expander_table() -> SyntaxEnv {
|
||||
pub struct ExtCtxt<'a> {
|
||||
pub parse_sess: &'a parse::ParseSess,
|
||||
pub cfg: ast::CrateConfig,
|
||||
pub backtrace: Option<@ExpnInfo>,
|
||||
pub backtrace: Option<Gc<ExpnInfo>>,
|
||||
pub ecfg: expand::ExpansionConfig,
|
||||
|
||||
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 {
|
||||
match e.node {
|
||||
ast::ExprMac(..) => {
|
||||
@ -442,7 +443,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
}
|
||||
}
|
||||
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_pop(&mut self) { self.mod_path.pop().unwrap(); }
|
||||
pub fn mod_path(&self) -> Vec<ast::Ident> {
|
||||
@ -455,9 +456,9 @@ impl<'a> ExtCtxt<'a> {
|
||||
match ei {
|
||||
ExpnInfo {call_site: cs, callee: ref callee} => {
|
||||
self.backtrace =
|
||||
Some(@ExpnInfo {
|
||||
Some(box(GC) ExpnInfo {
|
||||
call_site: Span {lo: cs.lo, hi: cs.hi,
|
||||
expn_info: self.backtrace},
|
||||
expn_info: self.backtrace.clone()},
|
||||
callee: (*callee).clone()
|
||||
});
|
||||
}
|
||||
@ -528,7 +529,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
/// 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
|
||||
/// 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)> {
|
||||
// we want to be able to handle e.g. concat("foo", "bar")
|
||||
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.
|
||||
pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
|
||||
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(),
|
||||
cx.cfg(),
|
||||
tts.iter()
|
||||
|
@ -21,6 +21,8 @@ use parse::token::special_idents;
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
// Transitional reexports so qquote can find the paths it is looking for
|
||||
mod syntax {
|
||||
pub use ext;
|
||||
@ -73,115 +75,129 @@ pub trait AstBuilder {
|
||||
fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime;
|
||||
|
||||
// statements
|
||||
fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt;
|
||||
fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @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: Gc<ast::Expr>) -> Gc<ast::Stmt>;
|
||||
fn stmt_let_typed(&self,
|
||||
sp: Span,
|
||||
mutbl: bool,
|
||||
ident: ast::Ident,
|
||||
typ: P<ast::Ty>,
|
||||
ex: @ast::Expr)
|
||||
-> @ast::Stmt;
|
||||
ex: Gc<ast::Expr>)
|
||||
-> Gc<ast::Stmt>;
|
||||
|
||||
// blocks
|
||||
fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@ast::Expr>) -> P<ast::Block>;
|
||||
fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block>;
|
||||
fn block(&self, span: Span, stmts: Vec<Gc<ast::Stmt>>,
|
||||
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,
|
||||
view_items: Vec<ast::ViewItem> ,
|
||||
stmts: Vec<@ast::Stmt> ,
|
||||
expr: Option<@ast::Expr>) -> P<ast::Block>;
|
||||
stmts: Vec<Gc<ast::Stmt>> ,
|
||||
expr: Option<Gc<ast::Expr>>) -> P<ast::Block>;
|
||||
|
||||
// expressions
|
||||
fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr;
|
||||
fn expr_path(&self, path: ast::Path) -> @ast::Expr;
|
||||
fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr;
|
||||
fn expr(&self, span: Span, node: ast::Expr_) -> Gc<ast::Expr>;
|
||||
fn expr_path(&self, path: ast::Path) -> Gc<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,
|
||||
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr;
|
||||
lhs: Gc<ast::Expr>, rhs: Gc<ast::Expr>) -> Gc<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: Gc<ast::Expr>) -> Gc<ast::Expr>;
|
||||
|
||||
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_field_access(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr;
|
||||
fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr;
|
||||
fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@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: Gc<ast::Expr>) -> Gc<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: Gc<ast::Expr>,
|
||||
ident: ast::Ident) -> Gc<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> ,
|
||||
args: Vec<@ast::Expr> ) -> @ast::Expr;
|
||||
args: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
|
||||
fn expr_method_call(&self, span: Span,
|
||||
expr: @ast::Expr, ident: ast::Ident,
|
||||
args: Vec<@ast::Expr> ) -> @ast::Expr;
|
||||
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr;
|
||||
fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr;
|
||||
expr: Gc<ast::Expr>, ident: ast::Ident,
|
||||
args: Vec<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
|
||||
fn expr_block(&self, b: P<ast::Block>) -> Gc<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 expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr;
|
||||
fn expr_struct_ident(&self, span: Span, id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr;
|
||||
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> ) -> 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_int(&self, sp: Span, i: int) -> @ast::Expr;
|
||||
fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr;
|
||||
fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr;
|
||||
fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr>;
|
||||
fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr>;
|
||||
fn expr_u8(&self, sp: Span, u: u8) -> Gc<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_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr;
|
||||
fn expr_vec_ng(&self, sp: Span) -> @ast::Expr;
|
||||
fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr;
|
||||
fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr;
|
||||
fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @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<Gc<ast::Expr>> ) -> Gc<ast::Expr>;
|
||||
fn expr_vec_ng(&self, sp: Span) -> Gc<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) -> Gc<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_none(&self, sp: Span) -> @ast::Expr;
|
||||
fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
|
||||
fn expr_none(&self, sp: Span) -> Gc<ast::Expr>;
|
||||
|
||||
fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr;
|
||||
fn expr_unreachable(&self, span: Span) -> @ast::Expr;
|
||||
fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr>;
|
||||
fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr>;
|
||||
|
||||
fn expr_ok(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_err(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_try(&self, span: Span, head: @ast::Expr) -> @ast::Expr;
|
||||
fn expr_ok(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
|
||||
fn expr_err(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<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_wild(&self, span: Span) -> @ast::Pat;
|
||||
fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat;
|
||||
fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat;
|
||||
fn pat(&self, span: Span, pat: ast::Pat_) -> Gc<ast::Pat>;
|
||||
fn pat_wild(&self, span: Span) -> Gc<ast::Pat>;
|
||||
fn pat_lit(&self, span: Span, expr: Gc<ast::Expr>) -> Gc<ast::Pat>;
|
||||
fn pat_ident(&self, span: Span, ident: ast::Ident) -> Gc<ast::Pat>;
|
||||
|
||||
fn pat_ident_binding_mode(&self,
|
||||
span: Span,
|
||||
ident: ast::Ident,
|
||||
bm: ast::BindingMode) -> @ast::Pat;
|
||||
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat;
|
||||
bm: ast::BindingMode) -> Gc<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,
|
||||
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 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,
|
||||
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_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 lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr;
|
||||
fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @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>) -> Gc<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_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
|
||||
fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @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: Gc<ast::Expr>) -> Gc<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_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr;
|
||||
fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr;
|
||||
fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident>,
|
||||
blk: Vec<Gc<ast::Stmt>>) -> Gc<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
|
||||
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;
|
||||
// FIXME unused self
|
||||
@ -193,56 +209,59 @@ pub trait AstBuilder {
|
||||
inputs: Vec<ast::Arg> ,
|
||||
output: P<ast::Ty>,
|
||||
generics: Generics,
|
||||
body: P<ast::Block>) -> @ast::Item;
|
||||
body: P<ast::Block>) -> Gc<ast::Item>;
|
||||
fn item_fn(&self,
|
||||
span: Span,
|
||||
name: Ident,
|
||||
inputs: Vec<ast::Arg> ,
|
||||
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 item_enum_poly(&self,
|
||||
span: Span,
|
||||
name: Ident,
|
||||
enum_definition: ast::EnumDef,
|
||||
generics: Generics) -> @ast::Item;
|
||||
fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> @ast::Item;
|
||||
generics: Generics) -> Gc<ast::Item>;
|
||||
fn item_enum(&self, span: Span, name: Ident,
|
||||
enum_def: ast::EnumDef) -> Gc<ast::Item>;
|
||||
|
||||
fn item_struct_poly(&self,
|
||||
span: Span,
|
||||
name: Ident,
|
||||
struct_def: ast::StructDef,
|
||||
generics: Generics) -> @ast::Item;
|
||||
fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> @ast::Item;
|
||||
generics: Generics) -> Gc<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,
|
||||
name: Ident, attrs: Vec<ast::Attribute> ,
|
||||
vi: Vec<ast::ViewItem> , items: Vec<@ast::Item> ) -> @ast::Item;
|
||||
name: Ident, attrs: Vec<ast::Attribute>,
|
||||
vi: Vec<ast::ViewItem>,
|
||||
items: Vec<Gc<ast::Item>>) -> Gc<ast::Item>;
|
||||
|
||||
fn item_ty_poly(&self,
|
||||
span: Span,
|
||||
name: Ident,
|
||||
ty: P<ast::Ty>,
|
||||
generics: Generics) -> @ast::Item;
|
||||
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item;
|
||||
generics: Generics) -> Gc<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,
|
||||
sp: Span,
|
||||
name: InternedString,
|
||||
mis: Vec<@ast::MetaItem> )
|
||||
-> @ast::MetaItem;
|
||||
mis: Vec<Gc<ast::MetaItem>>)
|
||||
-> Gc<ast::MetaItem>;
|
||||
fn meta_name_value(&self,
|
||||
sp: Span,
|
||||
name: InternedString,
|
||||
value: ast::Lit_)
|
||||
-> @ast::MetaItem;
|
||||
-> Gc<ast::MetaItem>;
|
||||
|
||||
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,
|
||||
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 }
|
||||
}
|
||||
|
||||
fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt {
|
||||
@respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID))
|
||||
fn stmt_expr(&self, expr: Gc<ast::Expr>) -> Gc<ast::Stmt> {
|
||||
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 {
|
||||
self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
|
||||
} else {
|
||||
self.pat_ident(sp, ident)
|
||||
};
|
||||
let local = @ast::Local {
|
||||
let local = box(GC) ast::Local {
|
||||
ty: self.ty_infer(sp),
|
||||
pat: pat,
|
||||
init: Some(ex),
|
||||
@ -437,7 +457,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
source: ast::LocalLet,
|
||||
};
|
||||
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,
|
||||
@ -445,14 +465,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
mutbl: bool,
|
||||
ident: ast::Ident,
|
||||
typ: P<ast::Ty>,
|
||||
ex: @ast::Expr)
|
||||
-> @ast::Stmt {
|
||||
ex: Gc<ast::Expr>)
|
||||
-> Gc<ast::Stmt> {
|
||||
let pat = if mutbl {
|
||||
self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
|
||||
} else {
|
||||
self.pat_ident(sp, ident)
|
||||
};
|
||||
let local = @ast::Local {
|
||||
let local = box(GC) ast::Local {
|
||||
ty: typ,
|
||||
pat: pat,
|
||||
init: Some(ex),
|
||||
@ -461,21 +481,22 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
source: ast::LocalLet,
|
||||
};
|
||||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
fn block_all(&self,
|
||||
span: Span,
|
||||
view_items: Vec<ast::ViewItem> ,
|
||||
stmts: Vec<@ast::Stmt> ,
|
||||
expr: Option<@ast::Expr>) -> P<ast::Block> {
|
||||
stmts: Vec<Gc<ast::Stmt>>,
|
||||
expr: Option<Gc<ast::Expr>>) -> P<ast::Block> {
|
||||
P(ast::Block {
|
||||
view_items: view_items,
|
||||
stmts: stmts,
|
||||
@ -486,107 +507,109 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr {
|
||||
@ast::Expr {
|
||||
fn expr(&self, span: Span, node: ast::Expr_) -> Gc<ast::Expr> {
|
||||
box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: node,
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
fn expr_self(&self, span: Span) -> @ast::Expr {
|
||||
fn expr_self(&self, span: Span) -> Gc<ast::Expr> {
|
||||
self.expr_ident(span, special_idents::self_)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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()))
|
||||
}
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
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));
|
||||
self.expr_call(sp, pathexpr, args)
|
||||
}
|
||||
fn expr_method_call(&self, span: Span,
|
||||
expr: @ast::Expr,
|
||||
expr: Gc<ast::Expr>,
|
||||
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 };
|
||||
args.unshift(expr);
|
||||
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))
|
||||
}
|
||||
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 }
|
||||
}
|
||||
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))
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr {
|
||||
self.expr(sp, ast::ExprLit(@respan(sp, lit)))
|
||||
fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> Gc<ast::Expr> {
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
fn expr_vec_ng(&self, sp: Span) -> @ast::Expr {
|
||||
fn expr_vec_ng(&self, sp: Span) -> Gc<ast::Expr> {
|
||||
self.expr_call_global(sp,
|
||||
vec!(self.ident_of("std"),
|
||||
self.ident_of("vec"),
|
||||
@ -594,23 +617,23 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
self.ident_of("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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
|
||||
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!(
|
||||
self.ident_of("std"),
|
||||
self.ident_of("option"),
|
||||
@ -618,7 +641,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
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!(
|
||||
self.ident_of("std"),
|
||||
self.ident_of("option"),
|
||||
@ -626,7 +649,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
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);
|
||||
self.expr_call_global(
|
||||
span,
|
||||
@ -643,13 +666,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
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,
|
||||
InternedString::new(
|
||||
"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!(
|
||||
self.ident_of("std"),
|
||||
self.ident_of("result"),
|
||||
@ -657,7 +680,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
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!(
|
||||
self.ident_of("std"),
|
||||
self.ident_of("result"),
|
||||
@ -665,7 +688,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
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_path = self.path_ident(sp, ok);
|
||||
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 {
|
||||
@ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }
|
||||
fn pat(&self, span: Span, pat: ast::Pat_) -> Gc<ast::Pat> {
|
||||
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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
||||
fn pat_ident_binding_mode(&self,
|
||||
span: Span,
|
||||
ident: ast::Ident,
|
||||
bm: ast::BindingMode) -> @ast::Pat {
|
||||
bm: ast::BindingMode) -> Gc<ast::Pat> {
|
||||
let path = self.path_ident(span, ident);
|
||||
let pat = ast::PatIdent(bm, path, None);
|
||||
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));
|
||||
self.pat(span, pat)
|
||||
}
|
||||
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);
|
||||
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 {
|
||||
attrs: vec!(),
|
||||
pats: pats,
|
||||
@ -738,56 +761,60 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
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))
|
||||
}
|
||||
|
||||
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)));
|
||||
self.expr(span, ast::ExprIf(cond, self.block_expr(then), els))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
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(
|
||||
ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
|
||||
self.ty_infer(span));
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
fn lambda_stmts(&self,
|
||||
span: Span,
|
||||
ids: Vec<ast::Ident>,
|
||||
stmts: Vec<@ast::Stmt>)
|
||||
-> @ast::Expr {
|
||||
stmts: Vec<Gc<ast::Stmt>>)
|
||||
-> Gc<ast::Expr> {
|
||||
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))
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
@ -811,10 +838,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}
|
||||
|
||||
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
|
||||
// Rust coding conventions
|
||||
@ast::Item { ident: name,
|
||||
box(GC) ast::Item { ident: name,
|
||||
attrs: attrs,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: node,
|
||||
@ -828,7 +856,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
inputs: Vec<ast::Arg> ,
|
||||
output: P<ast::Ty>,
|
||||
generics: Generics,
|
||||
body: P<ast::Block>) -> @ast::Item {
|
||||
body: P<ast::Block>) -> Gc<ast::Item> {
|
||||
self.item(span,
|
||||
name,
|
||||
Vec::new(),
|
||||
@ -845,7 +873,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
inputs: Vec<ast::Arg> ,
|
||||
output: P<ast::Ty>,
|
||||
body: P<ast::Block>
|
||||
) -> @ast::Item {
|
||||
) -> Gc<ast::Item> {
|
||||
self.item_fn_poly(
|
||||
span,
|
||||
name,
|
||||
@ -873,18 +901,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
|
||||
fn item_enum_poly(&self, span: Span, name: Ident,
|
||||
enum_definition: ast::EnumDef,
|
||||
generics: Generics) -> @ast::Item {
|
||||
generics: Generics) -> Gc<ast::Item> {
|
||||
self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics))
|
||||
}
|
||||
|
||||
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,
|
||||
ast_util::empty_generics())
|
||||
}
|
||||
|
||||
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(
|
||||
span,
|
||||
name,
|
||||
@ -894,14 +922,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}
|
||||
|
||||
fn item_struct_poly(&self, span: Span, name: Ident,
|
||||
struct_def: ast::StructDef, generics: Generics) -> @ast::Item {
|
||||
self.item(span, name, Vec::new(), ast::ItemStruct(@struct_def, generics))
|
||||
struct_def: ast::StructDef, generics: Generics) -> Gc<ast::Item> {
|
||||
self.item(span, name, Vec::new(), ast::ItemStruct(box(GC) struct_def, generics))
|
||||
}
|
||||
|
||||
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
|
||||
attrs: Vec<ast::Attribute> ,
|
||||
vi: Vec<ast::ViewItem> ,
|
||||
items: Vec<@ast::Item> ) -> @ast::Item {
|
||||
items: Vec<Gc<ast::Item>>) -> Gc<ast::Item> {
|
||||
self.item(
|
||||
span,
|
||||
name,
|
||||
@ -915,15 +943,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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_ {
|
||||
id: attr::mk_attr_id(),
|
||||
style: ast::AttrOuter,
|
||||
@ -932,26 +960,26 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem {
|
||||
@respan(sp, ast::MetaWord(w))
|
||||
fn meta_word(&self, sp: Span, w: InternedString) -> Gc<ast::MetaItem> {
|
||||
box(GC) respan(sp, ast::MetaWord(w))
|
||||
}
|
||||
fn meta_list(&self,
|
||||
sp: Span,
|
||||
name: InternedString,
|
||||
mis: Vec<@ast::MetaItem> )
|
||||
-> @ast::MetaItem {
|
||||
@respan(sp, ast::MetaList(name, mis))
|
||||
mis: Vec<Gc<ast::MetaItem>> )
|
||||
-> Gc<ast::MetaItem> {
|
||||
box(GC) respan(sp, ast::MetaList(name, mis))
|
||||
}
|
||||
fn meta_name_value(&self,
|
||||
sp: Span,
|
||||
name: InternedString,
|
||||
value: ast::Lit_)
|
||||
-> @ast::MetaItem {
|
||||
@respan(sp, ast::MetaNameValue(name, respan(sp, value)))
|
||||
-> Gc<ast::MetaItem> {
|
||||
box(GC) respan(sp, ast::MetaNameValue(name, respan(sp, value)))
|
||||
}
|
||||
|
||||
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 {
|
||||
node: ast::ViewItemUse(vp),
|
||||
attrs: Vec::new(),
|
||||
@ -968,7 +996,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||
ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
|
||||
self.view_use(sp, vis,
|
||||
@respan(sp,
|
||||
box(GC) respan(sp,
|
||||
ast::ViewPathSimple(ident,
|
||||
path,
|
||||
ast::DUMMY_NODE_ID)))
|
||||
@ -981,7 +1009,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}).collect();
|
||||
|
||||
self.view_use(sp, vis,
|
||||
@respan(sp,
|
||||
box(GC) respan(sp,
|
||||
ast::ViewPathList(self.path(sp, path),
|
||||
imports,
|
||||
ast::DUMMY_NODE_ID)))
|
||||
@ -990,7 +1018,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
fn view_use_glob(&self, sp: Span,
|
||||
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
|
||||
self.view_use(sp, vis,
|
||||
@respan(sp,
|
||||
box(GC) respan(sp,
|
||||
ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID)))
|
||||
}
|
||||
}
|
||||
@ -1013,8 +1041,8 @@ pub trait Duplicate {
|
||||
fn duplicate(&self, cx: &ExtCtxt) -> Self;
|
||||
}
|
||||
|
||||
impl Duplicate for @ast::Expr {
|
||||
fn duplicate(&self, _: &ExtCtxt) -> @ast::Expr {
|
||||
impl Duplicate for Gc<ast::Expr> {
|
||||
fn duplicate(&self, _: &ExtCtxt) -> Gc<ast::Expr> {
|
||||
let mut folder = Duplicator;
|
||||
folder.fold_expr(*self)
|
||||
}
|
||||
|
@ -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 e = @ast::Expr {
|
||||
let e = box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprPath(
|
||||
ast::Path {
|
||||
|
@ -14,11 +14,13 @@ use ext::base::ExtCtxt;
|
||||
use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_bound(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
|
||||
let name = match mitem.node {
|
||||
MetaWord(ref tname) => {
|
||||
|
@ -16,11 +16,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
let attrs = vec!(cx.attribute(span, inline));
|
||||
let trait_def = TraitDef {
|
||||
@ -51,7 +53,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
|
||||
fn cs_clone(
|
||||
name: &str,
|
||||
cx: &mut ExtCtxt, trait_span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
let clone_ident = substr.method_ident;
|
||||
let ctor_ident;
|
||||
let all_fields;
|
||||
|
@ -16,18 +16,20 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_eq(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
// structures are equal if all fields are equal, and non equal, if
|
||||
// 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),
|
||||
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),
|
||||
cx, span, substr)
|
||||
}
|
||||
|
@ -17,11 +17,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_ord(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
macro_rules! md (
|
||||
($name:expr, $op:expr, $equal:expr) => { {
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
@ -58,7 +60,8 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
|
||||
}
|
||||
|
||||
/// 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};
|
||||
cs_fold(
|
||||
false, // need foldr,
|
||||
|
@ -16,12 +16,15 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span,
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
cs_same_method(|cx, span, exprs| {
|
||||
// create `a.<method>(); b.<method>(); c.<method>(); ...`
|
||||
// (where method is `assert_receiver_is_total_eq`)
|
||||
|
@ -18,12 +18,13 @@ use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::cmp::{Ordering, Equal, Less, Greater};
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
let attrs = vec!(cx.attribute(span, inline));
|
||||
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,
|
||||
substr: &Substructure) -> @Expr {
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
let test_id = cx.ident_of("__test");
|
||||
let equals_path = ordering_const(cx, span, Equal);
|
||||
|
||||
|
@ -23,11 +23,13 @@ use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
use parse::token;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
@ -64,7 +66,7 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
|
||||
}
|
||||
|
||||
fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
let decoder = substr.nonself_args[0];
|
||||
let recurse = vec!(cx.ident_of("serialize"),
|
||||
cx.ident_of("Decodable"),
|
||||
@ -159,8 +161,8 @@ fn decode_static_fields(cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
outer_pat_ident: Ident,
|
||||
fields: &StaticFields,
|
||||
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> @Expr)
|
||||
-> @Expr {
|
||||
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> Gc<Expr>)
|
||||
-> Gc<Expr> {
|
||||
match *fields {
|
||||
Unnamed(ref fields) => {
|
||||
if fields.is_empty() {
|
||||
|
@ -16,11 +16,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_default(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
let attrs = vec!(cx.attribute(span, inline));
|
||||
let trait_def = TraitDef {
|
||||
@ -46,7 +48,8 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
|
||||
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!(
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("default"),
|
||||
|
@ -91,11 +91,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
@ -134,7 +136,7 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
|
||||
}
|
||||
|
||||
fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
let encoder = substr.nonself_args[0];
|
||||
// throw an underscore in front to suppress unused variable warnings
|
||||
let blkarg = cx.ident_of("_e");
|
||||
|
@ -178,6 +178,7 @@ StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span
|
||||
*/
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
|
||||
use ast;
|
||||
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
|
||||
@ -248,9 +249,9 @@ pub struct Substructure<'a> {
|
||||
/// ident of the method
|
||||
pub method_ident: Ident,
|
||||
/// 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
|
||||
pub nonself_args: &'a [@Expr],
|
||||
pub nonself_args: &'a [Gc<Expr>],
|
||||
pub fields: &'a SubstructureFields<'a>
|
||||
}
|
||||
|
||||
@ -262,42 +263,43 @@ pub struct FieldInfo {
|
||||
pub name: Option<Ident>,
|
||||
/// The expression corresponding to this field of `self`
|
||||
/// (specifically, a reference to it).
|
||||
pub self_: @Expr,
|
||||
pub self_: Gc<Expr>,
|
||||
/// The expressions corresponding to references to this field in
|
||||
/// the other Self arguments.
|
||||
pub other: Vec<@Expr>,
|
||||
pub other: Vec<Gc<Expr>>,
|
||||
}
|
||||
|
||||
/// Fields for a static method
|
||||
pub enum StaticFields {
|
||||
/// Tuple structs/enum variants like this
|
||||
Unnamed(Vec<Span> ),
|
||||
Unnamed(Vec<Span>),
|
||||
/// Normal structs/struct variants.
|
||||
Named(Vec<(Ident, Span)> )
|
||||
Named(Vec<(Ident, Span)>),
|
||||
}
|
||||
|
||||
/// A summary of the possible sets of fields. See above for details
|
||||
/// and examples
|
||||
pub enum SubstructureFields<'a> {
|
||||
Struct(Vec<FieldInfo> ),
|
||||
Struct(Vec<FieldInfo>),
|
||||
/**
|
||||
Matching variants of the enum: variant index, ast::Variant,
|
||||
fields: the field name is only non-`None` in the case of a struct
|
||||
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,
|
||||
[field span, field ident, fields])] \(i.e. all fields for self are in the
|
||||
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.
|
||||
StaticStruct(&'a ast::StructDef, StaticFields),
|
||||
/// 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.
|
||||
*/
|
||||
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
|
||||
@ -317,9 +319,9 @@ representing each variant: (variant index, ast::Variant instance,
|
||||
pub type EnumNonMatchFunc<'a> =
|
||||
|&mut ExtCtxt,
|
||||
Span,
|
||||
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )],
|
||||
&[@Expr]|: 'a
|
||||
-> @Expr;
|
||||
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, Gc<Expr>)>)],
|
||||
&[Gc<Expr>]|: 'a
|
||||
-> Gc<Expr>;
|
||||
|
||||
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
|
||||
-> RefCell<CombineSubstructureFunc<'a>> {
|
||||
@ -330,13 +332,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
|
||||
impl<'a> TraitDef<'a> {
|
||||
pub fn expand(&self,
|
||||
cx: &mut ExtCtxt,
|
||||
_mitem: @ast::MetaItem,
|
||||
item: @ast::Item,
|
||||
push: |@ast::Item|) {
|
||||
_mitem: Gc<ast::MetaItem>,
|
||||
item: Gc<ast::Item>,
|
||||
push: |Gc<ast::Item>|) {
|
||||
let newitem = match item.node {
|
||||
ast::ItemStruct(struct_def, ref generics) => {
|
||||
ast::ItemStruct(ref struct_def, ref generics) => {
|
||||
self.expand_struct_def(cx,
|
||||
struct_def,
|
||||
&**struct_def,
|
||||
item.ident,
|
||||
generics)
|
||||
}
|
||||
@ -357,7 +359,7 @@ impl<'a> TraitDef<'a> {
|
||||
_ => false,
|
||||
}
|
||||
}).map(|a| a.clone()));
|
||||
push(@ast::Item {
|
||||
push(box(GC) ast::Item {
|
||||
attrs: attrs,
|
||||
..(*newitem).clone()
|
||||
})
|
||||
@ -379,7 +381,7 @@ impl<'a> TraitDef<'a> {
|
||||
cx: &mut ExtCtxt,
|
||||
type_ident: Ident,
|
||||
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 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
|
||||
attr::mark_used(&attr);
|
||||
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(
|
||||
self.span,
|
||||
ident,
|
||||
@ -448,7 +450,7 @@ impl<'a> TraitDef<'a> {
|
||||
cx: &mut ExtCtxt,
|
||||
struct_def: &StructDef,
|
||||
type_ident: Ident,
|
||||
generics: &Generics) -> @ast::Item {
|
||||
generics: &Generics) -> Gc<ast::Item> {
|
||||
let methods = self.methods.iter().map(|method_def| {
|
||||
let (explicit_self, self_args, nonself_args, tys) =
|
||||
method_def.split_self_nonself_args(
|
||||
@ -484,7 +486,7 @@ impl<'a> TraitDef<'a> {
|
||||
cx: &mut ExtCtxt,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
generics: &Generics) -> @ast::Item {
|
||||
generics: &Generics) -> Gc<ast::Item> {
|
||||
let methods = self.methods.iter().map(|method_def| {
|
||||
let (explicit_self, self_args, nonself_args, tys) =
|
||||
method_def.split_self_nonself_args(cx, self,
|
||||
@ -522,10 +524,10 @@ impl<'a> MethodDef<'a> {
|
||||
cx: &mut ExtCtxt,
|
||||
trait_: &TraitDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr],
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>],
|
||||
fields: &SubstructureFields)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
let substructure = Substructure {
|
||||
type_ident: type_ident,
|
||||
method_ident: cx.ident_of(self.name),
|
||||
@ -556,7 +558,8 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
type_ident: Ident,
|
||||
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 nonself_args = Vec::new();
|
||||
@ -608,7 +611,7 @@ impl<'a> MethodDef<'a> {
|
||||
generics: &Generics,
|
||||
explicit_self: ast::ExplicitSelf,
|
||||
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
|
||||
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);
|
||||
|
||||
// Create the method.
|
||||
@ast::Method {
|
||||
box(GC) ast::Method {
|
||||
ident: method_ident,
|
||||
attrs: self.attributes.clone(),
|
||||
generics: fn_generics,
|
||||
@ -670,9 +673,9 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
struct_def: &StructDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
|
||||
let mut raw_fields = Vec::new(); // ~[[fields of self],
|
||||
// [fields of next Self arg], [etc]]
|
||||
@ -737,9 +740,9 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
struct_def: &StructDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
let summary = trait_.summarise_struct(cx, struct_def);
|
||||
|
||||
self.call_substructure_method(cx,
|
||||
@ -780,9 +783,9 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
let mut matches = Vec::new();
|
||||
self.build_enum_match(cx, trait_, enum_def, type_ident,
|
||||
self_args, nonself_args,
|
||||
@ -816,12 +819,12 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr],
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>],
|
||||
matching: Option<uint>,
|
||||
matches_so_far: &mut Vec<(uint, P<ast::Variant>,
|
||||
Vec<(Span, Option<Ident>, @Expr)> )> ,
|
||||
match_count: uint) -> @Expr {
|
||||
Vec<(Span, Option<Ident>, Gc<Expr>)>)> ,
|
||||
match_count: uint) -> Gc<Expr> {
|
||||
if match_count == self_args.len() {
|
||||
// we've matched against all arguments, so make the final
|
||||
// expression at the bottom of the match tree
|
||||
@ -871,7 +874,7 @@ impl<'a> MethodDef<'a> {
|
||||
other: (*other).clone()
|
||||
}
|
||||
}).collect();
|
||||
EnumMatching(variant_index, variant, field_tuples)
|
||||
EnumMatching(variant_index, &*variant, field_tuples)
|
||||
}
|
||||
None => {
|
||||
EnumNonMatching(matches_so_far.as_slice())
|
||||
@ -905,7 +908,7 @@ impl<'a> MethodDef<'a> {
|
||||
let variant = *enum_def.variants.get(index);
|
||||
let (pattern, idents) = trait_.create_enum_variant_pattern(
|
||||
cx,
|
||||
variant,
|
||||
&*variant,
|
||||
current_match_str.as_slice(),
|
||||
ast::MutImmutable);
|
||||
|
||||
@ -938,7 +941,7 @@ impl<'a> MethodDef<'a> {
|
||||
let (pattern, idents) =
|
||||
trait_.create_enum_variant_pattern(
|
||||
cx,
|
||||
variant,
|
||||
&*variant,
|
||||
current_match_str.as_slice(),
|
||||
ast::MutImmutable);
|
||||
|
||||
@ -974,17 +977,17 @@ impl<'a> MethodDef<'a> {
|
||||
trait_: &TraitDef,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
let summary = enum_def.variants.iter().map(|v| {
|
||||
let ident = v.node.name;
|
||||
let summary = match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect())
|
||||
}
|
||||
ast::StructVariantKind(struct_def) => {
|
||||
trait_.summarise_struct(cx, struct_def)
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
trait_.summarise_struct(cx, &**struct_def)
|
||||
}
|
||||
};
|
||||
(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`"),
|
||||
Some(name) => *name
|
||||
};
|
||||
to_set.expn_info = Some(@codemap::ExpnInfo {
|
||||
to_set.expn_info = Some(box(GC) codemap::ExpnInfo {
|
||||
call_site: to_set,
|
||||
callee: codemap::NameAndSpan {
|
||||
name: format!("deriving({})", trait_name).to_string(),
|
||||
@ -1048,7 +1051,7 @@ impl<'a> TraitDef<'a> {
|
||||
cx: &mut ExtCtxt,
|
||||
field_paths: Vec<ast::Path> ,
|
||||
mutbl: ast::Mutability)
|
||||
-> Vec<@ast::Pat> {
|
||||
-> Vec<Gc<ast::Pat>> {
|
||||
field_paths.iter().map(|path| {
|
||||
cx.pat(path.span,
|
||||
ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
|
||||
@ -1061,7 +1064,7 @@ impl<'a> TraitDef<'a> {
|
||||
struct_def: &StructDef,
|
||||
prefix: &str,
|
||||
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() {
|
||||
return (
|
||||
cx.pat_ident_binding_mode(
|
||||
@ -1126,7 +1129,7 @@ impl<'a> TraitDef<'a> {
|
||||
variant: &ast::Variant,
|
||||
prefix: &str,
|
||||
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;
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref variant_args) => {
|
||||
@ -1159,8 +1162,8 @@ impl<'a> TraitDef<'a> {
|
||||
(cx.pat_enum(variant.span, matching_path, subpats),
|
||||
ident_expr)
|
||||
}
|
||||
ast::StructVariantKind(struct_def) => {
|
||||
self.create_struct_pattern(cx, variant_ident, struct_def,
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
self.create_struct_pattern(cx, variant_ident, &**struct_def,
|
||||
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`).
|
||||
*/
|
||||
pub fn cs_fold(use_foldl: bool,
|
||||
f: |&mut ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr,
|
||||
base: @Expr,
|
||||
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
|
||||
base: Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
match *substructure.fields {
|
||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||
if use_foldl {
|
||||
@ -1221,12 +1224,12 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
|
||||
~~~
|
||||
*/
|
||||
#[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,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
match *substructure.fields {
|
||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||
// 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]
|
||||
pub fn cs_same_method_fold(use_foldl: bool,
|
||||
f: |&mut ExtCtxt, Span, @Expr, @Expr| -> @Expr,
|
||||
base: @Expr,
|
||||
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
|
||||
base: Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
cs_same_method(
|
||||
|cx, span, vals| {
|
||||
if use_foldl {
|
||||
@ -1285,10 +1288,10 @@ Use a given binop to combine the result of calling the derived method
|
||||
on all the fields.
|
||||
*/
|
||||
#[inline]
|
||||
pub fn cs_binop(binop: ast::BinOp, base: @Expr,
|
||||
pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt, trait_span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
substructure: &Substructure) -> Gc<Expr> {
|
||||
cs_same_method_fold(
|
||||
true, // foldl is good enough
|
||||
|cx, span, old, new| {
|
||||
@ -1306,7 +1309,7 @@ pub fn cs_binop(binop: ast::BinOp, base: @Expr,
|
||||
#[inline]
|
||||
pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt, span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
substructure: &Substructure) -> Gc<Expr> {
|
||||
cs_binop(ast::BiOr, cx.expr_bool(span, false),
|
||||
enum_nonmatch_f,
|
||||
cx, span, substructure)
|
||||
@ -1316,7 +1319,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
#[inline]
|
||||
pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt, span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
substructure: &Substructure) -> Gc<Expr> {
|
||||
cs_binop(ast::BiAnd, cx.expr_bool(span, true),
|
||||
enum_nonmatch_f,
|
||||
cx, span, substructure)
|
||||
|
@ -20,6 +20,7 @@ use ext::build::AstBuilder;
|
||||
use codemap::{Span,respan};
|
||||
use owned_slice::OwnedSlice;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
/// The types of pointers
|
||||
pub enum PtrTy<'a> {
|
||||
@ -81,7 +82,7 @@ impl<'a> Path<'a> {
|
||||
/// A type. Supports pointers (except for *), Self, and literals
|
||||
pub enum Ty<'a> {
|
||||
Self,
|
||||
// &/Box/@ Ty
|
||||
// &/Box/ Ty
|
||||
Ptr(Box<Ty<'a>>, PtrTy<'a>),
|
||||
// mod::mod::Type<[lifetime], [Params...]>, including a plain type
|
||||
// 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>)
|
||||
-> (@Expr, ast::ExplicitSelf) {
|
||||
-> (Gc<Expr>, ast::ExplicitSelf) {
|
||||
let self_path = cx.expr_self(span);
|
||||
match *self_ptr {
|
||||
None => {
|
||||
|
@ -17,11 +17,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_hash(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
|
||||
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
|
||||
(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);
|
||||
}
|
||||
|
||||
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 {
|
||||
[state_expr] => state_expr,
|
||||
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")
|
||||
|
@ -22,6 +22,8 @@ use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
|
||||
use ext::base::ExtCtxt;
|
||||
use codemap::Span;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub mod bounds;
|
||||
pub mod clone;
|
||||
pub mod encodable;
|
||||
@ -47,9 +49,9 @@ pub mod generic;
|
||||
|
||||
pub fn expand_meta_deriving(cx: &mut ExtCtxt,
|
||||
_span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
match mitem.node {
|
||||
MetaNameValue(_, ref l) => {
|
||||
cx.span_err(l.span, "unexpected value in `deriving`");
|
||||
|
@ -17,11 +17,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
let attrs = vec!(cx.attribute(span, inline));
|
||||
let trait_def = TraitDef {
|
||||
@ -70,7 +72,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
|
||||
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 {
|
||||
[n] => n,
|
||||
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`")
|
||||
|
@ -16,11 +16,13 @@ use ext::build::{AstBuilder};
|
||||
use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_rand(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
@ -53,7 +55,8 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
|
||||
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 {
|
||||
[rng] => vec!( rng ),
|
||||
_ => 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,
|
||||
ctor_ident: Ident,
|
||||
summary: &StaticFields,
|
||||
rand_call: |&mut ExtCtxt, Span| -> @Expr)
|
||||
-> @Expr {
|
||||
rand_call: |&mut ExtCtxt, Span| -> Gc<Expr>)
|
||||
-> Gc<Expr> {
|
||||
match *summary {
|
||||
Unnamed(ref fields) => {
|
||||
if fields.is_empty() {
|
||||
|
@ -20,12 +20,13 @@ use parse::token;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::string::String;
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_show(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
// &mut ::std::fmt::Formatter
|
||||
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
|
||||
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
|
||||
// knows what's up with formatting at so on.
|
||||
fn show_substructure(cx: &mut ExtCtxt, span: Span,
|
||||
substr: &Substructure) -> @Expr {
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
// build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
|
||||
// <field>: {}, ... }` based on the "shape".
|
||||
//
|
||||
|
@ -16,11 +16,13 @@ use ext::deriving::generic::*;
|
||||
use ext::deriving::generic::ty::*;
|
||||
use parse::token::InternedString;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn expand_deriving_zero(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
mitem: @MetaItem,
|
||||
item: @Item,
|
||||
push: |@Item|) {
|
||||
mitem: Gc<MetaItem>,
|
||||
item: Gc<Item>,
|
||||
push: |Gc<Item>|) {
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
let attrs = vec!(cx.attribute(span, inline));
|
||||
let trait_def = TraitDef {
|
||||
@ -63,7 +65,8 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
|
||||
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!(
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("num"),
|
||||
|
@ -29,7 +29,9 @@ use visit;
|
||||
use visit::Visitor;
|
||||
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 {
|
||||
// expr_mac should really be expr_ext or something; it's the
|
||||
// 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.cx.bt_pop();
|
||||
|
||||
@ast::Expr {
|
||||
box(GC) ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: fully_expanded,
|
||||
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");
|
||||
// this is careful to use src_pat.span so that error
|
||||
// messages point exact at that.
|
||||
let local = @ast::Local {
|
||||
let local = box(GC) ast::Local {
|
||||
ty: fld.cx.ty_infer(src_pat.span),
|
||||
pat: src_pat,
|
||||
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
|
||||
};
|
||||
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 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.
|
||||
fld.extsbox.push_frame();
|
||||
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();
|
||||
|
||||
(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!`
|
||||
pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander)
|
||||
-> SmallVector<@ast::Item> {
|
||||
pub fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
|
||||
-> SmallVector<Gc<ast::Item>> {
|
||||
let it = expand_item_modifiers(it, fld);
|
||||
|
||||
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)),
|
||||
// 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,
|
||||
|item| items.push(item));
|
||||
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 result = with_exts_frame!(fld.extsbox,
|
||||
macro_escape,
|
||||
noop_fold_item(it, fld));
|
||||
noop_fold_item(&*it, fld));
|
||||
fld.cx.mod_pop();
|
||||
result
|
||||
},
|
||||
_ => {
|
||||
let it = @ast::Item {
|
||||
let it = box(GC) ast::Item {
|
||||
attrs: new_attrs,
|
||||
..(*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
|
||||
}
|
||||
|
||||
fn expand_item_modifiers(mut it: @ast::Item, fld: &mut MacroExpander)
|
||||
-> @ast::Item {
|
||||
fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
|
||||
-> Gc<ast::Item> {
|
||||
let (modifiers, attrs) = it.attrs.partitioned(|attr| {
|
||||
match fld.extsbox.find(&intern(attr.name().get())) {
|
||||
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,
|
||||
..(*it).clone()
|
||||
};
|
||||
@ -388,8 +391,8 @@ pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
|
||||
|
||||
// Support for item-position macro invocations, exactly the same
|
||||
// logic as for expression-position macro invocations.
|
||||
pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
|
||||
-> SmallVector<@ast::Item> {
|
||||
pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
|
||||
-> SmallVector<Gc<ast::Item>> {
|
||||
let (pth, tts) = match it.node {
|
||||
ItemMac(codemap::Spanned {
|
||||
node: MacInvocTT(ref pth, ref tts, _),
|
||||
@ -494,7 +497,7 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander)
|
||||
}
|
||||
|
||||
// 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?
|
||||
// looks like classic changed-in-only-one-place
|
||||
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.
|
||||
let fully_expanded = fld.fold_stmt(marked_after);
|
||||
let fully_expanded = fld.fold_stmt(&*marked_after);
|
||||
if fully_expanded.is_empty() {
|
||||
fld.cx.span_err(pth.span, "macro didn't expand to a statement");
|
||||
return SmallVector::zero();
|
||||
}
|
||||
fld.cx.bt_pop();
|
||||
let fully_expanded: SmallVector<@Stmt> = fully_expanded.move_iter()
|
||||
.map(|s| @Spanned { span: s.span, node: s.node.clone() })
|
||||
let fully_expanded: SmallVector<Gc<Stmt>> = fully_expanded.move_iter()
|
||||
.map(|s| box(GC) Spanned { span: s.span, node: s.node.clone() })
|
||||
.collect();
|
||||
|
||||
fully_expanded.move_iter().map(|s| {
|
||||
match s.node {
|
||||
StmtExpr(e, stmt_id) if semi => {
|
||||
@Spanned {
|
||||
box(GC) Spanned {
|
||||
span: s.span,
|
||||
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_stmt, above.
|
||||
fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
|
||||
-> SmallVector<@Stmt> {
|
||||
-> SmallVector<Gc<Stmt>> {
|
||||
// is it a let?
|
||||
match s.node {
|
||||
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
|
||||
// the new names are gensyms for the old ones.
|
||||
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
|
||||
let mut new_pending_renames = Vec::new();
|
||||
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:
|
||||
let new_init_opt = init.map(|e| fld.fold_expr(e));
|
||||
let rewritten_local =
|
||||
@Local {
|
||||
box(GC) Local {
|
||||
ty: local.ty,
|
||||
pat: rewritten_pat,
|
||||
init: new_init_opt,
|
||||
@ -639,8 +642,8 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
|
||||
span: span,
|
||||
source: source
|
||||
};
|
||||
SmallVector::one(@Spanned {
|
||||
node: StmtDecl(@Spanned {
|
||||
SmallVector::one(box(GC) Spanned {
|
||||
node: StmtDecl(box(GC) Spanned {
|
||||
node: DeclLocal(rewritten_local),
|
||||
span: stmt_span
|
||||
},
|
||||
@ -687,7 +690,7 @@ impl Visitor<()> for NewNameFinderContext {
|
||||
}
|
||||
// visit optional subpattern of pat_ident:
|
||||
for subpat in inner.iter() {
|
||||
self.visit_pat(*subpat, ())
|
||||
self.visit_pat(&**subpat, ())
|
||||
}
|
||||
}
|
||||
// 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 pending_renames = &mut fld.extsbox.info().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();
|
||||
let new_expr = b.expr.map(|x| {
|
||||
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 {
|
||||
PatMac(ref mac) => {
|
||||
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.cx.bt_pop();
|
||||
|
||||
@ast::Pat {
|
||||
box(GC) ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: fully_expanded,
|
||||
span: p.span,
|
||||
@ -863,24 +866,24 @@ pub struct 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -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.
|
||||
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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
.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.
|
||||
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)
|
||||
}
|
||||
|
||||
fn original_span(cx: &ExtCtxt) -> @codemap::ExpnInfo {
|
||||
fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
|
||||
let mut relevant_info = cx.backtrace();
|
||||
let mut einfo = relevant_info.unwrap();
|
||||
loop {
|
||||
@ -1134,7 +1137,7 @@ mod test {
|
||||
node: Attribute_ {
|
||||
id: attr::mk_attr_id(),
|
||||
style: AttrOuter,
|
||||
value: @Spanned {
|
||||
value: box(GC) Spanned {
|
||||
node: MetaWord(token::intern_and_get_ident(s)),
|
||||
span: codemap::DUMMY_SP,
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user