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_hash::{
7 RawDefId, StableHash, StableHashCtxt, StableHasher, StableOrd, ToStableHashKey,
8};
9use rustc_data_structures::unhash::Unhasher;
10use rustc_hashes::Hash64;
11use rustc_index::Idx;
12use rustc_macros::{BlobDecodable, Decodable, Encodable, StableHash};
13use rustc_serialize::{ContextOrd, Decodable, Encodable};
1415use crate::{BlobDecoder, SpanEncoder, Symbol};
1617pub type StableCrateIdMap =
18 indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;
1920#[automatically_derived]impl ::core::marker::Copy for CrateNum { }
impl CrateNum {
#[doc = r" Maximum value the index can take, as a `u32`."]
pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
#[doc = r" Maximum value the index can take."]
pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
#[doc = r" Zero value of the index."]
pub const ZERO: Self = Self::from_u32(0);
#[doc = r" Creates a new index from a given `usize`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_usize(value: usize) -> Self {
if !(value <= (0xFFFF_FF00 as usize)) {
::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
};
unsafe { Self::from_u32_unchecked(value as u32) }
}
#[doc = r" Creates a new index from a given `u32`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_u32(value: u32) -> Self {
if !(value <= 0xFFFF_FF00) {
::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
};
unsafe { Self::from_u32_unchecked(value) }
}
#[doc = r" Creates a new index from a given `u16`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_u16(value: u16) -> Self {
let value = value as u32;
if !(value <= 0xFFFF_FF00) {
::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
};
unsafe { Self::from_u32_unchecked(value) }
}
#[doc = r" Creates a new index from a given `u32`."]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc =
r" The provided value must be less than or equal to the maximum value for the newtype."]
#[doc =
r" Providing a value outside this range is undefined due to layout restrictions."]
#[doc = r""]
#[doc = r" Prefer using `from_u32`."]
#[inline]
pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
Self {
private_use_as_methods_instead: unsafe {
std::mem::transmute(value)
},
}
}
#[doc = r" Extracts the value of this index as a `usize`."]
#[inline]
pub const fn index(self) -> usize { self.as_usize() }
#[doc = r" Extracts the value of this index as a `u32`."]
#[inline]
pub const fn as_u32(self) -> u32 {
unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
}
#[doc = r" Extracts the value of this index as a `usize`."]
#[inline]
pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for CrateNum {
type Output = Self;
#[inline]
fn add(self, other: usize) -> Self {
Self::from_usize(self.index() + other)
}
}
impl std::ops::AddAssign<usize> for CrateNum {
#[inline]
fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for CrateNum {
#[inline]
fn new(value: usize) -> Self { Self::from_usize(value) }
#[inline]
fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for CrateNum {
#[inline]
fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
<usize as
::std::iter::Step>::steps_between(&Self::index(*start),
&Self::index(*end))
}
#[inline]
fn forward_checked(start: Self, u: usize) -> Option<Self> {
Self::index(start).checked_add(u).map(Self::from_usize)
}
#[inline]
fn backward_checked(start: Self, u: usize) -> Option<Self> {
Self::index(start).checked_sub(u).map(Self::from_usize)
}
#[inline]
fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
let (s, o) = Self::index(start).overflowing_add(u);
(Self::from_usize(s), o)
}
#[inline]
fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
let (s, o) = Self::index(start).overflowing_sub(u);
(Self::from_usize(s), o)
}
}
impl ::std::cmp::Ord for CrateNum {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_u32().cmp(&other.as_u32())
}
}
impl ::std::cmp::PartialOrd for CrateNum {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl From<CrateNum> for u32 {
#[inline]
fn from(v: CrateNum) -> u32 { v.as_u32() }
}
impl From<CrateNum> for usize {
#[inline]
fn from(v: CrateNum) -> usize { v.as_usize() }
}
impl From<usize> for CrateNum {
#[inline]
fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for CrateNum {
#[inline]
fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for CrateNum {}
impl ::std::cmp::PartialEq for CrateNum {
fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for CrateNum {}
impl ::std::hash::Hash for CrateNum {
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
self.as_u32().hash(state)
}
}
impl ::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! {
21#[orderable]
22 #[debug_format = "crate{}"]
23pub struct CrateNum {}
24}2526impl<E: SpanEncoder> ContextOrd<&E> for CrateNum {
27fn stable_cmp_with_context(context: &E) -> impl FnMut(&Self, &Self) -> std::cmp::Ordering {
28let hasher = context.def_path_hasher();
29move |id1, id2| hasher(id1.as_def_id()).cmp(&hasher(id2.as_def_id()))
30 }
31}
3233/// Item definitions in the currently-compiled crate would have the `CrateNum`
34/// `LOCAL_CRATE` in their `DefId`.
35pub const LOCAL_CRATE: CrateNum = CrateNum::ZERO;
3637impl CrateNum {
38#[inline]
39pub fn new(x: usize) -> CrateNum {
40CrateNum::from_usize(x)
41 }
4243// FIXME(typed_def_id): Replace this with `as_mod_def_id`.
44#[inline]
45pub fn as_def_id(self) -> DefId {
46DefId { krate: self, index: CRATE_DEF_INDEX }
47 }
4849#[inline]
50pub fn as_mod_id(self) -> ModId {
51ModId::new_unchecked(DefId { krate: self, index: CRATE_DEF_INDEX })
52 }
53}
5455impl fmt::Displayfor CrateNum {
56fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 fmt::Display::fmt(&self.as_u32(), f)
58 }
59}
6061/// A `DefPathHash` is a fixed-size representation of a `DefPath` that is
62/// stable across crate and compilation session boundaries. It consists of two
63/// separate 64-bit hashes. The first uniquely identifies the crate this
64/// `DefPathHash` originates from (see [StableCrateId]), and the second
65/// uniquely identifies the corresponding `DefPath` within that crate. Together
66/// they form a unique identifier within an entire crate graph.
67///
68/// There is a very small chance of hash collisions, which would mean that two
69/// different `DefPath`s map to the same `DefPathHash`. Proceeding compilation
70/// with such a hash collision would very probably lead to an ICE, and in the
71/// worst case lead to a silent mis-compilation. The compiler therefore actively
72/// and exhaustively checks for such hash collisions and aborts compilation if
73/// it finds one.
74///
75/// `DefPathHash` uses 64-bit hashes for both the crate-id part and the
76/// crate-internal part, even though it is likely that there are many more
77/// `LocalDefId`s in a single crate than there are individual crates in a crate
78/// graph. Since we use the same number of bits in both cases, the collision
79/// probability for the crate-local part will be quite a bit higher (though
80/// still very small).
81///
82/// This imbalance is not by accident: A hash collision in the
83/// crate-local part of a `DefPathHash` will be detected and reported while
84/// compiling the crate in question. Such a collision does not depend on
85/// outside factors and can be easily fixed by the crate maintainer (e.g. by
86/// renaming the item in question or by bumping the crate version in a harmless
87/// way).
88///
89/// A collision between crate-id hashes on the other hand is harder to fix
90/// because it depends on the set of crates in the entire crate graph of a
91/// compilation session. Again, using the same crate with a different version
92/// number would fix the issue with a high probability -- but that might be
93/// easier said than done if the crates in questions are dependencies of
94/// third-party crates.
95///
96/// That being said, given a high quality hash function, the collision
97/// probabilities in question are very small. For example, for a big crate like
98/// `rustc_middle` (with ~50000 `LocalDefId`s as of the time of writing) there
99/// is a probability of roughly 1 in 14,750,000,000 of a crate-internal
100/// collision occurring. For a big crate graph with 1000 crates in it, there is
101/// a probability of 1 in 36,890,000,000,000 of a `StableCrateId` collision.
102#[derive(#[automatically_derived]impl ::core::marker::Copy for DefPathHash { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for DefPathHash {
}
#[automatically_derived]impl ::core::clone::Clone for DefPathHash {
#[inline]
fn clone(&self) -> Self {
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::marker::StructuralPartialEq for
DefPathHash {
}
#[automatically_derived]impl ::core::cmp::PartialEq for DefPathHash {
#[inline]
fn eq(&self, other: &Self) -> 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: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]impl ::core::cmp::Ord for DefPathHash {
#[inline]
fn cmp(&self, other: &Self) -> ::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_struct_field1_finish(f, "DefPathHash",
&&self.0)
}
}Debug)]
103#[derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for DefPathHash
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
DefPathHash(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for DefPathHash {
fn encode(&self, __encoder: &mut __E) {
let DefPathHash(ref __binding_0) = *self;
::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)]
104pub struct DefPathHash(pub Fingerprint);
105106impl DefPathHash {
107/// Returns the [StableCrateId] identifying the crate this [DefPathHash]
108 /// originates from.
109#[inline]
110pub fn stable_crate_id(&self) -> StableCrateId {
111StableCrateId(self.0.split().0)
112 }
113114/// Returns the crate-local part of the [DefPathHash].
115#[inline]
116pub fn local_hash(&self) -> Hash64 {
117self.0.split().1
118}
119120/// Builds a new [DefPathHash] with the given [StableCrateId] and
121 /// `local_hash`, where `local_hash` must be unique within its crate.
122#[inline]
123pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash {
124DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash))
125 }
126}
127128impl Defaultfor DefPathHash {
129fn default() -> Self {
130DefPathHash(Fingerprint::ZERO)
131 }
132}
133134impl StableOrd for DefPathHash {
135const CAN_USE_UNSTABLE_SORT: bool = true;
136137// `DefPathHash` sort order is not affected by (de)serialization.
138const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
139}
140141/// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
142/// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to
143/// [`DefId`]. It is stable across compilation sessions.
144///
145/// Since the ID is a hash value, there is a small chance that two crates
146/// end up with the same [`StableCrateId`]. The compiler will check for such
147/// collisions when loading crates and abort compilation in order to avoid
148/// further trouble.
149///
150/// For more information on the possibility of hash collisions in rustc,
151/// see the discussion in [`DefId`].
152#[derive(#[automatically_derived]impl ::core::marker::Copy for StableCrateId { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for StableCrateId {
}
#[automatically_derived]impl ::core::clone::Clone for StableCrateId {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Hash64>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
StableCrateId {
}
#[automatically_derived]impl ::core::cmp::PartialEq for StableCrateId {
#[inline]
fn eq(&self, other: &Self) -> 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: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]impl ::core::cmp::Ord for StableCrateId {
#[inline]
fn cmp(&self, other: &Self) -> ::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_struct_field1_finish(f, "StableCrateId",
&&self.0)
}
}Debug)]
153#[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_hash::StableHash for
StableCrateId {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
StableCrateId(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for StableCrateId {
fn encode(&self, __encoder: &mut __E) {
let StableCrateId(ref __binding_0) = *self;
::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)]
154pub struct StableCrateId(pub(crate) Hash64);
155156impl StableCrateId {
157/// Computes the stable ID for a crate with the given name and
158 /// `-Cmetadata` arguments.
159pub fn new(
160 crate_name: Symbol,
161 is_exe: bool,
162mut metadata: Vec<String>,
163 cfg_version: &'static str,
164 ) -> StableCrateId {
165let mut hasher = StableHasher::new();
166// We must hash the string text of the crate name, not the id, as the id is not stable
167 // across builds.
168crate_name.as_str().hash(&mut hasher);
169170// We don't want the stable crate ID to depend on the order of
171 // -C metadata arguments, so sort them:
172metadata.sort();
173// Every distinct -C metadata value is only incorporated once:
174metadata.dedup();
175176hasher.write(b"metadata");
177for s in &metadata {
178// Also incorporate the length of a metadata string, so that we generate
179 // different values for `-Cmetadata=ab -Cmetadata=c` and
180 // `-Cmetadata=a -Cmetadata=bc`
181hasher.write_usize(s.len());
182 hasher.write(s.as_bytes());
183 }
184185// Also incorporate crate type, so that we don't get symbol conflicts when
186 // linking against a library of the same name, if this is an executable.
187hasher.write(if is_exe { b"exe" } else { b"lib" });
188189// Also incorporate the rustc version. Otherwise, with -Zsymbol-mangling-version=v0
190 // and no -Cmetadata, symbols from the same crate compiled with different versions of
191 // rustc are named the same.
192 //
193 // RUSTC_FORCE_RUSTC_VERSION is used to inject rustc version information
194 // during testing.
195if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
196hasher.write(val.to_string_lossy().into_owned().as_bytes())
197 } else {
198hasher.write(cfg_version.as_bytes())
199 }
200201StableCrateId(hasher.finish())
202 }
203204#[inline]
205pub fn as_hash(self) -> Hash64 {
206self.0
207}
208209#[inline]
210pub fn as_u64(self) -> u64 {
211self.0.as_u64()
212 }
213}
214215impl fmt::LowerHexfor StableCrateId {
216fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 fmt::LowerHex::fmt(&self.0, f)
218 }
219}
220221#[automatically_derived]impl ::core::marker::Copy for DefIndex { }
#[doc = " The crate root is always assigned index 0 by the AST Map code,"]
#[doc = " thanks to `NodeCollector::new`."]
pub const CRATE_DEF_INDEX: DefIndex = DefIndex::from_u32(0);
impl DefIndex {
#[doc = r" Maximum value the index can take, as a `u32`."]
pub const MAX_AS_U32: u32 = 0xFFFF_FF00;
#[doc = r" Maximum value the index can take."]
pub const MAX: Self = Self::from_u32(0xFFFF_FF00);
#[doc = r" Zero value of the index."]
pub const ZERO: Self = Self::from_u32(0);
#[doc = r" Creates a new index from a given `usize`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_usize(value: usize) -> Self {
if !(value <= (0xFFFF_FF00 as usize)) {
::core::panicking::panic("assertion failed: value <= (0xFFFF_FF00 as usize)")
};
unsafe { Self::from_u32_unchecked(value as u32) }
}
#[doc = r" Creates a new index from a given `u32`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_u32(value: u32) -> Self {
if !(value <= 0xFFFF_FF00) {
::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
};
unsafe { Self::from_u32_unchecked(value) }
}
#[doc = r" Creates a new index from a given `u16`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" Will panic if `value` exceeds `MAX`."]
#[inline]
pub const fn from_u16(value: u16) -> Self {
let value = value as u32;
if !(value <= 0xFFFF_FF00) {
::core::panicking::panic("assertion failed: value <= 0xFFFF_FF00")
};
unsafe { Self::from_u32_unchecked(value) }
}
#[doc = r" Creates a new index from a given `u32`."]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc =
r" The provided value must be less than or equal to the maximum value for the newtype."]
#[doc =
r" Providing a value outside this range is undefined due to layout restrictions."]
#[doc = r""]
#[doc = r" Prefer using `from_u32`."]
#[inline]
pub const unsafe fn from_u32_unchecked(value: u32) -> Self {
Self {
private_use_as_methods_instead: unsafe {
std::mem::transmute(value)
},
}
}
#[doc = r" Extracts the value of this index as a `usize`."]
#[inline]
pub const fn index(self) -> usize { self.as_usize() }
#[doc = r" Extracts the value of this index as a `u32`."]
#[inline]
pub const fn as_u32(self) -> u32 {
unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
}
#[doc = r" Extracts the value of this index as a `usize`."]
#[inline]
pub const fn as_usize(self) -> usize { self.as_u32() as usize }
}
impl std::ops::Add<usize> for DefIndex {
type Output = Self;
#[inline]
fn add(self, other: usize) -> Self {
Self::from_usize(self.index() + other)
}
}
impl std::ops::AddAssign<usize> for DefIndex {
#[inline]
fn add_assign(&mut self, other: usize) { *self = *self + other; }
}
impl rustc_index::Idx for DefIndex {
#[inline]
fn new(value: usize) -> Self { Self::from_usize(value) }
#[inline]
fn index(self) -> usize { self.as_usize() }
}
impl ::std::iter::Step for DefIndex {
#[inline]
fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
<usize as
::std::iter::Step>::steps_between(&Self::index(*start),
&Self::index(*end))
}
#[inline]
fn forward_checked(start: Self, u: usize) -> Option<Self> {
Self::index(start).checked_add(u).map(Self::from_usize)
}
#[inline]
fn backward_checked(start: Self, u: usize) -> Option<Self> {
Self::index(start).checked_sub(u).map(Self::from_usize)
}
#[inline]
fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
let (s, o) = Self::index(start).overflowing_add(u);
(Self::from_usize(s), o)
}
#[inline]
fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
let (s, o) = Self::index(start).overflowing_sub(u);
(Self::from_usize(s), o)
}
}
impl ::std::cmp::Ord for DefIndex {
#[inline]
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_u32().cmp(&other.as_u32())
}
}
impl ::std::cmp::PartialOrd for DefIndex {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl From<DefIndex> for u32 {
#[inline]
fn from(v: DefIndex) -> u32 { v.as_u32() }
}
impl From<DefIndex> for usize {
#[inline]
fn from(v: DefIndex) -> usize { v.as_usize() }
}
impl From<usize> for DefIndex {
#[inline]
fn from(value: usize) -> Self { Self::from_usize(value) }
}
impl From<u32> for DefIndex {
#[inline]
fn from(value: u32) -> Self { Self::from_u32(value) }
}
impl ::std::cmp::Eq for DefIndex {}
impl ::std::cmp::PartialEq for DefIndex {
fn eq(&self, other: &Self) -> bool { self.as_u32().eq(&other.as_u32()) }
}
impl ::std::marker::StructuralPartialEq for DefIndex {}
impl ::std::hash::Hash for DefIndex {
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
self.as_u32().hash(state)
}
}
impl ::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! {
222/// A DefIndex is an index into the hir-map for a crate, identifying a
223 /// particular definition. It should really be considered an interned
224 /// shorthand for a particular DefPath.
225#[orderable]
226 #[debug_format = "DefIndex({})"]
227pub struct DefIndex {
228/// The crate root is always assigned index 0 by the AST Map code,
229 /// thanks to `NodeCollector::new`.
230const CRATE_DEF_INDEX = 0;
231 }
232}233234/// A `DefId` identifies a particular *definition*, by combining a crate
235/// index and a def index.
236///
237/// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`.
238#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for DefId {
}
#[automatically_derived]impl ::core::clone::Clone for DefId {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<DefIndex>;
let _: ::core::clone::AssertParamIsClone<CrateNum>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::StructuralPartialEq for DefId { }
#[automatically_derived]impl ::core::cmp::PartialEq for DefId {
#[inline]
fn eq(&self, other: &Self) -> 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)]
239// On below-64 bit systems we can simply use the derived `Hash` impl
240#[cfg_attr(not(target_pointer_width = "64"), derive(Hash))]
241#[repr(C)]
242#[rustc_pass_by_value]
243// We guarantee field order. Note that the order is essential here, see below why.
244pub struct DefId {
245// cfg-ing the order of fields so that the `DefIndex` which is high entropy always ends up in
246 // the lower bits no matter the endianness. This allows the compiler to turn that `Hash` impl
247 // into a direct call to `u64::hash(_)`.
248#[cfg(not(all(target_pointer_width = "64", target_endian = "big")))]
249pub index: DefIndex,
250pub krate: CrateNum,
251#[cfg(all(target_pointer_width = "64", target_endian = "big"))]
252pub index: DefIndex,
253}
254255// To ensure correctness of incremental compilation,
256// `DefId` must not implement `Ord` or `PartialOrd`.
257// See https://github.com/rust-lang/rust/issues/90317.
258impl !Ordfor DefId {}
259impl !PartialOrdfor DefId {}
260261// On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This
262// improves performance without impairing `FxHash` quality. So the below code gets compiled to a
263// noop on little endian systems because the memory layout of `DefId` is as follows:
264//
265// ```
266// +-1--------------31-+-32-------------63-+
267// ! index ! krate !
268// +-------------------+-------------------+
269// ```
270//
271// The order here has direct impact on `FxHash` quality because we have far more `DefIndex` per
272// crate than we have `Crate`s within one compilation. Or in other words, this arrangement puts
273// more entropy in the low bits than the high bits. The reason this matters is that `FxHash`, which
274// is used throughout rustc, has problems distributing the entropy from the high bits, so reversing
275// the order would lead to a large number of collisions and thus far worse performance.
276//
277// On 64-bit big-endian systems, this compiles to a 64-bit rotation by 32 bits, which is still
278// faster than another `FxHash` round.
279#[cfg(target_pointer_width = "64")]
280impl Hashfor DefId {
281fn hash<H: Hasher>(&self, h: &mut H) {
282 (((self.krate.as_u32() as u64) << 32) | (self.index.as_u32() as u64)).hash(h)
283 }
284}
285286impl DefId {
287/// Makes a local `DefId` from the given `DefIndex`.
288#[inline]
289pub fn local(index: DefIndex) -> DefId {
290DefId { krate: LOCAL_CRATE, index }
291 }
292293/// Returns whether the item is defined in the crate currently being compiled.
294#[inline]
295pub fn is_local(self) -> bool {
296self.krate == LOCAL_CRATE297 }
298299#[inline]
300pub fn as_local(self) -> Option<LocalDefId> {
301self.is_local().then(|| LocalDefId { local_def_index: self.index })
302 }
303304#[inline]
305 #[track_caller]
306pub fn expect_local(self) -> LocalDefId {
307// NOTE: `match` below is required to apply `#[track_caller]`,
308 // i.e. don't use closures.
309match self.as_local() {
310Some(local_def_id) => local_def_id,
311None => {
::core::panicking::panic_fmt(format_args!("DefId::expect_local: `{0:?}` isn\'t local",
self));
}panic!("DefId::expect_local: `{self:?}` isn't local"),
312 }
313 }
314315#[inline]
316pub fn is_crate_root(self) -> bool {
317self.index == CRATE_DEF_INDEX318 }
319320#[inline]
321pub fn as_crate_root(self) -> Option<CrateNum> {
322self.is_crate_root().then_some(self.krate)
323 }
324325#[inline]
326pub fn is_top_level_module(self) -> bool {
327self.is_local() && self.is_crate_root()
328 }
329330#[inline]
331pub fn to_raw_def_id(self) -> RawDefId {
332// Field order must match `from_raw_def_id`.
333RawDefId(self.krate.as_u32(), self.index.as_u32())
334 }
335336#[inline]
337pub fn from_raw_def_id(RawDefId(a, b): RawDefId) -> DefId {
338// Field order must match `to_raw_def_id`.
339DefId { krate: a.into(), index: b.into() }
340 }
341}
342343impl From<LocalDefId> for DefId {
344fn from(local: LocalDefId) -> DefId {
345local.to_def_id()
346 }
347}
348349pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
351}
352353pub static DEF_ID_DEBUG: AtomicRef<fn(DefId, &mut fmt::Formatter<'_>) -> fmt::Result> =
354 AtomicRef::new(&(default_def_id_debugas fn(_, &mut fmt::Formatter<'_>) -> _));
355356impl fmt::Debugfor DefId {
357fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
358 (*DEF_ID_DEBUG)(*self, f)
359 }
360}
361362pub 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);
363364/// A `LocalDefId` is equivalent to a `DefId` with `krate == LOCAL_CRATE`. Since
365/// we encode this information in the type, we can ensure at compile time that
366/// no `DefId`s from upstream crates get thrown into the mix. There are quite a
367/// few cases where we know that only `DefId`s from the local crate are expected;
368/// a `DefId` from a different crate would signify a bug somewhere. This
369/// is when `LocalDefId` comes in handy.
370#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for LocalDefId {
}
#[automatically_derived]impl ::core::clone::Clone for LocalDefId {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<DefIndex>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for LocalDefId { }Copy, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
LocalDefId {
}
#[automatically_derived]impl ::core::cmp::PartialEq for LocalDefId {
#[inline]
fn eq(&self, other: &Self) -> 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)]
371pub struct LocalDefId {
372pub local_def_index: DefIndex,
373}
374375// To ensure correctness of incremental compilation,
376// `LocalDefId` must not implement `Ord` or `PartialOrd`.
377// See https://github.com/rust-lang/rust/issues/90317.
378impl !Ordfor LocalDefId {}
379impl !PartialOrdfor LocalDefId {}
380381pub const CRATE_DEF_ID: LocalDefId = LocalDefId { local_def_index: CRATE_DEF_INDEX };
382pub const CRATE_MOD_ID: LocalModId = LocalModId::new_unchecked(CRATE_DEF_ID);
383384impl Idxfor LocalDefId {
385#[inline]
386fn new(idx: usize) -> Self {
387LocalDefId { local_def_index: Idx::new(idx) }
388 }
389#[inline]
390fn index(self) -> usize {
391self.local_def_index.index()
392 }
393}
394395impl LocalDefId {
396#[inline]
397pub fn to_def_id(self) -> DefId {
398DefId { krate: LOCAL_CRATE, index: self.local_def_index }
399 }
400401#[inline]
402pub fn is_top_level_module(self) -> bool {
403self == CRATE_DEF_ID404 }
405}
406407impl fmt::Debugfor LocalDefId {
408fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
409self.to_def_id().fmt(f)
410 }
411}
412413impl<E: SpanEncoder> Encodable<E> for LocalDefId {
414fn encode(&self, e: &mut E) {
415e.encode_local_def_id(*self);
416 }
417}
418419impl<D: BlobDecoder> Decodable<D> for LocalDefId {
420fn decode(d: &mut D) -> LocalDefId {
421d.decode_local_def_id()
422 }
423}
424425impl<E: SpanEncoder> ContextOrd<&E> for LocalDefId {
426fn stable_cmp_with_context(context: &E) -> impl FnMut(&Self, &Self) -> std::cmp::Ordering {
427let hasher = context.def_path_hasher();
428move |id1, id2| hasher(id1.to_def_id()).cmp(&hasher(id2.to_def_id()))
429 }
430}
431432pub 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!(
433LocalDefIdMap,
434LocalDefIdSet,
435LocalDefIdMapEntry,
436 LocalDefId
437);
438439impl<E: SpanEncoder> ContextOrd<&E> for DefId {
440fn stable_cmp_with_context(context: &E) -> impl FnMut(&Self, &Self) -> std::cmp::Ordering {
441let hasher = context.def_path_hasher();
442move |id1, id2| hasher(*id1).cmp(&hasher(*id2))
443 }
444}
445446impl StableHash for DefId {
447#[inline]
448fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
449self.to_stable_hash_key(hcx).stable_hash(hcx, hasher);
450 }
451}
452453impl StableHash for LocalDefId {
454#[inline]
455fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
456self.to_stable_hash_key(hcx).local_hash().stable_hash(hcx, hasher);
457 }
458}
459460impl StableHash for CrateNum {
461#[inline]
462fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
463self.as_def_id().to_stable_hash_key(hcx).stable_crate_id().stable_hash(hcx, hasher);
464 }
465}
466467impl ToStableHashKey for DefId {
468type KeyType = DefPathHash;
469470#[inline]
471fn to_stable_hash_key<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx) -> DefPathHash {
472DefPathHash(hcx.def_path_hash(self.to_raw_def_id()))
473 }
474}
475476impl ToStableHashKey for LocalDefId {
477type KeyType = DefPathHash;
478479#[inline]
480fn to_stable_hash_key<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx) -> DefPathHash {
481self.to_def_id().to_stable_hash_key(hcx)
482 }
483}
484485#[derive(#[automatically_derived]impl ::core::fmt::Debug for ModId {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "ModId",
&&self.0)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for ModId {
}
#[automatically_derived]impl ::core::clone::Clone for ModId {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<DefId>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for ModId { }Copy, #[automatically_derived]impl ::core::marker::StructuralPartialEq for ModId { }
#[automatically_derived]impl ::core::cmp::PartialEq for ModId {
#[inline]
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]impl ::core::cmp::Eq for ModId {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<DefId>;
}
}Eq, #[automatically_derived]impl ::core::hash::Hash for ModId {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for ModId {
fn encode(&self, __encoder: &mut __E) {
let ModId(ref __binding_0) = *self;
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for ModId {
fn decode(__decoder: &mut __D) -> Self {
ModId(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for ModId {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
ModId(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
486pub struct ModId(DefId);
487488impl ModId {
489#[inline]
490pub const fn new_unchecked(def_id: DefId) -> Self {
491Self(def_id)
492 }
493494#[inline]
495pub fn to_def_id(self) -> DefId {
496self.into()
497 }
498499#[inline]
500pub fn is_local(self) -> bool {
501self.0.is_local()
502 }
503504#[inline]
505pub fn as_local(self) -> Option<LocalModId> {
506self.0.as_local().map(LocalModId::new_unchecked)
507 }
508509pub fn expect_local(self) -> LocalModId {
510LocalModId::new_unchecked(self.0.expect_local())
511 }
512513pub fn is_crate_root(self) -> bool {
514self.0.is_crate_root()
515 }
516517pub fn is_top_level_module(self) -> bool {
518self.0.is_top_level_module()
519 }
520}
521522impl From<LocalModId> for ModId {
523#[inline]
524fn from(local: LocalModId) -> Self {
525Self(local.0.to_def_id())
526 }
527}
528529impl From<ModId> for DefId {
530#[inline]
531fn from(typed: ModId) -> Self {
532typed.0
533}
534}
535536#[derive(#[automatically_derived]impl ::core::fmt::Debug for LocalModId {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "LocalModId",
&&self.0)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for LocalModId {
}
#[automatically_derived]impl ::core::clone::Clone for LocalModId {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<LocalDefId>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for LocalModId { }Copy, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
LocalModId {
}
#[automatically_derived]impl ::core::cmp::PartialEq for LocalModId {
#[inline]
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]impl ::core::cmp::Eq for LocalModId {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<LocalDefId>;
}
}Eq, #[automatically_derived]impl ::core::hash::Hash for LocalModId {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for LocalModId {
fn encode(&self, __encoder: &mut __E) {
let LocalModId(ref __binding_0) = *self;
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for LocalModId {
fn decode(__decoder: &mut __D) -> Self {
LocalModId(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for LocalModId {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
LocalModId(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
537pub struct LocalModId(LocalDefId);
538539impl !Ordfor LocalModId {}
540impl !PartialOrdfor LocalModId {}
541542impl LocalModId {
543#[inline]
544pub const fn new_unchecked(def_id: LocalDefId) -> Self {
545Self(def_id)
546 }
547548pub fn is_top_level_module(self) -> bool {
549self.0.is_top_level_module()
550 }
551552#[inline]
553pub fn to_def_id(self) -> DefId {
554self.0.into()
555 }
556557pub fn to_mod_id(self) -> ModId {
558ModId::new_unchecked(self.0.to_def_id())
559 }
560561#[inline]
562pub fn to_local_def_id(self) -> LocalDefId {
563self.0
564}
565}
566567impl From<LocalModId> for LocalDefId {
568#[inline]
569fn from(typed: LocalModId) -> Self {
570typed.0
571}
572}
573574impl From<LocalModId> for DefId {
575#[inline]
576fn from(typed: LocalModId) -> Self {
577typed.0.into()
578 }
579}