1 use crate::HashStableContext
;
2 use rustc_data_structures
::fingerprint
::Fingerprint
;
3 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
4 use rustc_data_structures
::AtomicRef
;
5 use rustc_index
::vec
::Idx
;
6 use rustc_macros
::HashStable_Generic
;
7 use rustc_serialize
::{Decodable, Decoder, Encodable, Encoder}
;
8 use std
::borrow
::Borrow
;
11 rustc_index
::newtype_index
! {
17 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19 /// A special `CrateNum` that we use for the `tcx.rcache` when decoding from
20 /// the incr. comp. cache.
21 ReservedForIncrCompCache
,
25 /// Item definitions in the currently-compiled crate would have the `CrateNum`
26 /// `LOCAL_CRATE` in their `DefId`.
27 pub const LOCAL_CRATE
: CrateNum
= CrateNum
::Index(CrateId
::from_u32(0));
29 impl Idx
for CrateNum
{
31 fn new(value
: usize) -> Self {
32 CrateNum
::Index(Idx
::new(value
))
36 fn index(self) -> usize {
38 CrateNum
::Index(idx
) => Idx
::index(idx
),
39 _
=> panic
!("Tried to get crate index of {:?}", self),
45 pub fn new(x
: usize) -> CrateNum
{
46 CrateNum
::from_usize(x
)
49 pub fn from_usize(x
: usize) -> CrateNum
{
50 CrateNum
::Index(CrateId
::from_usize(x
))
53 pub fn from_u32(x
: u32) -> CrateNum
{
54 CrateNum
::Index(CrateId
::from_u32(x
))
57 pub fn as_usize(self) -> usize {
59 CrateNum
::Index(id
) => id
.as_usize(),
60 _
=> panic
!("tried to get index of non-standard crate {:?}", self),
64 pub fn as_u32(self) -> u32 {
66 CrateNum
::Index(id
) => id
.as_u32(),
67 _
=> panic
!("tried to get index of non-standard crate {:?}", self),
71 pub fn as_def_id(&self) -> DefId
{
72 DefId { krate: *self, index: CRATE_DEF_INDEX }
76 impl fmt
::Display
for CrateNum
{
77 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
79 CrateNum
::Index(id
) => fmt
::Display
::fmt(&id
.private
, f
),
80 CrateNum
::ReservedForIncrCompCache
=> write
!(f
, "crate for decoding incr comp cache"),
85 /// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
86 /// Therefore, make sure to include the context when encode a `CrateNum`.
87 impl<E
: Encoder
> Encodable
<E
> for CrateNum
{
88 default fn encode(&self, s
: &mut E
) -> Result
<(), E
::Error
> {
89 s
.emit_u32(self.as_u32())
93 impl<D
: Decoder
> Decodable
<D
> for CrateNum
{
94 default fn decode(d
: &mut D
) -> Result
<CrateNum
, D
::Error
> {
95 Ok(CrateNum
::from_u32(d
.read_u32()?
))
99 impl ::std
::fmt
::Debug
for CrateNum
{
100 fn fmt(&self, fmt
: &mut ::std
::fmt
::Formatter
<'_
>) -> ::std
::fmt
::Result
{
102 CrateNum
::Index(id
) => write
!(fmt
, "crate{}", id
.private
),
103 CrateNum
::ReservedForIncrCompCache
=> write
!(fmt
, "crate for decoding incr comp cache"),
108 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
109 #[derive(HashStable_Generic, Encodable, Decodable)]
110 pub struct DefPathHash(pub Fingerprint
);
112 impl Borrow
<Fingerprint
> for DefPathHash
{
114 fn borrow(&self) -> &Fingerprint
{
119 rustc_index
::newtype_index
! {
120 /// A DefIndex is an index into the hir-map for a crate, identifying a
121 /// particular definition. It should really be considered an interned
122 /// shorthand for a particular DefPath.
123 pub struct DefIndex
{
124 ENCODABLE
= custom
// (only encodable in metadata)
126 DEBUG_FORMAT
= "DefIndex({})",
127 /// The crate root is always assigned index 0 by the AST Map code,
128 /// thanks to `NodeCollector::new`.
129 const CRATE_DEF_INDEX
= 0,
133 impl<E
: Encoder
> Encodable
<E
> for DefIndex
{
134 default fn encode(&self, _
: &mut E
) -> Result
<(), E
::Error
> {
135 panic
!("cannot encode `DefIndex` with `{}`", std
::any
::type_name
::<E
>());
139 impl<D
: Decoder
> Decodable
<D
> for DefIndex
{
140 default fn decode(_
: &mut D
) -> Result
<DefIndex
, D
::Error
> {
141 panic
!("cannot decode `DefIndex` with `{}`", std
::any
::type_name
::<D
>());
145 /// A `DefId` identifies a particular *definition*, by combining a crate
146 /// index and a def index.
148 /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`.
149 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
156 /// Makes a local `DefId` from the given `DefIndex`.
158 pub fn local(index
: DefIndex
) -> DefId
{
159 DefId { krate: LOCAL_CRATE, index }
163 pub fn is_local(self) -> bool
{
164 self.krate
== LOCAL_CRATE
168 pub fn as_local(self) -> Option
<LocalDefId
> {
169 if self.is_local() { Some(LocalDefId { local_def_index: self.index }
) } else { None }
173 pub fn expect_local(self) -> LocalDefId
{
174 self.as_local().unwrap_or_else(|| panic
!("DefId::expect_local: `{:?}` isn't local", self))
177 pub fn is_top_level_module(self) -> bool
{
178 self.is_local() && self.index
== CRATE_DEF_INDEX
182 impl<E
: Encoder
> Encodable
<E
> for DefId
{
183 default fn encode(&self, s
: &mut E
) -> Result
<(), E
::Error
> {
184 s
.emit_struct("DefId", 2, |s
| {
185 s
.emit_struct_field("krate", 0, |s
| self.krate
.encode(s
))?
;
187 s
.emit_struct_field("index", 1, |s
| self.index
.encode(s
))
192 impl<D
: Decoder
> Decodable
<D
> for DefId
{
193 default fn decode(d
: &mut D
) -> Result
<DefId
, D
::Error
> {
194 d
.read_struct("DefId", 2, |d
| {
196 krate
: d
.read_struct_field("krate", 0, Decodable
::decode
)?
,
197 index
: d
.read_struct_field("index", 1, Decodable
::decode
)?
,
203 pub fn default_def_id_debug(def_id
: DefId
, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
204 f
.debug_struct("DefId").field("krate", &def_id
.krate
).field("index", &def_id
.index
).finish()
207 pub static DEF_ID_DEBUG
: AtomicRef
<fn(DefId
, &mut fmt
::Formatter
<'_
>) -> fmt
::Result
> =
208 AtomicRef
::new(&(default_def_id_debug
as fn(_
, &mut fmt
::Formatter
<'_
>) -> _
));
210 impl fmt
::Debug
for DefId
{
211 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
212 (*DEF_ID_DEBUG
)(*self, f
)
216 rustc_data_structures
::define_id_collections
!(DefIdMap
, DefIdSet
, DefId
);
218 /// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
219 /// we encode this information in the type, we can ensure at compile time that
220 /// no DefIds from upstream crates get thrown into the mix. There are quite a
221 /// few cases where we know that only DefIds from the local crate are expected
222 /// and a DefId from a different crate would signify a bug somewhere. This
223 /// is when LocalDefId comes in handy.
224 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
225 pub struct LocalDefId
{
226 pub local_def_index
: DefIndex
,
229 impl Idx
for LocalDefId
{
231 fn new(idx
: usize) -> Self {
232 LocalDefId { local_def_index: Idx::new(idx) }
235 fn index(self) -> usize {
236 self.local_def_index
.index()
242 pub fn to_def_id(self) -> DefId
{
243 DefId { krate: LOCAL_CRATE, index: self.local_def_index }
247 pub fn is_top_level_module(self) -> bool
{
248 self.local_def_index
== CRATE_DEF_INDEX
252 impl fmt
::Debug
for LocalDefId
{
253 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
254 self.to_def_id().fmt(f
)
258 impl<E
: Encoder
> Encodable
<E
> for LocalDefId
{
259 fn encode(&self, s
: &mut E
) -> Result
<(), E
::Error
> {
260 self.to_def_id().encode(s
)
264 impl<D
: Decoder
> Decodable
<D
> for LocalDefId
{
265 fn decode(d
: &mut D
) -> Result
<LocalDefId
, D
::Error
> {
266 DefId
::decode(d
).map(|d
| d
.expect_local())
270 impl<CTX
: HashStableContext
> HashStable
<CTX
> for DefId
{
271 fn hash_stable(&self, hcx
: &mut CTX
, hasher
: &mut StableHasher
) {
272 hcx
.hash_def_id(*self, hasher
)
276 impl<CTX
: HashStableContext
> HashStable
<CTX
> for CrateNum
{
277 fn hash_stable(&self, hcx
: &mut CTX
, hasher
: &mut StableHasher
) {
278 hcx
.hash_crate_num(*self, hasher
)