Skip to content

Commit 531ed3d

Browse files
committed
rustc: Update how Gc<T> is recognized
This commit uses the same trick as ~/Box to map Gc<T> to @t internally inside the compiler. This moves a number of implementations of traits to the `gc` module in the standard library. This removes functions such as `Gc::new`, `Gc::borrow`, and `Gc::ptr_eq` in favor of the more modern equivalents, `box(GC)`, `Deref`, and pointer equality. The Gc pointer itself should be much more useful now, and subsequent commits will move the compiler away from @t towards Gc<T> [breaking-change]
1 parent ea41101 commit 531ed3d

File tree

16 files changed

+155
-173
lines changed

16 files changed

+155
-173
lines changed

src/liballoc/rc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,8 @@ mod tests {
320320
#[test]
321321
fn gc_inside() {
322322
// see issue #11532
323-
use std::gc::Gc;
324-
let a = Rc::new(RefCell::new(Gc::new(1)));
323+
use realstd::gc::Gc;
324+
let a = Rc::new(RefCell::new(box(GC) 1));
325325
assert!(a.try_borrow_mut().is_some());
326326
}
327327

src/libcollections/hash/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,6 @@ impl<S: Writer, T: Hash<S>> Hash<S> for Box<T> {
248248
}
249249
}
250250

251-
impl<S: Writer, T: Hash<S>> Hash<S> for @T {
252-
#[inline]
253-
fn hash(&self, state: &mut S) {
254-
(**self).hash(state);
255-
}
256-
}
257-
258251
impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> {
259252
#[inline]
260253
fn hash(&self, state: &mut S) {

src/libcore/clone.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ pub trait Clone {
3939
}
4040
}
4141

42-
impl<T> Clone for @T {
43-
/// Return a shallow copy of the managed box.
44-
#[inline]
45-
fn clone(&self) -> @T { *self }
46-
}
47-
4842
impl<'a, T> Clone for &'a T {
4943
/// Return a shallow copy of the reference.
5044
#[inline]

src/libcore/cmp.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -326,29 +326,6 @@ mod impls {
326326
fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
327327
}
328328
impl<'a, T: Eq> Eq for &'a mut T {}
329-
330-
// @ pointers
331-
impl<T:PartialEq> PartialEq for @T {
332-
#[inline]
333-
fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
334-
#[inline]
335-
fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
336-
}
337-
impl<T:PartialOrd> PartialOrd for @T {
338-
#[inline]
339-
fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
340-
#[inline]
341-
fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
342-
#[inline]
343-
fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
344-
#[inline]
345-
fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
346-
}
347-
impl<T: Ord> Ord for @T {
348-
#[inline]
349-
fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
350-
}
351-
impl<T: Eq> Eq for @T {}
352329
}
353330

354331
#[cfg(test)]

src/libcore/default.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,3 @@ default_impl!(i64, 0i64)
4343

4444
default_impl!(f32, 0.0f32)
4545
default_impl!(f64, 0.0f64)
46-
47-
impl<T: Default + 'static> Default for @T {
48-
fn default() -> @T { @Default::default() }
49-
}

src/libcore/fmt/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,6 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
628628

629629
// Implementations of the core formatting traits
630630

631-
impl<T: Show> Show for @T {
632-
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
633-
}
634631
impl<'a, T: Show> Show for &'a T {
635632
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
636633
}

src/libcore/raw.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ pub trait Repr<T> {
7979

8080
impl<'a, T> Repr<Slice<T>> for &'a [T] {}
8181
impl<'a> Repr<Slice<u8>> for &'a str {}
82-
impl<T> Repr<*Box<T>> for @T {}
8382
impl<T> Repr<*Vec<T>> for ~[T] {}
8483

8584
#[cfg(test)]

src/librustc/middle/trans/expr.rs

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -399,12 +399,20 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
399399
bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
400400
DatumBlock::new(bcx, datum)
401401
}
402-
ast::ExprBox(_, contents) => {
403-
// Special case for `box T`. (The other case, for GC, is handled
404-
// in `trans_rvalue_dps_unadjusted`.)
402+
ast::ExprBox(_, ref contents) => {
403+
// Special case for `Box<T>` and `Gc<T>`
405404
let box_ty = expr_ty(bcx, expr);
406-
let contents_ty = expr_ty(bcx, contents);
407-
trans_uniq_expr(bcx, box_ty, contents, contents_ty)
405+
let contents_ty = expr_ty(bcx, &**contents);
406+
match ty::get(box_ty).sty {
407+
ty::ty_uniq(..) => {
408+
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
409+
}
410+
ty::ty_box(..) => {
411+
trans_managed_expr(bcx, box_ty, &**contents, contents_ty)
412+
}
413+
_ => bcx.sess().span_bug(expr.span,
414+
"expected unique or managed box")
415+
}
408416
}
409417
ast::ExprLit(lit) => trans_immediate_lit(bcx, expr, (*lit).clone()),
410418
ast::ExprBinary(op, lhs, rhs) => {
@@ -773,11 +781,6 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
773781
ast::ExprAssignOp(op, dst, src) => {
774782
trans_assign_op(bcx, expr, op, dst, src)
775783
}
776-
ast::ExprBox(_, contents) => {
777-
// Special case for `Gc<T>` for now. The other case, for unique
778-
// pointers, is handled in `trans_rvalue_datum_unadjusted`.
779-
trans_gc(bcx, expr, contents, dest)
780-
}
781784
_ => {
782785
bcx.tcx().sess.span_bug(
783786
expr.span,
@@ -1242,31 +1245,6 @@ fn trans_addr_of<'a>(bcx: &'a Block<'a>,
12421245
return immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock();
12431246
}
12441247

1245-
fn trans_gc<'a>(mut bcx: &'a Block<'a>,
1246-
expr: &ast::Expr,
1247-
contents: &ast::Expr,
1248-
dest: Dest)
1249-
-> &'a Block<'a> {
1250-
let contents_ty = expr_ty(bcx, contents);
1251-
let box_ty = ty::mk_box(bcx.tcx(), contents_ty);
1252-
1253-
let contents_datum = unpack_datum!(bcx, trans_managed_expr(bcx,
1254-
box_ty,
1255-
contents,
1256-
contents_ty));
1257-
1258-
match dest {
1259-
Ignore => bcx,
1260-
SaveIn(addr) => {
1261-
let expr_ty = expr_ty(bcx, expr);
1262-
let repr = adt::represent_type(bcx.ccx(), expr_ty);
1263-
adt::trans_start_init(bcx, &*repr, addr, 0);
1264-
let field_dest = adt::trans_field_ptr(bcx, &*repr, addr, 0, 0);
1265-
contents_datum.store_to(bcx, field_dest)
1266-
}
1267-
}
1268-
}
1269-
12701248
// Important to get types for both lhs and rhs, because one might be _|_
12711249
// and the other not.
12721250
fn trans_eager_binop<'a>(

src/librustc/middle/ty.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use middle::lint;
1818
use middle::const_eval;
1919
use middle::def;
2020
use middle::dependency_format;
21-
use middle::lang_items::{ExchangeHeapLangItem, OpaqueStructLangItem};
21+
use middle::lang_items::OpaqueStructLangItem;
2222
use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
2323
use middle::freevars;
2424
use middle::resolve;
@@ -3108,17 +3108,17 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
31083108
}
31093109

31103110
ast::ExprBox(place, _) => {
3111-
// Special case `Box<T>` for now:
3111+
// Special case `Box<T>`/`Gc<T>` for now:
31123112
let definition = match tcx.def_map.borrow().find(&place.id) {
31133113
Some(&def) => def,
31143114
None => fail!("no def for place"),
31153115
};
31163116
let def_id = definition.def_id();
3117-
match tcx.lang_items.items.get(ExchangeHeapLangItem as uint) {
3118-
&Some(item_def_id) if def_id == item_def_id => {
3119-
RvalueDatumExpr
3120-
}
3121-
&Some(_) | &None => RvalueDpsExpr,
3117+
if tcx.lang_items.exchange_heap() == Some(def_id) ||
3118+
tcx.lang_items.managed_heap() == Some(def_id) {
3119+
RvalueDatumExpr
3120+
} else {
3121+
RvalueDpsExpr
31223122
}
31233123
}
31243124

src/librustc/middle/typeck/astconv.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,53 @@ pub fn ast_ty_to_builtin_ty<AC:AstConv,
451451
supplied to `Box<T>`");
452452
Some(ty::mk_err())
453453
}
454+
ast::DefTy(did) | ast::DefStruct(did)
455+
if Some(did) == this.tcx().lang_items.gc() => {
456+
if path.segments
457+
.iter()
458+
.flat_map(|s| s.types.iter())
459+
.len() > 1 {
460+
this.tcx()
461+
.sess
462+
.span_err(path.span,
463+
"`Gc` has only one type parameter")
464+
}
465+
466+
for inner_ast_type in path.segments
467+
.iter()
468+
.flat_map(|s| s.types.iter()) {
469+
let mt = ast::MutTy {
470+
ty: *inner_ast_type,
471+
mutbl: ast::MutImmutable,
472+
};
473+
return Some(mk_pointer(this,
474+
rscope,
475+
&mt,
476+
Box,
477+
|typ| {
478+
match ty::get(typ).sty {
479+
ty::ty_str => {
480+
this.tcx()
481+
.sess
482+
.span_err(path.span,
483+
"`Gc<str>` is not a type");
484+
ty::mk_err()
485+
}
486+
ty::ty_vec(_, None) => {
487+
this.tcx()
488+
.sess
489+
.span_err(path.span,
490+
"`Gc<[T]>` is not a type");
491+
ty::mk_err()
492+
}
493+
_ => ty::mk_box(this.tcx(), typ),
494+
}
495+
}))
496+
}
497+
this.tcx().sess.span_bug(path.span,
498+
"not enough type parameters \
499+
supplied to `Gc<T>`")
500+
}
454501
_ => None
455502
}
456503
}

src/librustc/middle/typeck/check/mod.rs

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,52 +2862,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
28622862
// places: the exchange heap and the managed heap.
28632863
let definition = lookup_def(fcx, path.span, place.id);
28642864
let def_id = definition.def_id();
2865-
match tcx.lang_items
2866-
.items
2867-
.get(ExchangeHeapLangItem as uint) {
2868-
&Some(item_def_id) if def_id == item_def_id => {
2869-
fcx.write_ty(id, ty::mk_uniq(tcx,
2870-
fcx.expr_ty(subexpr)));
2871-
checked = true
2872-
}
2873-
&Some(_) | &None => {}
2874-
}
2875-
if !checked {
2876-
match tcx.lang_items
2877-
.items
2878-
.get(ManagedHeapLangItem as uint) {
2879-
&Some(item_def_id) if def_id == item_def_id => {
2880-
// Assign the magic `Gc<T>` struct.
2881-
let gc_struct_id =
2882-
match tcx.lang_items
2883-
.require(GcLangItem) {
2884-
Ok(id) => id,
2885-
Err(msg) => {
2886-
tcx.sess.span_err(expr.span,
2887-
msg.as_slice());
2888-
ast::DefId {
2889-
krate: ast::CRATE_NODE_ID,
2890-
node: ast::DUMMY_NODE_ID,
2891-
}
2892-
}
2893-
};
2894-
let regions =
2895-
subst::NonerasedRegions(Vec::new());
2896-
let sty = ty::mk_struct(tcx,
2897-
gc_struct_id,
2898-
subst::Substs {
2899-
self_ty: None,
2900-
tps: vec!(
2901-
fcx.expr_ty(
2902-
subexpr)
2903-
),
2904-
regions: regions,
2905-
});
2906-
fcx.write_ty(id, sty);
2907-
checked = true
2908-
}
2909-
&Some(_) | &None => {}
2910-
}
2865+
if tcx.lang_items.exchange_heap() == Some(def_id) {
2866+
fcx.write_ty(id, ty::mk_uniq(tcx,
2867+
fcx.expr_ty(&**subexpr)));
2868+
checked = true
2869+
} else if tcx.lang_items.managed_heap() == Some(def_id) {
2870+
fcx.write_ty(id, ty::mk_box(tcx,
2871+
fcx.expr_ty(&**subexpr)));
2872+
checked = true
29112873
}
29122874
}
29132875
_ => {}

src/librustc/middle/typeck/coherence.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
129129
_ => {}
130130
}
131131
}
132+
ty_box(..) => {
133+
match tcx.lang_items.gc() {
134+
Some(did) if did.krate == ast::LOCAL_CRATE => {
135+
found_nominal = true;
136+
}
137+
_ => {}
138+
}
139+
}
132140

133141
_ => { }
134142
}

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ impl<T:Repr> Repr for Rc<T> {
510510
}
511511
}
512512

513-
impl<T:Repr> Repr for @T {
513+
impl<T:Repr + 'static> Repr for Gc<T> {
514514
fn repr(&self, tcx: &ctxt) -> String {
515515
(&**self).repr(tcx)
516516
}

src/libserialize/serialize.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Core encoding and decoding interfaces.
1616

1717
use std::path;
1818
use std::rc::Rc;
19+
use std::gc::Gc;
1920

2021
pub trait Encoder<E> {
2122
// Primitive types:
@@ -387,7 +388,7 @@ impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Box<T> {
387388
}
388389
}
389390

390-
impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for @T {
391+
impl<E, S:Encoder<E>,T:'static + Encodable<S, E>> Encodable<S, E> for Gc<T> {
391392
fn encode(&self, s: &mut S) -> Result<(), E> {
392393
(**self).encode(s)
393394
}
@@ -407,9 +408,9 @@ impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Rc<T> {
407408
}
408409
}
409410

410-
impl<E, D:Decoder<E>,T:Decodable<D, E> + 'static> Decodable<D, E> for @T {
411-
fn decode(d: &mut D) -> Result<@T, E> {
412-
Ok(@try!(Decodable::decode(d)))
411+
impl<E, D:Decoder<E>,T:Decodable<D, E> + 'static> Decodable<D, E> for Gc<T> {
412+
fn decode(d: &mut D) -> Result<Gc<T>, E> {
413+
Ok(box(GC) try!(Decodable::decode(d)))
413414
}
414415
}
415416

0 commit comments

Comments
 (0)