]> git.proxmox.com Git - rustc.git/blame - src/librustc/hir/def_id.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / librustc / hir / def_id.rs
CommitLineData
e9174d1e
SL
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.
4//
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.
10
54a0048b 11use ty;
9e0c209e
SL
12
13use rustc_data_structures::indexed_vec::Idx;
abe05a73 14use serialize;
e9174d1e 15use std::fmt;
b039eaaf 16use std::u32;
e9174d1e 17
abe05a73
XL
18newtype_index!(CrateNum
19 {
20 derive[Debug]
21 ENCODABLE = custom
9e0c209e 22
abe05a73
XL
23 /// Item definitions in the currently-compiled crate would have the CrateNum
24 /// LOCAL_CRATE in their DefId.
25 const LOCAL_CRATE = 0,
9e0c209e 26
abe05a73
XL
27 /// Virtual crate for builtin macros
28 // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
29 // `CrateNum`s.
30 const BUILTIN_MACROS_CRATE = u32::MAX,
9e0c209e 31
abe05a73
XL
32 /// A CrateNum value that indicates that something is wrong.
33 const INVALID_CRATE = u32::MAX - 1,
7cac9316 34
abe05a73
XL
35 /// A special CrateNum that we use for the tcx.rcache when decoding from
36 /// the incr. comp. cache.
37 const RESERVED_FOR_INCR_COMP_CACHE = u32::MAX - 2,
38 });
476ff2be 39
9e0c209e
SL
40impl CrateNum {
41 pub fn new(x: usize) -> CrateNum {
42 assert!(x < (u32::MAX as usize));
43 CrateNum(x as u32)
44 }
45
46 pub fn from_u32(x: u32) -> CrateNum {
47 CrateNum(x)
48 }
49
50 pub fn as_usize(&self) -> usize {
51 self.0 as usize
52 }
53
54 pub fn as_u32(&self) -> u32 {
55 self.0
56 }
041b39d2
XL
57
58 pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
9e0c209e
SL
59}
60
61impl fmt::Display for CrateNum {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 fmt::Display::fmt(&self.0, f)
64 }
65}
66
abe05a73
XL
67impl serialize::UseSpecializedEncodable for CrateNum {}
68impl serialize::UseSpecializedDecodable for CrateNum {}
9e0c209e 69
b039eaaf
SL
70/// A DefIndex is an index into the hir-map for a crate, identifying a
71/// particular definition. It should really be considered an interned
72/// shorthand for a particular DefPath.
cc61c64b
XL
73///
74/// At the moment we are allocating the numerical values of DefIndexes into two
75/// ranges: the "low" range (starting at zero) and the "high" range (starting at
76/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
77/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
78/// consequently use a simple array for lookup tables keyed by DefIndex and
79/// known to be densely populated. This is especially important for the HIR map.
80///
81/// Since the DefIndex is mostly treated as an opaque ID, you probably
82/// don't have to care about these ranges.
abe05a73
XL
83newtype_index!(DefIndex
84 {
85 ENCODABLE = custom
86 DEBUG_FORMAT = custom,
b039eaaf 87
abe05a73
XL
88 /// The start of the "high" range of DefIndexes.
89 const DEF_INDEX_HI_START = 1 << 31,
ea8adc8c 90
abe05a73
XL
91 /// The crate root is always assigned index 0 by the AST Map code,
92 /// thanks to `NodeCollector::new`.
93 const CRATE_DEF_INDEX = 0,
94 });
ea8adc8c
XL
95
96impl fmt::Debug for DefIndex {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 write!(f,
99 "DefIndex({}:{})",
100 self.address_space().index(),
101 self.as_array_index())
102 }
103}
104
b039eaaf 105impl DefIndex {
cc61c64b 106 #[inline]
b039eaaf
SL
107 pub fn from_u32(x: u32) -> DefIndex {
108 DefIndex(x)
109 }
110
cc61c64b 111 #[inline]
b039eaaf
SL
112 pub fn as_usize(&self) -> usize {
113 self.0 as usize
114 }
115
cc61c64b 116 #[inline]
b039eaaf
SL
117 pub fn as_u32(&self) -> u32 {
118 self.0
119 }
cc61c64b
XL
120
121 #[inline]
122 pub fn address_space(&self) -> DefIndexAddressSpace {
123 if self.0 < DEF_INDEX_HI_START.0 {
124 DefIndexAddressSpace::Low
125 } else {
126 DefIndexAddressSpace::High
127 }
128 }
129
130 /// Converts this DefIndex into a zero-based array index.
131 /// This index is the offset within the given "range" of the DefIndex,
132 /// that is, if the DefIndex is part of the "high" range, the resulting
133 /// index will be (DefIndex - DEF_INDEX_HI_START).
134 #[inline]
135 pub fn as_array_index(&self) -> usize {
136 (self.0 & !DEF_INDEX_HI_START.0) as usize
137 }
3b2f2976
XL
138
139 pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
140 DefIndex::new(address_space.start() + i)
141 }
b039eaaf
SL
142}
143
abe05a73
XL
144impl serialize::UseSpecializedEncodable for DefIndex {}
145impl serialize::UseSpecializedDecodable for DefIndex {}
b039eaaf 146
cc61c64b
XL
147#[derive(Copy, Clone, Eq, PartialEq, Hash)]
148pub enum DefIndexAddressSpace {
149 Low = 0,
150 High = 1,
151}
152
153impl DefIndexAddressSpace {
154 #[inline]
155 pub fn index(&self) -> usize {
156 *self as usize
157 }
158
159 #[inline]
160 pub fn start(&self) -> usize {
161 self.index() * DEF_INDEX_HI_START.as_usize()
162 }
163}
164
b039eaaf
SL
165/// A DefId identifies a particular *definition*, by combining a crate
166/// index and a def index.
abe05a73 167#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, Hash, Copy)]
e9174d1e
SL
168pub struct DefId {
169 pub krate: CrateNum,
b039eaaf 170 pub index: DefIndex,
e9174d1e
SL
171}
172
173impl fmt::Debug for DefId {
174 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ea8adc8c 175 write!(f, "DefId {{ krate: {:?}, index: {:?}",
54a0048b 176 self.krate, self.index)?;
e9174d1e 177
9e0c209e
SL
178 ty::tls::with_opt(|opt_tcx| {
179 if let Some(tcx) = opt_tcx {
ea8adc8c 180 write!(f, " => {}", tcx.def_path_debug_str(*self))?;
9e0c209e
SL
181 }
182 Ok(())
183 })?;
e9174d1e
SL
184
185 write!(f, " }}")
186 }
187}
188
e9174d1e 189impl DefId {
041b39d2 190 /// Make a local `DefId` with the given index.
abe05a73 191 #[inline]
b039eaaf
SL
192 pub fn local(index: DefIndex) -> DefId {
193 DefId { krate: LOCAL_CRATE, index: index }
e9174d1e
SL
194 }
195
abe05a73
XL
196 #[inline]
197 pub fn is_local(self) -> bool {
e9174d1e
SL
198 self.krate == LOCAL_CRATE
199 }
abe05a73
XL
200
201 #[inline]
202 pub fn to_local(self) -> LocalDefId {
203 LocalDefId::from_def_id(self)
204 }
e9174d1e 205}
abe05a73
XL
206
207impl serialize::UseSpecializedEncodable for DefId {}
208impl serialize::UseSpecializedDecodable for DefId {}
209
210/// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
211/// we encode this information in the type, we can ensure at compile time that
212/// no DefIds from upstream crates get thrown into the mix. There are quite a
213/// few cases where we know that only DefIds from the local crate are expected
214/// and a DefId from a different crate would signify a bug somewhere. This
215/// is when LocalDefId comes in handy.
216#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
217pub struct LocalDefId(DefIndex);
218
219impl LocalDefId {
220
221 #[inline]
222 pub fn from_def_id(def_id: DefId) -> LocalDefId {
223 assert!(def_id.is_local());
224 LocalDefId(def_id.index)
225 }
226
227 #[inline]
228 pub fn to_def_id(self) -> DefId {
229 DefId {
230 krate: LOCAL_CRATE,
231 index: self.0
232 }
233 }
234}
235
236impl fmt::Debug for LocalDefId {
237 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238 self.to_def_id().fmt(f)
239 }
240}
241
242impl serialize::UseSpecializedEncodable for LocalDefId {}
243impl serialize::UseSpecializedDecodable for LocalDefId {}