Skip to content

Commit

Permalink
auto merge of #14250 : alexcrichton/rust/gc, r=brson
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jun 11, 2014
2 parents c54ce27 + 54c2a1e commit f0f9095
Show file tree
Hide file tree
Showing 119 changed files with 2,818 additions and 2,668 deletions.
6 changes: 3 additions & 3 deletions src/doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand Down
7 changes: 0 additions & 7 deletions src/libcollections/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 4 additions & 9 deletions src/libcore/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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;
Expand All @@ -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]
Expand Down
23 changes: 0 additions & 23 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
4 changes: 0 additions & 4 deletions src/libcore/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
}
3 changes: 0 additions & 3 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
}
Expand Down
1 change: 0 additions & 1 deletion src/libcore/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(), };
Expand Down
48 changes: 25 additions & 23 deletions src/librustc/front/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand All @@ -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)
}
}
Expand All @@ -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())
Expand All @@ -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
Expand All @@ -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)
}
Expand All @@ -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()).
Expand All @@ -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
Expand All @@ -148,24 +150,24 @@ 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(),
is_virtual: def.is_virtual,
}
}

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
}
Expand All @@ -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))
Expand All @@ -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),
Expand Down Expand Up @@ -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))
}

8 changes: 5 additions & 3 deletions src/librustc/front/std_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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)
}
Expand All @@ -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(),
Expand Down
Loading

0 comments on commit f0f9095

Please sign in to comment.