@@ -61,6 +61,7 @@ use util::ppaux::{Repr, UserString};
61
61
use util:: common:: { indenter, memoized} ;
62
62
use util:: nodemap:: { NodeMap , NodeSet , DefIdMap , DefIdSet } ;
63
63
use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
64
+ use std:: borrow:: BorrowFrom ;
64
65
use std:: cell:: { Cell , RefCell } ;
65
66
use std:: cmp;
66
67
use std:: fmt:: { mod, Show } ;
@@ -252,32 +253,6 @@ pub struct creader_cache_key {
252
253
pub len : uint
253
254
}
254
255
255
- pub struct intern_key {
256
- sty : * const sty ,
257
- }
258
-
259
- // NB: Do not replace this with #[deriving(PartialEq)]. The automatically-derived
260
- // implementation will not recurse through sty and you will get stack
261
- // exhaustion.
262
- impl cmp:: PartialEq for intern_key {
263
- fn eq ( & self , other : & intern_key ) -> bool {
264
- unsafe {
265
- * self . sty == * other. sty
266
- }
267
- }
268
- fn ne ( & self , other : & intern_key ) -> bool {
269
- !self . eq ( other)
270
- }
271
- }
272
-
273
- impl Eq for intern_key { }
274
-
275
- impl < W : Writer > Hash < W > for intern_key {
276
- fn hash ( & self , s : & mut W ) {
277
- unsafe { ( * self . sty ) . hash ( s) }
278
- }
279
- }
280
-
281
256
pub enum ast_ty_to_ty_cache_entry {
282
257
atttce_unresolved, /* not resolved yet */
283
258
atttce_resolved( Ty ) /* resolved to a type, irrespective of region */
@@ -456,11 +431,13 @@ pub struct TransmuteRestriction {
456
431
/// later on.
457
432
pub struct ctxt < ' tcx > {
458
433
/// The arena that types are allocated from.
459
- type_arena : & ' tcx TypedArena < t_box_ > ,
434
+ type_arena : & ' tcx TypedArena < TyS > ,
460
435
461
436
/// Specifically use a speedy hash algorithm for this hash map, it's used
462
437
/// quite often.
463
- interner : RefCell < FnvHashMap < intern_key , & ' tcx t_box_ > > ,
438
+ // TODO(eddyb) use a FnvHashSet<InternedTy<'tcx>> when equivalent keys can
439
+ // queried from a HashSet.
440
+ interner : RefCell < FnvHashMap < InternedTy < ' tcx > , Ty < ' tcx > > > ,
464
441
pub sess : Session ,
465
442
pub def_map : resolve:: DefMap ,
466
443
@@ -621,10 +598,8 @@ bitflags! {
621
598
}
622
599
}
623
600
624
- pub type t_box = & ' static t_box_ ;
625
-
626
601
#[ deriving( Show ) ]
627
- pub struct t_box_ {
602
+ pub struct TyS {
628
603
pub sty : sty ,
629
604
pub flags : TypeFlags ,
630
605
@@ -638,32 +613,52 @@ impl fmt::Show for TypeFlags {
638
613
}
639
614
}
640
615
641
- // To reduce refcounting cost, we're representing types as unsafe pointers
642
- // throughout the compiler. These are simply casted t_box values. Use ty::get
643
- // to cast them back to a box. (Without the cast, compiler performance suffers
644
- // ~15%.) This does mean that a Ty value relies on the ctxt to keep its box
645
- // alive, and using ty::get is unsafe when the ctxt is no longer alive.
646
- enum t_opaque { }
616
+ impl PartialEq for TyS {
617
+ fn eq ( & self , other : & TyS ) -> bool {
618
+ ( self as * const _ ) == ( other as * const _ )
619
+ }
620
+ }
621
+ impl Eq for TyS { }
647
622
648
- #[ allow( raw_pointer_deriving) ]
649
- #[ deriving( Clone , PartialEq , Eq , Hash ) ]
650
- pub struct Ty { inner : * const t_opaque }
623
+ impl < S : Writer > Hash < S > for TyS {
624
+ fn hash ( & self , s : & mut S ) {
625
+ ( self as * const _ ) . hash ( s)
626
+ }
627
+ }
651
628
652
- impl fmt:: Show for Ty {
653
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
654
- write ! ( f, "{}" , get( * self ) )
629
+ pub type Ty < ' tcx > = & ' tcx TyS ;
630
+
631
+ /// An entry in the type interner.
632
+ struct InternedTy < ' tcx > {
633
+ ty : Ty < ' tcx >
634
+ }
635
+
636
+ // NB: An InternedTy compares and hashes as a sty.
637
+ impl < ' tcx > PartialEq for InternedTy < ' tcx > {
638
+ fn eq ( & self , other : & InternedTy < ' tcx > ) -> bool {
639
+ self . ty . sty == other. ty . sty
640
+ }
641
+ }
642
+ impl < ' tcx > Eq for InternedTy < ' tcx > { }
643
+
644
+ impl < ' tcx , S : Writer > Hash < S > for InternedTy < ' tcx > {
645
+ fn hash ( & self , s : & mut S ) {
646
+ self . ty . sty . hash ( s)
655
647
}
656
648
}
657
649
658
- pub fn get ( ty : Ty ) -> t_box {
659
- unsafe {
660
- let t2: t_box = mem:: transmute ( ty) ;
661
- t2
650
+ impl < ' tcx > BorrowFrom < InternedTy < ' tcx > > for sty < ' tcx > {
651
+ fn borrow_from < ' a > ( ty : & ' a InternedTy < ' tcx > ) -> & ' a sty < ' tcx > {
652
+ & ty. ty . sty
662
653
}
663
654
}
664
655
665
- fn tbox_has_flag ( tb : t_box , flag : TypeFlags ) -> bool {
666
- tb. flags . intersects ( flag)
656
+ pub fn get ( ty : Ty ) -> Ty {
657
+ ty
658
+ }
659
+
660
+ fn tbox_has_flag ( ty : Ty , flag : TypeFlags ) -> bool {
661
+ ty. flags . intersects ( flag)
667
662
}
668
663
pub fn type_has_params ( ty : Ty ) -> bool {
669
664
tbox_has_flag ( get ( ty) , HAS_PARAMS )
@@ -1024,13 +1019,13 @@ pub enum BoundRegion {
1024
1019
}
1025
1020
1026
1021
mod primitives {
1027
- use super :: t_box_ ;
1022
+ use super :: TyS ;
1028
1023
1029
1024
use syntax:: ast;
1030
1025
1031
1026
macro_rules! def_prim_ty(
1032
1027
( $name: ident, $sty: expr) => (
1033
- pub static $name: t_box_ = t_box_ {
1028
+ pub static $name: TyS = TyS {
1034
1029
sty: $sty,
1035
1030
flags: super :: NO_TYPE_FLAGS ,
1036
1031
region_depth: 0 ,
@@ -1053,7 +1048,7 @@ mod primitives {
1053
1048
def_prim_ty ! ( TY_F32 , super :: ty_float( ast:: TyF32 ) )
1054
1049
def_prim_ty ! ( TY_F64 , super :: ty_float( ast:: TyF64 ) )
1055
1050
1056
- pub static TY_ERR : t_box_ = t_box_ {
1051
+ pub static TY_ERR : TyS = TyS {
1057
1052
sty : super :: ty_err,
1058
1053
flags : super :: HAS_TY_ERR ,
1059
1054
region_depth : 0 ,
@@ -1701,7 +1696,7 @@ impl UnboxedClosureKind {
1701
1696
}
1702
1697
1703
1698
pub fn mk_ctxt < ' tcx > ( s : Session ,
1704
- type_arena : & ' tcx TypedArena < t_box_ > ,
1699
+ type_arena : & ' tcx TypedArena < TyS > ,
1705
1700
dm : resolve:: DefMap ,
1706
1701
named_region_map : resolve_lifetime:: NamedRegionMap ,
1707
1702
map : ast_map:: Map < ' tcx > ,
@@ -1785,32 +1780,22 @@ pub fn mk_t(cx: &ctxt, st: sty) -> Ty {
1785
1780
_ => { }
1786
1781
} ;
1787
1782
1788
- let key = intern_key { sty : & st } ;
1789
-
1790
- match cx. interner . borrow ( ) . get ( & key) {
1791
- Some ( ty) => unsafe { return mem:: transmute ( & ty. sty ) ; } ,
1783
+ match cx. interner . borrow ( ) . get ( & st) {
1784
+ Some ( ty) => return ty,
1792
1785
_ => ( )
1793
1786
}
1794
1787
1795
1788
let flags = FlagComputation :: for_sty ( & st) ;
1796
1789
1797
- let ty = cx. type_arena . alloc ( t_box_ {
1790
+ let ty = cx. type_arena . alloc ( TyS {
1798
1791
sty : st,
1799
1792
flags : flags. flags ,
1800
1793
region_depth : flags. depth ,
1801
1794
} ) ;
1802
1795
1803
- let sty_ptr = & ty. sty as * const sty ;
1804
-
1805
- let key = intern_key {
1806
- sty : sty_ptr,
1807
- } ;
1808
-
1809
- cx. interner . borrow_mut ( ) . insert ( key, ty) ;
1796
+ cx. interner . borrow_mut ( ) . insert ( InternedTy { ty : ty } , ty) ;
1810
1797
1811
- unsafe {
1812
- mem:: transmute :: < * const sty , Ty > ( sty_ptr)
1813
- }
1798
+ Ty { inner : ty }
1814
1799
}
1815
1800
1816
1801
struct FlagComputation {
@@ -1996,10 +1981,8 @@ impl FlagComputation {
1996
1981
}
1997
1982
1998
1983
#[ inline]
1999
- pub fn mk_prim_t ( primitive : & ' static t_box_ ) -> Ty {
2000
- unsafe {
2001
- mem:: transmute :: < & ' static t_box_ , Ty > ( primitive)
2002
- }
1984
+ pub fn mk_prim_t ( primitive : & ' static TyS ) -> Ty {
1985
+ Ty { inner : primitive }
2003
1986
}
2004
1987
2005
1988
#[ inline]
0 commit comments