Skip to main content

rustc_span/
def_id.rs

1use std::fmt;
2use std::hash::{BuildHasherDefault, Hash, Hasher};
3
4use rustc_data_structures::AtomicRef;
5use rustc_data_structures::fingerprint::Fingerprint;
6use rustc_data_structures::stable_hasher::{
7    HashStable, HashStableContext, RawDefId, RawDefPathHash, StableHasher, StableOrd,
8    ToStableHashKey,
9};
10use rustc_data_structures::unhash::Unhasher;
11use rustc_hashes::Hash64;
12use rustc_index::Idx;
13use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable};
14use rustc_serialize::{Decodable, Encodable};
15
16use crate::{SpanDecoder, SpanEncoder, Symbol};
17
18pub type StableCrateIdMap =
19    indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;
20
21impl ::std::fmt::Debug for CrateNum {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("crate{0}", self.as_u32()))
    }
}rustc_index::newtype_index! {
22    #[orderable]
23    #[debug_format = "crate{}"]
24    pub struct CrateNum {}
25}
26
27/// Item definitions in the currently-compiled crate would have the `CrateNum`
28/// `LOCAL_CRATE` in their `DefId`.
29pub const LOCAL_CRATE: CrateNum = CrateNum::ZERO;
30
31impl CrateNum {
32    #[inline]
33    pub fn new(x: usize) -> CrateNum {
34        CrateNum::from_usize(x)
35    }
36
37    // FIXME(typed_def_id): Replace this with `as_mod_def_id`.
38    #[inline]
39    pub fn as_def_id(self) -> DefId {
40        DefId { krate: self, index: CRATE_DEF_INDEX }
41    }
42
43    #[inline]
44    pub fn as_mod_def_id(self) -> ModDefId {
45        ModDefId::new_unchecked(DefId { krate: self, index: CRATE_DEF_INDEX })
46    }
47}
48
49impl fmt::Display for CrateNum {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        fmt::Display::fmt(&self.as_u32(), f)
52    }
53}
54
55/// A `DefPathHash` is a fixed-size representation of a `DefPath` that is
56/// stable across crate and compilation session boundaries. It consists of two
57/// separate 64-bit hashes. The first uniquely identifies the crate this
58/// `DefPathHash` originates from (see [StableCrateId]), and the second
59/// uniquely identifies the corresponding `DefPath` within that crate. Together
60/// they form a unique identifier within an entire crate graph.
61///
62/// There is a very small chance of hash collisions, which would mean that two
63/// different `DefPath`s map to the same `DefPathHash`. Proceeding compilation
64/// with such a hash collision would very probably lead to an ICE, and in the
65/// worst case lead to a silent mis-compilation. The compiler therefore actively
66/// and exhaustively checks for such hash collisions and aborts compilation if
67/// it finds one.
68///
69/// `DefPathHash` uses 64-bit hashes for both the crate-id part and the
70/// crate-internal part, even though it is likely that there are many more
71/// `LocalDefId`s in a single crate than there are individual crates in a crate
72/// graph. Since we use the same number of bits in both cases, the collision
73/// probability for the crate-local part will be quite a bit higher (though
74/// still very small).
75///
76/// This imbalance is not by accident: A hash collision in the
77/// crate-local part of a `DefPathHash` will be detected and reported while
78/// compiling the crate in question. Such a collision does not depend on
79/// outside factors and can be easily fixed by the crate maintainer (e.g. by
80/// renaming the item in question or by bumping the crate version in a harmless
81/// way).
82///
83/// A collision between crate-id hashes on the other hand is harder to fix
84/// because it depends on the set of crates in the entire crate graph of a
85/// compilation session. Again, using the same crate with a different version
86/// number would fix the issue with a high probability -- but that might be
87/// easier said than done if the crates in questions are dependencies of
88/// third-party crates.
89///
90/// That being said, given a high quality hash function, the collision
91/// probabilities in question are very small. For example, for a big crate like
92/// `rustc_middle` (with ~50000 `LocalDefId`s as of the time of writing) there
93/// is a probability of roughly 1 in 14,750,000,000 of a crate-internal
94/// collision occurring. For a big crate graph with 1000 crates in it, there is
95/// a probability of 1 in 36,890,000,000,000 of a `StableCrateId` collision.
96#[derive(#[automatically_derived]
impl ::core::marker::Copy for DefPathHash { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DefPathHash {
    #[inline]
    fn clone(&self) -> DefPathHash {
        let _: ::core::clone::AssertParamIsClone<Fingerprint>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for DefPathHash {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for DefPathHash {
    #[inline]
    fn eq(&self, other: &DefPathHash) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DefPathHash {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Fingerprint>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for DefPathHash {
    #[inline]
    fn partial_cmp(&self, other: &DefPathHash)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for DefPathHash {
    #[inline]
    fn cmp(&self, other: &DefPathHash) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::fmt::Debug for DefPathHash {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "DefPathHash",
            &&self.0)
    }
}Debug)]
97#[derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::HashStable for
            DefPathHash {
            #[inline]
            fn hash_stable<__Hcx: ::rustc_data_structures::stable_hasher::HashStableContext>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    DefPathHash(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for DefPathHash {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    DefPathHash(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for DefPathHash {
            fn decode(__decoder: &mut __D) -> Self {
                DefPathHash(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };Decodable)]
98pub struct DefPathHash(pub Fingerprint);
99
100impl DefPathHash {
101    /// Returns the [StableCrateId] identifying the crate this [DefPathHash]
102    /// originates from.
103    #[inline]
104    pub fn stable_crate_id(&self) -> StableCrateId {
105        StableCrateId(self.0.split().0)
106    }
107
108    /// Returns the crate-local part of the [DefPathHash].
109    #[inline]
110    pub fn local_hash(&self) -> Hash64 {
111        self.0.split().1
112    }
113
114    /// Builds a new [DefPathHash] with the given [StableCrateId] and
115    /// `local_hash`, where `local_hash` must be unique within its crate.
116    #[inline]
117    pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
118        DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
119    }
120
121    #[inline]
122    pub fn to_raw_def_path_hash(self) -> RawDefPathHash {
123        RawDefPathHash(self.0.to_le_bytes())
124    }
125
126    #[inline]
127    pub fn from_raw_def_path_hash(RawDefPathHash(a): RawDefPathHash) -> DefPathHash {
128        DefPathHash(Fingerprint::from_le_bytes(a))
129    }
130}
131
132impl Default for DefPathHash {
133    fn default() -> Self {
134        DefPathHash(Fingerprint::ZERO)
135    }
136}
137
138impl StableOrd for DefPathHash {
139    const CAN_USE_UNSTABLE_SORT: bool = true;
140
141    // `DefPathHash` sort order is not affected by (de)serialization.
142    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
143}
144
145/// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
146/// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to
147/// [`DefId`]. It is stable across compilation sessions.
148///
149/// Since the ID is a hash value, there is a small chance that two crates
150/// end up with the same [`StableCrateId`]. The compiler will check for such
151/// collisions when loading crates and abort compilation in order to avoid
152/// further trouble.
153///
154/// For more information on the possibility of hash collisions in rustc,
155/// see the discussion in [`DefId`].
156#[derive(#[automatically_derived]
impl ::core::marker::Copy for StableCrateId { }Copy, #[automatically_derived]
impl ::core::clone::Clone for StableCrateId {
    #[inline]
    fn clone(&self) -> StableCrateId {
        let _: ::core::clone::AssertParamIsClone<Hash64>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for StableCrateId {
    #[inline]
    fn eq(&self, other: &StableCrateId) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for StableCrateId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Hash64>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for StableCrateId {
    #[inline]
    fn partial_cmp(&self, other: &StableCrateId)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for StableCrateId {
    #[inline]
    fn cmp(&self, other: &StableCrateId) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::fmt::Debug for StableCrateId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "StableCrateId",
            &&self.0)
    }
}Debug)]
157#[derive(#[automatically_derived]
impl ::core::hash::Hash for StableCrateId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::HashStable for
            StableCrateId {
            #[inline]
            fn hash_stable<__Hcx: ::rustc_data_structures::stable_hasher::HashStableContext>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    StableCrateId(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for StableCrateId {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    StableCrateId(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::BlobDecoder> ::rustc_serialize::Decodable<__D>
            for StableCrateId {
            fn decode(__decoder: &mut __D) -> Self {
                StableCrateId(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };BlobDecodable)]
158pub struct StableCrateId(pub(crate) Hash64);
159
160impl StableCrateId {
161    /// Computes the stable ID for a crate with the given name and
162    /// `-Cmetadata` arguments.
163    pub fn new(
164        crate_name: Symbol,
165        is_exe: bool,
166        mut metadata: Vec<String>,
167        cfg_version: &'static str,
168    ) -> StableCrateId {
169        let mut hasher = StableHasher::new();
170        // We must hash the string text of the crate name, not the id, as the id is not stable
171        // across builds.
172        crate_name.as_str().hash(&mut hasher);
173
174        // We don't want the stable crate ID to depend on the order of
175        // -C metadata arguments, so sort them:
176        metadata.sort();
177        // Every distinct -C metadata value is only incorporated once:
178        metadata.dedup();
179
180        hasher.write(b"metadata");
181        for s in &metadata {
182            // Also incorporate the length of a metadata string, so that we generate
183            // different values for `-Cmetadata=ab -Cmetadata=c` and
184            // `-Cmetadata=a -Cmetadata=bc`
185            hasher.write_usize(s.len());
186            hasher.write(s.as_bytes());
187        }
188
189        // Also incorporate crate type, so that we don't get symbol conflicts when
190        // linking against a library of the same name, if this is an executable.
191        hasher.write(if is_exe { b"exe" } else { b"lib" });
192
193        // Also incorporate the rustc version. Otherwise, with -Zsymbol-mangling-version=v0
194        // and no -Cmetadata, symbols from the same crate compiled with different versions of
195        // rustc are named the same.
196        //
197        // RUSTC_FORCE_RUSTC_VERSION is used to inject rustc version information
198        // during testing.
199        if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
200            hasher.write(val.to_string_lossy().into_owned().as_bytes())
201        } else {
202            hasher.write(cfg_version.as_bytes())
203        }
204
205        StableCrateId(hasher.finish())
206    }
207
208    #[inline]
209    pub fn as_u64(self) -> u64 {
210        self.0.as_u64()
211    }
212}
213
214impl fmt::LowerHex for StableCrateId {
215    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216        fmt::LowerHex::fmt(&self.0, f)
217    }
218}
219
220impl ::std::fmt::Debug for DefIndex {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_fmt(format_args!("DefIndex({0})", self.as_u32()))
    }
}rustc_index::newtype_index! {
221    /// A DefIndex is an index into the hir-map for a crate, identifying a
222    /// particular definition. It should really be considered an interned
223    /// shorthand for a particular DefPath.
224    #[orderable]
225    #[debug_format = "DefIndex({})"]
226    pub struct DefIndex {
227        /// The crate root is always assigned index 0 by the AST Map code,
228        /// thanks to `NodeCollector::new`.
229        const CRATE_DEF_INDEX = 0;
230    }
231}
232
233/// A `DefId` identifies a particular *definition*, by combining a crate
234/// index and a def index.
235///
236/// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`.
237#[derive(#[automatically_derived]
impl ::core::clone::Clone for DefId {
    #[inline]
    fn clone(&self) -> DefId {
        let _: ::core::clone::AssertParamIsClone<DefIndex>;
        let _: ::core::clone::AssertParamIsClone<CrateNum>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for DefId {
    #[inline]
    fn eq(&self, other: &DefId) -> bool {
        self.index == other.index && self.krate == other.krate
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DefId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefIndex>;
        let _: ::core::cmp::AssertParamIsEq<CrateNum>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::Copy for DefId { }Copy)]
238// On below-64 bit systems we can simply use the derived `Hash` impl
239#[cfg_attr(not(target_pointer_width = "64"), derive(Hash))]
240#[repr(C)]
241#[rustc_pass_by_value]
242// We guarantee field order. Note that the order is essential here, see below why.
243pub struct DefId {
244    // cfg-ing the order of fields so that the `DefIndex` which is high entropy always ends up in
245    // the lower bits no matter the endianness. This allows the compiler to turn that `Hash` impl
246    // into a direct call to `u64::hash(_)`.
247    #[cfg(not(all(target_pointer_width = "64", target_endian = "big")))]
248    pub index: DefIndex,
249    pub krate: CrateNum,
250    #[cfg(all(target_pointer_width = "64", target_endian = "big"))]
251    pub index: DefIndex,
252}
253
254// To ensure correctness of incremental compilation,
255// `DefId` must not implement `Ord` or `PartialOrd`.
256// See https://github.com/rust-lang/rust/issues/90317.
257impl !Ord for DefId {}
258impl !PartialOrd for DefId {}
259
260// On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This
261// improves performance without impairing `FxHash` quality. So the below code gets compiled to a
262// noop on little endian systems because the memory layout of `DefId` is as follows:
263//
264// ```
265//     +-1--------------31-+-32-------------63-+
266//     ! index             ! krate             !
267//     +-------------------+-------------------+
268// ```
269//
270// The order here has direct impact on `FxHash` quality because we have far more `DefIndex` per
271// crate than we have `Crate`s within one compilation. Or in other words, this arrangement puts
272// more entropy in the low bits than the high bits. The reason this matters is that `FxHash`, which
273// is used throughout rustc, has problems distributing the entropy from the high bits, so reversing
274// the order would lead to a large number of collisions and thus far worse performance.
275//
276// On 64-bit big-endian systems, this compiles to a 64-bit rotation by 32 bits, which is still
277// faster than another `FxHash` round.
278#[cfg(target_pointer_width = "64")]
279impl Hash for DefId {
280    fn hash<H: Hasher>(&self, h: &mut H) {
281        (((self.krate.as_u32() as u64) << 32) | (self.index.as_u32() as u64)).hash(h)
282    }
283}
284
285impl DefId {
286    /// Makes a local `DefId` from the given `DefIndex`.
287    #[inline]
288    pub fn local(index: DefIndex) -> DefId {
289        DefId { krate: LOCAL_CRATE, index }
290    }
291
292    /// Returns whether the item is defined in the crate currently being compiled.
293    #[inline]
294    pub fn is_local(self) -> bool {
295        self.krate == LOCAL_CRATE
296    }
297
298    #[inline]
299    pub fn as_local(self) -> Option<LocalDefId> {
300        self.is_local().then(|| LocalDefId { local_def_index: self.index })
301    }
302
303    #[inline]
304    #[track_caller]
305    pub fn expect_local(self) -> LocalDefId {
306        // NOTE: `match` below is required to apply `#[track_caller]`,
307        // i.e. don't use closures.
308        match self.as_local() {
309            Some(local_def_id) => local_def_id,
310            None => {
    ::core::panicking::panic_fmt(format_args!("DefId::expect_local: `{0:?}` isn\'t local",
            self));
}panic!("DefId::expect_local: `{self:?}` isn't local"),
311        }
312    }
313
314    #[inline]
315    pub fn is_crate_root(self) -> bool {
316        self.index == CRATE_DEF_INDEX
317    }
318
319    #[inline]
320    pub fn as_crate_root(self) -> Option<CrateNum> {
321        self.is_crate_root().then_some(self.krate)
322    }
323
324    #[inline]
325    pub fn is_top_level_module(self) -> bool {
326        self.is_local() && self.is_crate_root()
327    }
328
329    #[inline]
330    pub fn to_raw_def_id(self) -> RawDefId {
331        // Field order must match `from_raw_def_id`.
332        RawDefId(self.krate.as_u32(), self.index.as_u32())
333    }
334
335    #[inline]
336    pub fn from_raw_def_id(RawDefId(a, b): RawDefId) -> DefId {
337        // Field order must match `to_raw_def_id`.
338        DefId { krate: a.into(), index: b.into() }
339    }
340}
341
342impl From<LocalDefId> for DefId {
343    fn from(local: LocalDefId) -> DefId {
344        local.to_def_id()
345    }
346}
347
348pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349    f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
350}
351
352pub static DEF_ID_DEBUG: AtomicRef<fn(DefId, &mut fmt::Formatter<'_>) -> fmt::Result> =
353    AtomicRef::new(&(default_def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
354
355impl fmt::Debug for DefId {
356    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357        (*DEF_ID_DEBUG)(*self, f)
358    }
359}
360
361pub type DefIdMap<T> = ::rustc_data_structures::unord::UnordMap<DefId, T>;
pub type DefIdSet = ::rustc_data_structures::unord::UnordSet<DefId>;
pub type DefIdMapEntry<'a, T> =
    ::rustc_data_structures::fx::StdEntry<'a, DefId, T>;rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefIdMapEntry, DefId);
362
363/// A `LocalDefId` is equivalent to a `DefId` with `krate == LOCAL_CRATE`. Since
364/// we encode this information in the type, we can ensure at compile time that
365/// no `DefId`s from upstream crates get thrown into the mix. There are quite a
366/// few cases where we know that only `DefId`s from the local crate are expected;
367/// a `DefId` from a different crate would signify a bug somewhere. This
368/// is when `LocalDefId` comes in handy.
369#[derive(#[automatically_derived]
impl ::core::clone::Clone for LocalDefId {
    #[inline]
    fn clone(&self) -> LocalDefId {
        let _: ::core::clone::AssertParamIsClone<DefIndex>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LocalDefId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for LocalDefId {
    #[inline]
    fn eq(&self, other: &LocalDefId) -> bool {
        self.local_def_index == other.local_def_index
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LocalDefId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefIndex>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for LocalDefId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.local_def_index, state)
    }
}Hash)]
370pub struct LocalDefId {
371    pub local_def_index: DefIndex,
372}
373
374// To ensure correctness of incremental compilation,
375// `LocalDefId` must not implement `Ord` or `PartialOrd`.
376// See https://github.com/rust-lang/rust/issues/90317.
377impl !Ord for LocalDefId {}
378impl !PartialOrd for LocalDefId {}
379
380pub const CRATE_DEF_ID: LocalDefId = LocalDefId { local_def_index: CRATE_DEF_INDEX };
381
382impl Idx for LocalDefId {
383    #[inline]
384    fn new(idx: usize) -> Self {
385        LocalDefId { local_def_index: Idx::new(idx) }
386    }
387    #[inline]
388    fn index(self) -> usize {
389        self.local_def_index.index()
390    }
391}
392
393impl LocalDefId {
394    #[inline]
395    pub fn to_def_id(self) -> DefId {
396        DefId { krate: LOCAL_CRATE, index: self.local_def_index }
397    }
398
399    #[inline]
400    pub fn is_top_level_module(self) -> bool {
401        self == CRATE_DEF_ID
402    }
403}
404
405impl fmt::Debug for LocalDefId {
406    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
407        self.to_def_id().fmt(f)
408    }
409}
410
411impl<E: SpanEncoder> Encodable<E> for LocalDefId {
412    fn encode(&self, s: &mut E) {
413        self.to_def_id().encode(s);
414    }
415}
416
417impl<D: SpanDecoder> Decodable<D> for LocalDefId {
418    fn decode(d: &mut D) -> LocalDefId {
419        DefId::decode(d).expect_local()
420    }
421}
422
423pub type LocalDefIdMap<T> =
    ::rustc_data_structures::unord::UnordMap<LocalDefId, T>;
pub type LocalDefIdSet = ::rustc_data_structures::unord::UnordSet<LocalDefId>;
pub type LocalDefIdMapEntry<'a, T> =
    ::rustc_data_structures::fx::StdEntry<'a, LocalDefId, T>;rustc_data_structures::define_id_collections!(
424    LocalDefIdMap,
425    LocalDefIdSet,
426    LocalDefIdMapEntry,
427    LocalDefId
428);
429
430impl HashStable for DefId {
431    #[inline]
432    fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
433        self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
434    }
435}
436
437impl HashStable for LocalDefId {
438    #[inline]
439    fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
440        self.to_stable_hash_key(hcx).local_hash().hash_stable(hcx, hasher);
441    }
442}
443
444impl HashStable for CrateNum {
445    #[inline]
446    fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
447        self.as_def_id().to_stable_hash_key(hcx).stable_crate_id().hash_stable(hcx, hasher);
448    }
449}
450
451impl ToStableHashKey for DefId {
452    type KeyType = DefPathHash;
453
454    #[inline]
455    fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> DefPathHash {
456        DefPathHash::from_raw_def_path_hash(hcx.def_path_hash(self.to_raw_def_id()))
457    }
458}
459
460impl ToStableHashKey for LocalDefId {
461    type KeyType = DefPathHash;
462
463    #[inline]
464    fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> DefPathHash {
465        self.to_def_id().to_stable_hash_key(hcx)
466    }
467}
468
469impl ToStableHashKey for CrateNum {
470    type KeyType = DefPathHash;
471
472    #[inline]
473    fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> DefPathHash {
474        self.as_def_id().to_stable_hash_key(hcx)
475    }
476}
477
478impl ToStableHashKey for DefPathHash {
479    type KeyType = DefPathHash;
480
481    #[inline]
482    fn to_stable_hash_key<Hcx>(&self, _: &mut Hcx) -> DefPathHash {
483        *self
484    }
485}
486
487macro_rules! typed_def_id {
488    ($Name:ident, $LocalName:ident) => {
489        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
490        pub struct $Name(DefId);
491
492        impl $Name {
493            #[inline]
494            pub const fn new_unchecked(def_id: DefId) -> Self {
495                Self(def_id)
496            }
497
498            #[inline]
499            pub fn to_def_id(self) -> DefId {
500                self.into()
501            }
502
503            #[inline]
504            pub fn is_local(self) -> bool {
505                self.0.is_local()
506            }
507
508            #[inline]
509            pub fn as_local(self) -> Option<$LocalName> {
510                self.0.as_local().map($LocalName::new_unchecked)
511            }
512        }
513
514        impl From<$LocalName> for $Name {
515            #[inline]
516            fn from(local: $LocalName) -> Self {
517                Self(local.0.to_def_id())
518            }
519        }
520
521        impl From<$Name> for DefId {
522            #[inline]
523            fn from(typed: $Name) -> Self {
524                typed.0
525            }
526        }
527
528        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
529        pub struct $LocalName(LocalDefId);
530
531        impl !Ord for $LocalName {}
532        impl !PartialOrd for $LocalName {}
533
534        impl $LocalName {
535            #[inline]
536            pub const fn new_unchecked(def_id: LocalDefId) -> Self {
537                Self(def_id)
538            }
539
540            #[inline]
541            pub fn to_def_id(self) -> DefId {
542                self.0.into()
543            }
544
545            #[inline]
546            pub fn to_local_def_id(self) -> LocalDefId {
547                self.0
548            }
549        }
550
551        impl From<$LocalName> for LocalDefId {
552            #[inline]
553            fn from(typed: $LocalName) -> Self {
554                typed.0
555            }
556        }
557
558        impl From<$LocalName> for DefId {
559            #[inline]
560            fn from(typed: $LocalName) -> Self {
561                typed.0.into()
562            }
563        }
564    };
565}
566
567// N.B.: when adding new typed `DefId`s update the corresponding trait impls in
568// `rustc_middle::dep_graph::dep_node_key` for `DepNodeKey`.
569pub struct ModDefId(DefId);
#[automatically_derived]
impl ::core::fmt::Debug for ModDefId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "ModDefId",
            &&self.0)
    }
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for ModDefId { }
#[automatically_derived]
impl ::core::clone::Clone for ModDefId {
    #[inline]
    fn clone(&self) -> ModDefId {
        let _: ::core::clone::AssertParamIsClone<DefId>;
        *self
    }
}
#[automatically_derived]
impl ::core::marker::Copy for ModDefId { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for ModDefId { }
#[automatically_derived]
impl ::core::cmp::PartialEq for ModDefId {
    #[inline]
    fn eq(&self, other: &ModDefId) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::Eq for ModDefId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefId>;
    }
}
#[automatically_derived]
impl ::core::hash::Hash for ModDefId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}
const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for ModDefId {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    ModDefId(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };
const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for ModDefId {
            fn decode(__decoder: &mut __D) -> Self {
                ModDefId(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };
const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::HashStable for ModDefId {
            #[inline]
            fn hash_stable<__Hcx: ::rustc_data_structures::stable_hasher::HashStableContext>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    ModDefId(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };
impl ModDefId {
    #[inline]
    pub const fn new_unchecked(def_id: DefId) -> Self { Self(def_id) }
    #[inline]
    pub fn to_def_id(self) -> DefId { self.into() }
    #[inline]
    pub fn is_local(self) -> bool { self.0.is_local() }
    #[inline]
    pub fn as_local(self) -> Option<LocalModDefId> {
        self.0.as_local().map(LocalModDefId::new_unchecked)
    }
}
impl From<LocalModDefId> for ModDefId {
    #[inline]
    fn from(local: LocalModDefId) -> Self { Self(local.0.to_def_id()) }
}
impl From<ModDefId> for DefId {
    #[inline]
    fn from(typed: ModDefId) -> Self { typed.0 }
}
pub struct LocalModDefId(LocalDefId);
#[automatically_derived]
impl ::core::fmt::Debug for LocalModDefId {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "LocalModDefId",
            &&self.0)
    }
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LocalModDefId { }
#[automatically_derived]
impl ::core::clone::Clone for LocalModDefId {
    #[inline]
    fn clone(&self) -> LocalModDefId {
        let _: ::core::clone::AssertParamIsClone<LocalDefId>;
        *self
    }
}
#[automatically_derived]
impl ::core::marker::Copy for LocalModDefId { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for LocalModDefId { }
#[automatically_derived]
impl ::core::cmp::PartialEq for LocalModDefId {
    #[inline]
    fn eq(&self, other: &LocalModDefId) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::Eq for LocalModDefId {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<LocalDefId>;
    }
}
#[automatically_derived]
impl ::core::hash::Hash for LocalModDefId {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}
const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LocalModDefId {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    LocalModDefId(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };
const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LocalModDefId {
            fn decode(__decoder: &mut __D) -> Self {
                LocalModDefId(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };
const _: () =
    {
        impl ::rustc_data_structures::stable_hasher::HashStable for
            LocalModDefId {
            #[inline]
            fn hash_stable<__Hcx: ::rustc_data_structures::stable_hasher::HashStableContext>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    LocalModDefId(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };
impl !Ord for LocalModDefId {}
impl !PartialOrd for LocalModDefId {}
impl LocalModDefId {
    #[inline]
    pub const fn new_unchecked(def_id: LocalDefId) -> Self { Self(def_id) }
    #[inline]
    pub fn to_def_id(self) -> DefId { self.0.into() }
    #[inline]
    pub fn to_local_def_id(self) -> LocalDefId { self.0 }
}
impl From<LocalModDefId> for LocalDefId {
    #[inline]
    fn from(typed: LocalModDefId) -> Self { typed.0 }
}
impl From<LocalModDefId> for DefId {
    #[inline]
    fn from(typed: LocalModDefId) -> Self { typed.0.into() }
}typed_def_id! { ModDefId, LocalModDefId }
570
571impl LocalModDefId {
572    pub const CRATE_DEF_ID: Self = Self::new_unchecked(CRATE_DEF_ID);
573}
574
575impl ModDefId {
576    pub fn is_top_level_module(self) -> bool {
577        self.0.is_top_level_module()
578    }
579}
580
581impl LocalModDefId {
582    pub fn is_top_level_module(self) -> bool {
583        self.0.is_top_level_module()
584    }
585}