1use std::fmt;
2use std::hash::{BuildHasherDefault, Hash, Hasher};
34use 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};
1516use crate::{SpanDecoder, SpanEncoder, Symbol};
1718pub type StableCrateIdMap =
19 indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;
2021impl ::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{}"]
24pub struct CrateNum {}
25}2627/// Item definitions in the currently-compiled crate would have the `CrateNum`
28/// `LOCAL_CRATE` in their `DefId`.
29pub const LOCAL_CRATE: CrateNum = CrateNum::ZERO;
3031impl CrateNum {
32#[inline]
33pub fn new(x: usize) -> CrateNum {
34CrateNum::from_usize(x)
35 }
3637// FIXME(typed_def_id): Replace this with `as_mod_def_id`.
38#[inline]
39pub fn as_def_id(self) -> DefId {
40DefId { krate: self, index: CRATE_DEF_INDEX }
41 }
4243#[inline]
44pub fn as_mod_def_id(self) -> ModDefId {
45ModDefId::new_unchecked(DefId { krate: self, index: CRATE_DEF_INDEX })
46 }
47}
4849impl fmt::Displayfor CrateNum {
50fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 fmt::Display::fmt(&self.as_u32(), f)
52 }
53}
5455/// 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);
99100impl DefPathHash {
101/// Returns the [StableCrateId] identifying the crate this [DefPathHash]
102 /// originates from.
103#[inline]
104pub fn stable_crate_id(&self) -> StableCrateId {
105StableCrateId(self.0.split().0)
106 }
107108/// Returns the crate-local part of the [DefPathHash].
109#[inline]
110pub fn local_hash(&self) -> Hash64 {
111self.0.split().1
112}
113114/// Builds a new [DefPathHash] with the given [StableCrateId] and
115 /// `local_hash`, where `local_hash` must be unique within its crate.
116#[inline]
117pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
118DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
119 }
120121#[inline]
122pub fn to_raw_def_path_hash(self) -> RawDefPathHash {
123 RawDefPathHash(self.0.to_le_bytes())
124 }
125126#[inline]
127pub fn from_raw_def_path_hash(RawDefPathHash(a): RawDefPathHash) -> DefPathHash {
128DefPathHash(Fingerprint::from_le_bytes(a))
129 }
130}
131132impl Defaultfor DefPathHash {
133fn default() -> Self {
134DefPathHash(Fingerprint::ZERO)
135 }
136}
137138impl StableOrd for DefPathHash {
139const CAN_USE_UNSTABLE_SORT: bool = true;
140141// `DefPathHash` sort order is not affected by (de)serialization.
142const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
143}
144145/// 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);
159160impl StableCrateId {
161/// Computes the stable ID for a crate with the given name and
162 /// `-Cmetadata` arguments.
163pub fn new(
164 crate_name: Symbol,
165 is_exe: bool,
166mut metadata: Vec<String>,
167 cfg_version: &'static str,
168 ) -> StableCrateId {
169let 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.
172crate_name.as_str().hash(&mut hasher);
173174// We don't want the stable crate ID to depend on the order of
175 // -C metadata arguments, so sort them:
176metadata.sort();
177// Every distinct -C metadata value is only incorporated once:
178metadata.dedup();
179180hasher.write(b"metadata");
181for 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`
185hasher.write_usize(s.len());
186 hasher.write(s.as_bytes());
187 }
188189// 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.
191hasher.write(if is_exe { b"exe" } else { b"lib" });
192193// 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.
199if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
200hasher.write(val.to_string_lossy().into_owned().as_bytes())
201 } else {
202hasher.write(cfg_version.as_bytes())
203 }
204205StableCrateId(hasher.finish())
206 }
207208#[inline]
209pub fn as_u64(self) -> u64 {
210self.0.as_u64()
211 }
212}
213214impl fmt::LowerHexfor StableCrateId {
215fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 fmt::LowerHex::fmt(&self.0, f)
217 }
218}
219220impl ::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({})"]
226pub struct DefIndex {
227/// The crate root is always assigned index 0 by the AST Map code,
228 /// thanks to `NodeCollector::new`.
229const CRATE_DEF_INDEX = 0;
230 }
231}232233/// 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")))]
248pub index: DefIndex,
249pub krate: CrateNum,
250#[cfg(all(target_pointer_width = "64", target_endian = "big"))]
251pub index: DefIndex,
252}
253254// 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 !Ordfor DefId {}
258impl !PartialOrdfor DefId {}
259260// 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 Hashfor DefId {
280fn 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}
284285impl DefId {
286/// Makes a local `DefId` from the given `DefIndex`.
287#[inline]
288pub fn local(index: DefIndex) -> DefId {
289DefId { krate: LOCAL_CRATE, index }
290 }
291292/// Returns whether the item is defined in the crate currently being compiled.
293#[inline]
294pub fn is_local(self) -> bool {
295self.krate == LOCAL_CRATE296 }
297298#[inline]
299pub fn as_local(self) -> Option<LocalDefId> {
300self.is_local().then(|| LocalDefId { local_def_index: self.index })
301 }
302303#[inline]
304 #[track_caller]
305pub fn expect_local(self) -> LocalDefId {
306// NOTE: `match` below is required to apply `#[track_caller]`,
307 // i.e. don't use closures.
308match self.as_local() {
309Some(local_def_id) => local_def_id,
310None => {
::core::panicking::panic_fmt(format_args!("DefId::expect_local: `{0:?}` isn\'t local",
self));
}panic!("DefId::expect_local: `{self:?}` isn't local"),
311 }
312 }
313314#[inline]
315pub fn is_crate_root(self) -> bool {
316self.index == CRATE_DEF_INDEX317 }
318319#[inline]
320pub fn as_crate_root(self) -> Option<CrateNum> {
321self.is_crate_root().then_some(self.krate)
322 }
323324#[inline]
325pub fn is_top_level_module(self) -> bool {
326self.is_local() && self.is_crate_root()
327 }
328329#[inline]
330pub fn to_raw_def_id(self) -> RawDefId {
331// Field order must match `from_raw_def_id`.
332RawDefId(self.krate.as_u32(), self.index.as_u32())
333 }
334335#[inline]
336pub fn from_raw_def_id(RawDefId(a, b): RawDefId) -> DefId {
337// Field order must match `to_raw_def_id`.
338DefId { krate: a.into(), index: b.into() }
339 }
340}
341342impl From<LocalDefId> for DefId {
343fn from(local: LocalDefId) -> DefId {
344local.to_def_id()
345 }
346}
347348pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
350}
351352pub static DEF_ID_DEBUG: AtomicRef<fn(DefId, &mut fmt::Formatter<'_>) -> fmt::Result> =
353 AtomicRef::new(&(default_def_id_debugas fn(_, &mut fmt::Formatter<'_>) -> _));
354355impl fmt::Debugfor DefId {
356fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357 (*DEF_ID_DEBUG)(*self, f)
358 }
359}
360361pub 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);
362363/// 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 {
371pub local_def_index: DefIndex,
372}
373374// 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 !Ordfor LocalDefId {}
378impl !PartialOrdfor LocalDefId {}
379380pub const CRATE_DEF_ID: LocalDefId = LocalDefId { local_def_index: CRATE_DEF_INDEX };
381382impl Idx for LocalDefId {
383#[inline]
384fn new(idx: usize) -> Self {
385LocalDefId { local_def_index: Idx::new(idx) }
386 }
387#[inline]
388fn index(self) -> usize {
389self.local_def_index.index()
390 }
391}
392393impl LocalDefId {
394#[inline]
395pub fn to_def_id(self) -> DefId {
396DefId { krate: LOCAL_CRATE, index: self.local_def_index }
397 }
398399#[inline]
400pub fn is_top_level_module(self) -> bool {
401self == CRATE_DEF_ID402 }
403}
404405impl fmt::Debugfor LocalDefId {
406fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
407self.to_def_id().fmt(f)
408 }
409}
410411impl<E: SpanEncoder> Encodable<E> for LocalDefId {
412fn encode(&self, s: &mut E) {
413self.to_def_id().encode(s);
414 }
415}
416417impl<D: SpanDecoder> Decodable<D> for LocalDefId {
418fn decode(d: &mut D) -> LocalDefId {
419DefId::decode(d).expect_local()
420 }
421}
422423pub 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!(
424LocalDefIdMap,
425LocalDefIdSet,
426LocalDefIdMapEntry,
427 LocalDefId
428);
429430impl HashStable for DefId {
431#[inline]
432fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
433self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
434 }
435}
436437impl HashStable for LocalDefId {
438#[inline]
439fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
440self.to_stable_hash_key(hcx).local_hash().hash_stable(hcx, hasher);
441 }
442}
443444impl HashStable for CrateNum {
445#[inline]
446fn hash_stable<Hcx: HashStableContext>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
447self.as_def_id().to_stable_hash_key(hcx).stable_crate_id().hash_stable(hcx, hasher);
448 }
449}
450451impl ToStableHashKey for DefId {
452type KeyType = DefPathHash;
453454#[inline]
455fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> DefPathHash {
456DefPathHash::from_raw_def_path_hash(hcx.def_path_hash(self.to_raw_def_id()))
457 }
458}
459460impl ToStableHashKey for LocalDefId {
461type KeyType = DefPathHash;
462463#[inline]
464fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> DefPathHash {
465self.to_def_id().to_stable_hash_key(hcx)
466 }
467}
468469impl ToStableHashKey for CrateNum {
470type KeyType = DefPathHash;
471472#[inline]
473fn to_stable_hash_key<Hcx: HashStableContext>(&self, hcx: &mut Hcx) -> DefPathHash {
474self.as_def_id().to_stable_hash_key(hcx)
475 }
476}
477478impl ToStableHashKey for DefPathHash {
479type KeyType = DefPathHash;
480481#[inline]
482fn to_stable_hash_key<Hcx>(&self, _: &mut Hcx) -> DefPathHash {
483*self484 }
485}
486487macro_rules!typed_def_id {
488 ($Name:ident, $LocalName:ident) => {
489#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
490pub struct $Name(DefId);
491492impl $Name {
493#[inline]
494pub const fn new_unchecked(def_id: DefId) -> Self {
495Self(def_id)
496 }
497498#[inline]
499pub fn to_def_id(self) -> DefId {
500self.into()
501 }
502503#[inline]
504pub fn is_local(self) -> bool {
505self.0.is_local()
506 }
507508#[inline]
509pub fn as_local(self) -> Option<$LocalName> {
510self.0.as_local().map($LocalName::new_unchecked)
511 }
512 }
513514impl From<$LocalName> for $Name {
515#[inline]
516fn from(local: $LocalName) -> Self {
517Self(local.0.to_def_id())
518 }
519 }
520521impl From<$Name> for DefId {
522#[inline]
523fn from(typed: $Name) -> Self {
524 typed.0
525}
526 }
527528#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
529pub struct $LocalName(LocalDefId);
530531impl !Ord for $LocalName {}
532impl !PartialOrd for $LocalName {}
533534impl $LocalName {
535#[inline]
536pub const fn new_unchecked(def_id: LocalDefId) -> Self {
537Self(def_id)
538 }
539540#[inline]
541pub fn to_def_id(self) -> DefId {
542self.0.into()
543 }
544545#[inline]
546pub fn to_local_def_id(self) -> LocalDefId {
547self.0
548}
549 }
550551impl From<$LocalName> for LocalDefId {
552#[inline]
553fn from(typed: $LocalName) -> Self {
554 typed.0
555}
556 }
557558impl From<$LocalName> for DefId {
559#[inline]
560fn from(typed: $LocalName) -> Self {
561 typed.0.into()
562 }
563 }
564 };
565}
566567// 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 }570571impl LocalModDefId {
572pub const CRATE_DEF_ID: Self = Self::new_unchecked(CRATE_DEF_ID);
573}
574575impl ModDefId {
576pub fn is_top_level_module(self) -> bool {
577self.0.is_top_level_module()
578 }
579}
580581impl LocalModDefId {
582pub fn is_top_level_module(self) -> bool {
583self.0.is_top_level_module()
584 }
585}