Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0dde879

Browse files
committedMar 19, 2025
impl !PartialOrd for HirId
1 parent b2c632d commit 0dde879

File tree

5 files changed

+44
-32
lines changed

5 files changed

+44
-32
lines changed
 

‎compiler/rustc_hir/src/hir_id.rs

+6-16
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ pub struct HirId {
8383
pub local_id: ItemLocalId,
8484
}
8585

86+
// To ensure correctness of incremental compilation,
87+
// `HirId` must not implement `Ord` or `PartialOrd`.
88+
// See https://github.com/rust-lang/rust/issues/90317.
89+
impl !Ord for HirId {}
90+
impl !PartialOrd for HirId {}
91+
8692
impl Debug for HirId {
8793
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8894
// Example: HirId(DefId(0:1 ~ aa[7697]::{use#0}).10)
@@ -116,10 +122,6 @@ impl HirId {
116122
pub fn make_owner(owner: LocalDefId) -> Self {
117123
Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO }
118124
}
119-
120-
pub fn index(self) -> (usize, usize) {
121-
(rustc_index::Idx::index(self.owner.def_id), rustc_index::Idx::index(self.local_id))
122-
}
123125
}
124126

125127
impl fmt::Display for HirId {
@@ -128,18 +130,6 @@ impl fmt::Display for HirId {
128130
}
129131
}
130132

131-
impl Ord for HirId {
132-
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
133-
(self.index()).cmp(&(other.index()))
134-
}
135-
}
136-
137-
impl PartialOrd for HirId {
138-
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
139-
Some(self.cmp(other))
140-
}
141-
}
142-
143133
rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
144134
rustc_data_structures::define_id_collections!(
145135
ItemLocalMap,

‎compiler/rustc_hir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![feature(debug_closure_helpers)]
1212
#![feature(exhaustive_patterns)]
1313
#![feature(let_chains)]
14+
#![feature(negative_impls)]
1415
#![feature(never_type)]
1516
#![feature(rustc_attrs)]
1617
#![feature(variant_count)]

‎compiler/rustc_lint_defs/src/lib.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use rustc_data_structures::stable_hasher::{
88
};
99
use rustc_error_messages::{DiagMessage, MultiSpan};
1010
use rustc_hir::def::Namespace;
11-
use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
11+
use rustc_hir::def_id::DefPathHash;
12+
use rustc_hir::{HashStableContext, HirId, ItemLocalId, MissingLifetimeKind};
1213
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
1314
pub use rustc_span::edition::Edition;
1415
use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym};
@@ -102,7 +103,7 @@ pub enum Applicability {
102103
/// The index values have a type of `u16` to reduce the size of the `LintExpectationId`.
103104
/// It's reasonable to assume that no user will define 2^16 attributes on one node or
104105
/// have that amount of lints listed. `u16` values should therefore suffice.
105-
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, Encodable, Decodable)]
106+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)]
106107
pub enum LintExpectationId {
107108
/// Used for lints emitted during the `EarlyLintPass`. This id is not
108109
/// hash stable and should not be cached.
@@ -156,13 +157,14 @@ impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId {
156157
}
157158

158159
impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectationId {
159-
type KeyType = (HirId, u16, u16);
160+
type KeyType = (DefPathHash, ItemLocalId, u16, u16);
160161

161162
#[inline]
162-
fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
163+
fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType {
163164
match self {
164165
LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
165-
(*hir_id, *attr_index, *lint_index)
166+
let (def_path_hash, lint_idx) = hir_id.to_stable_hash_key(hcx);
167+
(def_path_hash, lint_idx, *attr_index, *lint_index)
166168
}
167169
_ => {
168170
unreachable!("HashStable should only be called for a filled `LintExpectationId`")

‎compiler/rustc_passes/src/dead.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,8 @@ impl<'tcx> DeadVisitor<'tcx> {
11321132
if dead_codes.is_empty() {
11331133
return;
11341134
}
1135-
dead_codes.sort_by_key(|v| v.level);
1135+
// FIXME: `dead_codes` should probably be morally equivalent to `IndexMap<(Level, LintExpectationId), (DefId, Symbol)>`
1136+
dead_codes.sort_by(|a, b| a.level.0.partial_cmp(&b.level.0).unwrap());
11361137
for group in dead_codes.chunk_by(|a, b| a.level == b.level) {
11371138
self.lint_at_single_level(&group, participle, Some(def_id), report_on);
11381139
}

‎src/tools/clippy/clippy_lints/src/macro_use.rs

+28-10
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,15 @@ impl LateLintPass<'_> for MacroUseImports {
153153
[] | [_] => return,
154154
[root, item] => {
155155
if !check_dup.contains(&(*item).to_string()) {
156-
used.entry(((*root).to_string(), span, hir_id))
157-
.or_insert_with(Vec::new)
158-
.push((*item).to_string());
156+
used.entry((
157+
(*root).to_string(),
158+
span,
159+
hir_id.local_id,
160+
cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
161+
))
162+
.or_insert_with(|| (vec![], hir_id))
163+
.0
164+
.push((*item).to_string());
159165
check_dup.push((*item).to_string());
160166
}
161167
},
@@ -171,15 +177,27 @@ impl LateLintPass<'_> for MacroUseImports {
171177
}
172178
})
173179
.collect::<Vec<_>>();
174-
used.entry(((*root).to_string(), span, hir_id))
175-
.or_insert_with(Vec::new)
176-
.push(filtered.join("::"));
180+
used.entry((
181+
(*root).to_string(),
182+
span,
183+
hir_id.local_id,
184+
cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
185+
))
186+
.or_insert_with(|| (vec![], hir_id))
187+
.0
188+
.push(filtered.join("::"));
177189
check_dup.extend(filtered);
178190
} else {
179191
let rest = rest.to_vec();
180-
used.entry(((*root).to_string(), span, hir_id))
181-
.or_insert_with(Vec::new)
182-
.push(rest.join("::"));
192+
used.entry((
193+
(*root).to_string(),
194+
span,
195+
hir_id.local_id,
196+
cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
197+
))
198+
.or_insert_with(|| (vec![], hir_id))
199+
.0
200+
.push(rest.join("::"));
183201
check_dup.extend(rest.iter().map(ToString::to_string));
184202
}
185203
},
@@ -190,7 +208,7 @@ impl LateLintPass<'_> for MacroUseImports {
190208
// If mac_refs is not empty we have encountered an import we could not handle
191209
// such as `std::prelude::v1::foo` or some other macro that expands to an import.
192210
if self.mac_refs.is_empty() {
193-
for ((root, span, hir_id), path) in used {
211+
for ((root, span, ..), (path, hir_id)) in used {
194212
let import = if let [single] = &path[..] {
195213
format!("{root}::{single}")
196214
} else {

0 commit comments

Comments
 (0)
Failed to load comments.