1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use rustc_data_structures::indexed_vec::Idx;
14 use serialize::{self, Encoder, Decoder};
19 newtype_index!(CrateNum nopub
21 /// Item definitions in the currently-compiled crate would have the CrateNum
22 /// LOCAL_CRATE in their DefId.
23 const LOCAL_CRATE = 0,
25 /// Virtual crate for builtin macros
26 // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
28 const BUILTIN_MACROS_CRATE = u32::MAX,
30 /// A CrateNum value that indicates that something is wrong.
31 const INVALID_CRATE = u32::MAX - 1,
35 pub fn new(x: usize) -> CrateNum {
36 assert!(x < (u32::MAX as usize));
40 pub fn from_u32(x: u32) -> CrateNum {
44 pub fn as_usize(&self) -> usize {
48 pub fn as_u32(&self) -> u32 {
52 pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
55 impl fmt::Display for CrateNum {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 fmt::Display::fmt(&self.0, f)
61 impl serialize::UseSpecializedEncodable for CrateNum {
62 fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
67 impl serialize::UseSpecializedDecodable for CrateNum {
68 fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
69 d.read_u32().map(CrateNum)
73 /// A DefIndex is an index into the hir-map for a crate, identifying a
74 /// particular definition. It should really be considered an interned
75 /// shorthand for a particular DefPath.
77 /// At the moment we are allocating the numerical values of DefIndexes into two
78 /// ranges: the "low" range (starting at zero) and the "high" range (starting at
79 /// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
80 /// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
81 /// consequently use a simple array for lookup tables keyed by DefIndex and
82 /// known to be densely populated. This is especially important for the HIR map.
84 /// Since the DefIndex is mostly treated as an opaque ID, you probably
85 /// don't have to care about these ranges.
86 #[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
87 RustcDecodable, Hash, Copy)]
88 pub struct DefIndex(u32);
90 impl Idx for DefIndex {
91 fn new(value: usize) -> Self {
92 assert!(value < (u32::MAX) as usize);
93 DefIndex(value as u32)
96 fn index(self) -> usize {
101 impl fmt::Debug for DefIndex {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 self.address_space().index(),
106 self.as_array_index())
112 pub fn new(x: usize) -> DefIndex {
113 assert!(x < (u32::MAX as usize));
118 pub fn from_u32(x: u32) -> DefIndex {
123 pub fn as_usize(&self) -> usize {
128 pub fn as_u32(&self) -> u32 {
133 pub fn address_space(&self) -> DefIndexAddressSpace {
134 if self.0 < DEF_INDEX_HI_START.0 {
135 DefIndexAddressSpace::Low
137 DefIndexAddressSpace::High
141 /// Converts this DefIndex into a zero-based array index.
142 /// This index is the offset within the given "range" of the DefIndex,
143 /// that is, if the DefIndex is part of the "high" range, the resulting
144 /// index will be (DefIndex - DEF_INDEX_HI_START).
146 pub fn as_array_index(&self) -> usize {
147 (self.0 & !DEF_INDEX_HI_START.0) as usize
150 pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
151 DefIndex::new(address_space.start() + i)
155 /// The start of the "high" range of DefIndexes.
156 const DEF_INDEX_HI_START: DefIndex = DefIndex(1 << 31);
158 /// The crate root is always assigned index 0 by the AST Map code,
159 /// thanks to `NodeCollector::new`.
160 pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
162 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
163 pub enum DefIndexAddressSpace {
168 impl DefIndexAddressSpace {
170 pub fn index(&self) -> usize {
175 pub fn start(&self) -> usize {
176 self.index() * DEF_INDEX_HI_START.as_usize()
180 /// A DefId identifies a particular *definition*, by combining a crate
181 /// index and a def index.
182 #[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
188 impl fmt::Debug for DefId {
189 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
190 write!(f, "DefId {{ krate: {:?}, index: {:?}",
191 self.krate, self.index)?;
193 ty::tls::with_opt(|opt_tcx| {
194 if let Some(tcx) = opt_tcx {
195 write!(f, " => {}", tcx.def_path_debug_str(*self))?;
206 /// Make a local `DefId` with the given index.
207 pub fn local(index: DefIndex) -> DefId {
208 DefId { krate: LOCAL_CRATE, index: index }
211 pub fn is_local(&self) -> bool {
212 self.krate == LOCAL_CRATE