Skip to content

Commit 92ae0c6

Browse files
committed
rustc: middle: ty: replace unsafe pointers with references in Ty.
1 parent 9706d8f commit 92ae0c6

File tree

1 file changed

+55
-72
lines changed

1 file changed

+55
-72
lines changed

src/librustc/middle/ty.rs

Lines changed: 55 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use util::ppaux::{Repr, UserString};
6161
use util::common::{indenter, memoized};
6262
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
6363
use util::nodemap::{FnvHashMap, FnvHashSet};
64+
use std::borrow::BorrowFrom;
6465
use std::cell::{Cell, RefCell};
6566
use std::cmp;
6667
use std::fmt::{mod, Show};
@@ -252,32 +253,6 @@ pub struct creader_cache_key {
252253
pub len: uint
253254
}
254255

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-
281256
pub enum ast_ty_to_ty_cache_entry {
282257
atttce_unresolved, /* not resolved yet */
283258
atttce_resolved(Ty) /* resolved to a type, irrespective of region */
@@ -456,11 +431,13 @@ pub struct TransmuteRestriction {
456431
/// later on.
457432
pub struct ctxt<'tcx> {
458433
/// The arena that types are allocated from.
459-
type_arena: &'tcx TypedArena<t_box_>,
434+
type_arena: &'tcx TypedArena<TyS>,
460435

461436
/// Specifically use a speedy hash algorithm for this hash map, it's used
462437
/// 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>>>,
464441
pub sess: Session,
465442
pub def_map: resolve::DefMap,
466443

@@ -621,10 +598,8 @@ bitflags! {
621598
}
622599
}
623600

624-
pub type t_box = &'static t_box_;
625-
626601
#[deriving(Show)]
627-
pub struct t_box_ {
602+
pub struct TyS {
628603
pub sty: sty,
629604
pub flags: TypeFlags,
630605

@@ -638,32 +613,52 @@ impl fmt::Show for TypeFlags {
638613
}
639614
}
640615

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 {}
647622

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+
}
651628

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)
655647
}
656648
}
657649

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
662653
}
663654
}
664655

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)
667662
}
668663
pub fn type_has_params(ty: Ty) -> bool {
669664
tbox_has_flag(get(ty), HAS_PARAMS)
@@ -1024,13 +1019,13 @@ pub enum BoundRegion {
10241019
}
10251020

10261021
mod primitives {
1027-
use super::t_box_;
1022+
use super::TyS;
10281023

10291024
use syntax::ast;
10301025

10311026
macro_rules! def_prim_ty(
10321027
($name:ident, $sty:expr) => (
1033-
pub static $name: t_box_ = t_box_ {
1028+
pub static $name: TyS = TyS {
10341029
sty: $sty,
10351030
flags: super::NO_TYPE_FLAGS,
10361031
region_depth: 0,
@@ -1053,7 +1048,7 @@ mod primitives {
10531048
def_prim_ty!(TY_F32, super::ty_float(ast::TyF32))
10541049
def_prim_ty!(TY_F64, super::ty_float(ast::TyF64))
10551050

1056-
pub static TY_ERR: t_box_ = t_box_ {
1051+
pub static TY_ERR: TyS = TyS {
10571052
sty: super::ty_err,
10581053
flags: super::HAS_TY_ERR,
10591054
region_depth: 0,
@@ -1701,7 +1696,7 @@ impl UnboxedClosureKind {
17011696
}
17021697

17031698
pub fn mk_ctxt<'tcx>(s: Session,
1704-
type_arena: &'tcx TypedArena<t_box_>,
1699+
type_arena: &'tcx TypedArena<TyS>,
17051700
dm: resolve::DefMap,
17061701
named_region_map: resolve_lifetime::NamedRegionMap,
17071702
map: ast_map::Map<'tcx>,
@@ -1785,32 +1780,22 @@ pub fn mk_t(cx: &ctxt, st: sty) -> Ty {
17851780
_ => {}
17861781
};
17871782

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,
17921785
_ => ()
17931786
}
17941787

17951788
let flags = FlagComputation::for_sty(&st);
17961789

1797-
let ty = cx.type_arena.alloc(t_box_ {
1790+
let ty = cx.type_arena.alloc(TyS {
17981791
sty: st,
17991792
flags: flags.flags,
18001793
region_depth: flags.depth,
18011794
});
18021795

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);
18101797

1811-
unsafe {
1812-
mem::transmute::<*const sty, Ty>(sty_ptr)
1813-
}
1798+
Ty { inner: ty }
18141799
}
18151800

18161801
struct FlagComputation {
@@ -1996,10 +1981,8 @@ impl FlagComputation {
19961981
}
19971982

19981983
#[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 }
20031986
}
20041987

20051988
#[inline]

0 commit comments

Comments
 (0)