Skip to content

Commit 84d7916

Browse files
committed
impl !PartialOrd for HirId
1 parent 2c773bc commit 84d7916

File tree

10 files changed

+62
-53
lines changed

10 files changed

+62
-53
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3946,6 +3946,7 @@ dependencies = [
39463946
name = "rustc_lint_defs"
39473947
version = "0.0.0"
39483948
dependencies = [
3949+
"derive-where",
39493950
"rustc_abi",
39503951
"rustc_ast",
39513952
"rustc_data_structures",

compiler/rustc_driver_impl/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,11 @@ Available lint options:
903903

904904
fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> {
905905
// The sort doesn't case-fold but it's doubtful we care.
906-
lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess.edition()), x.name));
906+
lints.sort_by(|a, b| {
907+
(a.default_level(sess.edition()), a.name)
908+
.partial_cmp(&(b.default_level(sess.edition()), b.name))
909+
.unwrap()
910+
});
907911
lints
908912
}
909913

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/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
# tidy-alphabetical-start
8+
derive-where = "1.2.7"
89
rustc_abi = { path = "../rustc_abi" }
910
rustc_ast = { path = "../rustc_ast" }
1011
rustc_data_structures = { path = "../rustc_data_structures" }

compiler/rustc_lint_defs/src/lib.rs

+16-20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use derive_where::derive_where;
12
use rustc_abi::ExternAbi;
23
use rustc_ast::AttrId;
34
use rustc_ast::attr::AttributeExt;
@@ -8,7 +9,8 @@ use rustc_data_structures::stable_hasher::{
89
};
910
use rustc_error_messages::{DiagMessage, MultiSpan};
1011
use rustc_hir::def::Namespace;
11-
use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
12+
use rustc_hir::def_id::DefPathHash;
13+
use rustc_hir::{HashStableContext, HirId, ItemLocalId, MissingLifetimeKind};
1214
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
1315
pub use rustc_span::edition::Edition;
1416
use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym};
@@ -102,7 +104,7 @@ pub enum Applicability {
102104
/// The index values have a type of `u16` to reduce the size of the `LintExpectationId`.
103105
/// It's reasonable to assume that no user will define 2^16 attributes on one node or
104106
/// have that amount of lints listed. `u16` values should therefore suffice.
105-
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, Encodable, Decodable)]
107+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)]
106108
pub enum LintExpectationId {
107109
/// Used for lints emitted during the `EarlyLintPass`. This id is not
108110
/// hash stable and should not be cached.
@@ -156,13 +158,14 @@ impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId {
156158
}
157159

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

161163
#[inline]
162-
fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
164+
fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType {
163165
match self {
164166
LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
165-
(*hir_id, *attr_index, *lint_index)
167+
let (def_path_hash, lint_idx) = hir_id.to_stable_hash_key(hcx);
168+
(def_path_hash, lint_idx, *attr_index, *lint_index)
166169
}
167170
_ => {
168171
unreachable!("HashStable should only be called for a filled `LintExpectationId`")
@@ -174,19 +177,8 @@ impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectation
174177
/// Setting for how to handle a lint.
175178
///
176179
/// See: <https://doc.rust-lang.org/rustc/lints/levels.html>
177-
#[derive(
178-
Clone,
179-
Copy,
180-
PartialEq,
181-
PartialOrd,
182-
Eq,
183-
Ord,
184-
Debug,
185-
Hash,
186-
Encodable,
187-
Decodable,
188-
HashStable_Generic
189-
)]
180+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable, HashStable_Generic)]
181+
#[derive_where(PartialOrd)]
190182
pub enum Level {
191183
/// The `allow` level will not issue any message.
192184
Allow,
@@ -201,7 +193,7 @@ pub enum Level {
201193
///
202194
/// The [`LintExpectationId`] is used to later link a lint emission to the actual
203195
/// expectation. It can be ignored in most cases.
204-
Expect(LintExpectationId),
196+
Expect(#[derive_where(skip)] LintExpectationId),
205197
/// The `warn` level will produce a warning if the lint was violated, however the
206198
/// compiler will continue with its execution.
207199
Warn,
@@ -211,7 +203,7 @@ pub enum Level {
211203
///
212204
/// The [`LintExpectationId`] is intended to fulfill expectations marked via the
213205
/// `#[expect]` attribute, that will still be suppressed due to the level.
214-
ForceWarn(Option<LintExpectationId>),
206+
ForceWarn(#[derive_where(skip)] Option<LintExpectationId>),
215207
/// The `deny` level will produce an error and stop further execution after the lint
216208
/// pass is complete.
217209
Deny,
@@ -294,6 +286,10 @@ impl Level {
294286
_ => None,
295287
}
296288
}
289+
290+
pub fn min(self, other: Self) -> Self {
291+
if self < other { self } else { other }
292+
}
297293
}
298294

299295
/// Specification of a single lint.

compiler/rustc_middle/src/lint.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::cmp;
2-
31
use rustc_data_structures::fx::FxIndexMap;
42
use rustc_data_structures::sorted_map::SortedMap;
53
use rustc_errors::{Diag, MultiSpan};
@@ -100,12 +98,12 @@ pub fn reveal_actual_level(
10098
level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
10199
level
102100
} else {
103-
cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
101+
level.min(sess.opts.lint_cap.unwrap_or(Level::Forbid))
104102
};
105103

106104
if let Some(driver_level) = sess.driver_lint_caps.get(&lint) {
107105
// Ensure that we never exceed driver level.
108-
level = cmp::min(*driver_level, level);
106+
level = driver_level.min(level);
109107
}
110108

111109
level

compiler/rustc_passes/src/dead.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ impl<'tcx> DeadVisitor<'tcx> {
11311131
if dead_codes.is_empty() {
11321132
return;
11331133
}
1134-
dead_codes.sort_by_key(|v| v.level);
1134+
dead_codes.sort_by(|a, b| a.level.partial_cmp(&b.level).unwrap());
11351135
for group in dead_codes.chunk_by(|a, b| a.level == b.level) {
11361136
self.lint_at_single_level(&group, participle, Some(def_id), report_on);
11371137
}

src/tools/clippy/clippy_lints/src/duplicate_mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ declare_clippy_lint! {
4545
"file loaded as module multiple times"
4646
}
4747

48-
#[derive(PartialOrd, Ord, PartialEq, Eq)]
48+
#[derive(PartialEq, Eq)]
4949
struct Modules {
5050
local_path: PathBuf,
5151
spans: Vec<Span>,

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)