diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d59c9dd6b53e8..28c1e4324de7a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -23,6 +23,7 @@ use ext::hygiene::{Mark, SyntaxContext}; use print::pprust; use ptr::P; use rustc_data_structures::indexed_vec; +use rustc_data_structures::indexed_vec::Idx; use symbol::{Symbol, keywords}; use tokenstream::{ThinTokenStream, TokenStream}; @@ -1910,9 +1911,18 @@ pub enum AttrStyle { Inner, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialOrd, Ord, Copy)] pub struct AttrId(pub usize); +impl Idx for AttrId { + fn new(idx: usize) -> Self { + AttrId(idx) + } + fn index(self) -> usize { + self.0 + } +} + /// Meta-data associated with an item /// Doc-comments are promoted to attributes that have is_sugared_doc = true #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 137b94230a3cd..7fbc5d4c41a50 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -41,51 +41,27 @@ use std::iter; pub fn mark_used(attr: &Attribute) { debug!("Marking {:?} as used.", attr); - let AttrId(id) = attr.id; GLOBALS.with(|globals| { - let mut slot = globals.used_attrs.lock(); - let idx = (id / 64) as usize; - let shift = id % 64; - if slot.len() <= idx { - slot.resize(idx + 1, 0); - } - slot[idx] |= 1 << shift; + globals.used_attrs.lock().insert(attr.id); }); } pub fn is_used(attr: &Attribute) -> bool { - let AttrId(id) = attr.id; GLOBALS.with(|globals| { - let slot = globals.used_attrs.lock(); - let idx = (id / 64) as usize; - let shift = id % 64; - slot.get(idx).map(|bits| bits & (1 << shift) != 0) - .unwrap_or(false) + globals.used_attrs.lock().contains(attr.id) }) } pub fn mark_known(attr: &Attribute) { debug!("Marking {:?} as known.", attr); - let AttrId(id) = attr.id; GLOBALS.with(|globals| { - let mut slot = globals.known_attrs.lock(); - let idx = (id / 64) as usize; - let shift = id % 64; - if slot.len() <= idx { - slot.resize(idx + 1, 0); - } - slot[idx] |= 1 << shift; + globals.known_attrs.lock().insert(attr.id); }); } pub fn is_known(attr: &Attribute) -> bool { - let AttrId(id) = attr.id; GLOBALS.with(|globals| { - let slot = globals.known_attrs.lock(); - let idx = (id / 64) as usize; - let shift = id % 64; - slot.get(idx).map(|bits| bits & (1 << shift) != 0) - .unwrap_or(false) + globals.known_attrs.lock().contains(attr.id) }) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 60de94821bba0..16507ec5a5dd5 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -43,6 +43,8 @@ extern crate rustc_target; extern crate serialize as rustc_serialize; // used by deriving use rustc_data_structures::sync::Lock; +use rustc_data_structures::bitvec::BitVector; +use ast::AttrId; // A variant of 'try!' that panics on an Err. This is used as a crutch on the // way towards a non-panic!-prone parser. It should be used for fatal parsing @@ -75,16 +77,18 @@ macro_rules! unwrap_or { } pub struct Globals { - used_attrs: Lock>, - known_attrs: Lock>, + used_attrs: Lock>, + known_attrs: Lock>, syntax_pos_globals: syntax_pos::Globals, } impl Globals { fn new() -> Globals { Globals { - used_attrs: Lock::new(Vec::new()), - known_attrs: Lock::new(Vec::new()), + // We have no idea how many attributes their will be, so just + // initiate the vectors with 0 bits. We'll grow them as necessary. + used_attrs: Lock::new(BitVector::new(0)), + known_attrs: Lock::new(BitVector::new(0)), syntax_pos_globals: syntax_pos::Globals::new(), } }