From 4a8d712345f30cba4f33bce9e0ece0eac64e8764 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 24 Oct 2014 10:20:02 -0400 Subject: [PATCH] Use type-safe wrapper for TypeFlags --- src/librustc/middle/traits/doc.rs | 2 +- src/librustc/middle/ty.rs | 103 +++++++++++++++++------------- 2 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/librustc/middle/traits/doc.rs b/src/librustc/middle/traits/doc.rs index a8fcdb360546b..c014bc0c164f2 100644 --- a/src/librustc/middle/traits/doc.rs +++ b/src/librustc/middle/traits/doc.rs @@ -287,7 +287,7 @@ want to be able to cache results even when all the types in the trait reference are not fully known. In that case, it may happen that the trait selection process is also influencing type variables, so we have to be able to not only cache the *result* of the selection process, -but *reply* its effects on the type variables. +but *replay* its effects on the type variables. ## An example diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 52ec97ab647be..4a081c0db3733 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -589,14 +589,19 @@ pub struct ctxt<'tcx> { // through the type during type construction, so that we can quickly // check whether the type has various kinds of types in it without // recursing over the type itself. -const HAS_PARAMS: uint = 1; -const HAS_SELF: uint = 2; -const HAS_TY_INFER: uint = 4; -const HAS_RE_INFER: uint = 8; -const HAS_REGIONS: uint = 16; -const HAS_TY_ERR: uint = 32; -const HAS_TY_BOT: uint = 64; -const NEEDS_SUBST: uint = HAS_PARAMS | HAS_SELF | HAS_REGIONS; +bitflags! { + flags TypeFlags: u32 { + const NO_TYPE_FLAGS = 0b0, + const HAS_PARAMS = 0b1, + const HAS_SELF = 0b10, + const HAS_TY_INFER = 0b100, + const HAS_RE_INFER = 0b1000, + const HAS_REGIONS = 0b10000, + const HAS_TY_ERR = 0b100000, + const HAS_TY_BOT = 0b1000000, + const NEEDS_SUBST = HAS_PARAMS.bits | HAS_SELF.bits | HAS_REGIONS.bits, + } +} pub type t_box = &'static t_box_; @@ -604,7 +609,13 @@ pub type t_box = &'static t_box_; pub struct t_box_ { pub sty: sty, pub id: uint, - pub flags: uint, + pub flags: TypeFlags, +} + +impl fmt::Show for TypeFlags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.bits) + } } // To reduce refcounting cost, we're representing types as unsafe pointers @@ -631,8 +642,8 @@ pub fn get(t: t) -> t_box { } } -fn tbox_has_flag(tb: t_box, flag: uint) -> bool { - (tb.flags & flag) != 0u +fn tbox_has_flag(tb: t_box, flag: TypeFlags) -> bool { + tb.flags.intersects(flag) } pub fn type_has_params(t: t) -> bool { tbox_has_flag(get(t), HAS_PARAMS) @@ -887,7 +898,7 @@ mod primitives { pub static $name: t_box_ = t_box_ { sty: $sty, id: $id, - flags: 0, + flags: super::NO_TYPE_FLAGS, }; ) ) @@ -1578,32 +1589,32 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { _ => () } - let mut flags = 0u; - fn rflags(r: Region) -> uint { + let mut flags = NO_TYPE_FLAGS; + fn rflags(r: Region) -> TypeFlags { HAS_REGIONS | { match r { ty::ReInfer(_) => HAS_RE_INFER, - _ => 0u + _ => NO_TYPE_FLAGS, } } } - fn sflags(substs: &Substs) -> uint { - let mut f = 0u; + fn sflags(substs: &Substs) -> TypeFlags { + let mut f = NO_TYPE_FLAGS; let mut i = substs.types.iter(); for tt in i { - f |= get(*tt).flags; + f = f | get(*tt).flags; } match substs.regions { subst::ErasedRegions => {} subst::NonerasedRegions(ref regions) => { for r in regions.iter() { - f |= rflags(*r) + f = f | rflags(*r) } } } return f; } - fn flags_for_bounds(bounds: &ExistentialBounds) -> uint { + fn flags_for_bounds(bounds: &ExistentialBounds) -> TypeFlags { rflags(bounds.region_bound) } match &st { @@ -1616,53 +1627,53 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { // But doing so caused sporadic memory corruption, and // neither I (tjc) nor nmatsakis could figure out why, // so we're doing it this way. - &ty_bot => flags |= HAS_TY_BOT, - &ty_err => flags |= HAS_TY_ERR, + &ty_bot => flags = flags | HAS_TY_BOT, + &ty_err => flags = flags | HAS_TY_ERR, &ty_param(ref p) => { if p.space == subst::SelfSpace { - flags |= HAS_SELF; + flags = flags | HAS_SELF; } else { - flags |= HAS_PARAMS; + flags = flags | HAS_PARAMS; } } - &ty_unboxed_closure(_, ref region) => flags |= rflags(*region), - &ty_infer(_) => flags |= HAS_TY_INFER, + &ty_unboxed_closure(_, ref region) => flags = flags | rflags(*region), + &ty_infer(_) => flags = flags | HAS_TY_INFER, &ty_enum(_, ref substs) | &ty_struct(_, ref substs) => { - flags |= sflags(substs); + flags = flags | sflags(substs); } &ty_trait(box TyTrait { ref substs, ref bounds, .. }) => { - flags |= sflags(substs); - flags |= flags_for_bounds(bounds); + flags = flags | sflags(substs); + flags = flags | flags_for_bounds(bounds); } &ty_uniq(tt) | &ty_vec(tt, _) | &ty_open(tt) => { - flags |= get(tt).flags + flags = flags | get(tt).flags } &ty_ptr(ref m) => { - flags |= get(m.ty).flags; + flags = flags | get(m.ty).flags; } &ty_rptr(r, ref m) => { - flags |= rflags(r); - flags |= get(m.ty).flags; + flags = flags | rflags(r); + flags = flags | get(m.ty).flags; } - &ty_tup(ref ts) => for tt in ts.iter() { flags |= get(*tt).flags; }, + &ty_tup(ref ts) => for tt in ts.iter() { flags = flags | get(*tt).flags; }, &ty_bare_fn(ref f) => { - for a in f.sig.inputs.iter() { flags |= get(*a).flags; } - flags |= get(f.sig.output).flags; + for a in f.sig.inputs.iter() { flags = flags | get(*a).flags; } + flags = flags | get(f.sig.output).flags; // T -> _|_ is *not* _|_ ! - flags &= !HAS_TY_BOT; + flags = flags - HAS_TY_BOT; } &ty_closure(ref f) => { match f.store { RegionTraitStore(r, _) => { - flags |= rflags(r); + flags = flags | rflags(r); } _ => {} } - for a in f.sig.inputs.iter() { flags |= get(*a).flags; } - flags |= get(f.sig.output).flags; + for a in f.sig.inputs.iter() { flags = flags | get(*a).flags; } + flags = flags | get(f.sig.output).flags; // T -> _|_ is *not* _|_ ! - flags &= !HAS_TY_BOT; - flags |= flags_for_bounds(&f.bounds); + flags = flags - HAS_TY_BOT; + flags = flags | flags_for_bounds(&f.bounds); } } @@ -1977,14 +1988,16 @@ impl ItemSubsts { // Type utilities -pub fn type_is_nil(ty: t) -> bool { get(ty).sty == ty_nil } +pub fn type_is_nil(ty: t) -> bool { + get(ty).sty == ty_nil +} pub fn type_is_bot(ty: t) -> bool { - (get(ty).flags & HAS_TY_BOT) != 0 + get(ty).flags.intersects(HAS_TY_BOT) } pub fn type_is_error(ty: t) -> bool { - (get(ty).flags & HAS_TY_ERR) != 0 + get(ty).flags.intersects(HAS_TY_ERR) } pub fn type_needs_subst(ty: t) -> bool {