Skip to content

Commit 4720e09

Browse files
committed
Auto merge of #154906 - Bryntet:fix-expectation-id-hashing, r=<try>
Change hashing/comparison of `LintExpectationId` (fix ICE)
2 parents a92a99e + 31d95d9 commit 4720e09

9 files changed

Lines changed: 73 additions & 30 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/lint.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use rustc_ast::LitKind;
2-
use rustc_hir::HashIgnoredAttrId;
32
use rustc_hir::attrs::{LintAttribute, LintAttributeKind, LintInstance};
43
use rustc_hir::lints::AttributeLintKind;
54
use rustc_hir::target::GenericParamKind;
@@ -251,7 +250,7 @@ fn validate_lint_attr<T: Lint, S: Stage>(
251250
lint_instances,
252251
attr_span: cx.attr_span,
253252
attr_style: cx.attr_style,
254-
attr_id: HashIgnoredAttrId { attr_id: cx.attr_id },
253+
target_span: cx.target_span,
255254
kind: T::KIND,
256255
})
257256
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::{AttrPath, HirId};
1515
use rustc_parse::parser::Recovery;
1616
use rustc_session::Session;
1717
use rustc_session::lint::{Lint, LintId};
18-
use rustc_span::{AttrId, ErrorGuaranteed, Span, Symbol};
18+
use rustc_span::{ErrorGuaranteed, Span, Symbol};
1919

2020
use crate::AttributeParser;
2121
// Glob imports to avoid big, bitrotty import lists
@@ -447,8 +447,6 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
447447

448448
/// The name of the attribute we're currently accepting.
449449
pub(crate) attr_path: AttrPath,
450-
451-
pub(crate) attr_id: AttrId,
452450
}
453451

454452
impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ impl<'sess> AttributeParser<'sess, Early> {
240240
if let Some(safety) = attr_safety {
241241
parser.check_attribute_safety(&attr_path, inner_span, safety, &mut emit_lint)
242242
}
243-
let attr_id = sess.psess.attr_id_generator.mk_attr_id();
244243
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
245244
shared: SharedContext {
246245
cx: &mut parser,
@@ -254,7 +253,6 @@ impl<'sess> AttributeParser<'sess, Early> {
254253
parsed_description,
255254
template,
256255
attr_path,
257-
attr_id,
258256
};
259257
parse_fn(&mut cx, args)
260258
}
@@ -420,7 +418,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
420418
parsed_description: ParsedDescription::Attribute,
421419
template: &accept.template,
422420
attr_path: attr_path.clone(),
423-
attr_id: attr.id,
424421
};
425422

426423
(accept.accept_fn)(&mut cx, &args);

compiler/rustc_data_structures/src/stable_hasher.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,38 @@ impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (
311311
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
312312
}
313313

314+
impl<T1, T2, T3, T4, T5, Hcx> HashStable<Hcx> for (T1, T2, T3, T4, T5)
315+
where
316+
T1: HashStable<Hcx>,
317+
T2: HashStable<Hcx>,
318+
T3: HashStable<Hcx>,
319+
T4: HashStable<Hcx>,
320+
T5: HashStable<Hcx>,
321+
{
322+
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
323+
let (ref _0, ref _1, ref _2, ref _3, ref _4) = *self;
324+
_0.hash_stable(hcx, hasher);
325+
_1.hash_stable(hcx, hasher);
326+
_2.hash_stable(hcx, hasher);
327+
_3.hash_stable(hcx, hasher);
328+
_4.hash_stable(hcx, hasher);
329+
}
330+
}
331+
332+
impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd, T5: StableOrd> StableOrd
333+
for (T1, T2, T3, T4, T5)
334+
{
335+
const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
336+
&& T2::CAN_USE_UNSTABLE_SORT
337+
&& T3::CAN_USE_UNSTABLE_SORT
338+
&& T4::CAN_USE_UNSTABLE_SORT
339+
&& T5::CAN_USE_UNSTABLE_SORT;
340+
341+
// Ordering of tuples is a pure function of their elements' ordering, and since
342+
// the ordering of each element is stable so must be the ordering of the tuple.
343+
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
344+
}
345+
314346
impl<T: HashStable<Hcx>, Hcx> HashStable<Hcx> for [T] {
315347
default fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
316348
self.len().hash_stable(hcx, hasher);

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ use thin_vec::ThinVec;
2222
use crate::attrs::diagnostic::*;
2323
use crate::attrs::pretty_printing::PrintAttribute;
2424
use crate::limit::Limit;
25-
use crate::{
26-
DefaultBodyStability, HashIgnoredAttrId, PartialConstStability, RustcVersion, Stability,
27-
};
25+
use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability};
2826

2927
#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
3028
pub enum EiiImplResolution {
@@ -903,8 +901,7 @@ pub struct LintAttribute {
903901
pub kind: LintAttributeKind,
904902
pub attr_style: AttrStyle,
905903
pub attr_span: Span,
906-
/// Needed by `LintExpectationId` to track fulfilled expectations
907-
pub attr_id: HashIgnoredAttrId,
904+
pub target_span: Span,
908905
pub lint_instances: ThinVec<LintInstance>,
909906
}
910907

compiler/rustc_lint/src/expect.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_middle::query::Providers;
44
use rustc_middle::ty::TyCtxt;
55
use rustc_session::lint::LintExpectationId;
66
use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
7-
use rustc_span::Symbol;
7+
use rustc_span::{Span, Symbol};
88

99
use crate::lints::{Expectation, ExpectationNote};
1010

@@ -33,10 +33,17 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
3333
expectations
3434
}
3535

36-
fn canonicalize_id(expect_id: &LintExpectationId) -> (rustc_span::AttrId, u16) {
36+
fn canonicalize_id(expect_id: &LintExpectationId) -> (Span, u16, u16) {
3737
match *expect_id {
38-
LintExpectationId::Unstable { attr_id, lint_index, .. } => (attr_id, lint_index),
39-
LintExpectationId::Stable { attr_id, lint_index, .. } => (attr_id, lint_index),
38+
LintExpectationId::Unstable { target_span, lint_index, attr_index } => {
39+
(target_span, lint_index, attr_index)
40+
}
41+
LintExpectationId::Stable { lint_index, target_span, attr_index, .. } => {
42+
// When targeting a crate, the unstable `target_span` will be `Span::default`,
43+
// `TyCtxt::hir_span` does not return `Span::default` for `CRATE_HIR_ID`
44+
// So we do it ourselves
45+
(target_span, lint_index, attr_index)
46+
}
4047
}
4148
}
4249

compiler/rustc_lint/src/levels.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
723723
return;
724724
};
725725

726-
for (attr_index, LintAttribute { reason, lint_instances, attr_id, kind, .. }) in
726+
for (attr_index, LintAttribute { reason, lint_instances, kind, target_span, .. }) in
727727
attrs.enumerate()
728728
{
729-
let attr_id = attr_id.attr_id;
730729
let level = match kind {
731730
LintAttributeKind::Allow => Level::Allow,
732731
LintAttributeKind::Deny => Level::Deny,
@@ -737,12 +736,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
737736
let lint_index = lint.lint_index().try_into().unwrap();
738737
let attr_index = attr_index.try_into().unwrap();
739738
let expectation_id = match source_hir_id {
740-
None => LintExpectationId::Unstable { attr_id, lint_index },
739+
None => LintExpectationId::Unstable {
740+
target_span: *target_span,
741+
lint_index,
742+
attr_index,
743+
},
741744
Some(hir_id) => LintExpectationId::Stable {
742745
hir_id,
743-
attr_id,
744746
lint_index,
745747
attr_index,
748+
target_span: *target_span,
746749
},
747750
};
748751

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::borrow::Cow;
22
use std::fmt::Display;
3+
use std::hash::Hash;
34

45
use rustc_data_structures::fx::FxIndexSet;
56
use rustc_data_structures::stable_hasher::{
@@ -10,7 +11,7 @@ use rustc_hir_id::{HirId, ItemLocalId};
1011
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
1112
use rustc_span::def_id::DefPathHash;
1213
pub use rustc_span::edition::Edition;
13-
use rustc_span::{AttrId, HashStableContext, Ident, Span, Symbol, sym};
14+
use rustc_span::{HashStableContext, Ident, Span, Symbol, sym};
1415
use serde::{Deserialize, Serialize};
1516

1617
pub use self::Level::*;
@@ -105,12 +106,12 @@ pub enum Applicability {
105106
pub enum LintExpectationId {
106107
/// Used for lints emitted during the `EarlyLintPass`. This id is not
107108
/// hash stable and should not be cached.
108-
Unstable { attr_id: AttrId, lint_index: u16 },
109+
Unstable { target_span: Span, lint_index: u16, attr_index: u16 },
109110
/// The [`HirId`] that the lint expectation is attached to. This id is
110111
/// stable and can be cached. The additional index ensures that nodes with
111112
/// several expectations can correctly match diagnostics to the individual
112113
/// expectation.
113-
Stable { hir_id: HirId, attr_id: AttrId, attr_index: u16, lint_index: u16 },
114+
Stable { hir_id: HirId, attr_index: u16, lint_index: u16, target_span: Span },
114115
}
115116

116117
impl LintExpectationId {
@@ -140,12 +141,13 @@ impl<Hcx: HashStableContext> HashStable<Hcx> for LintExpectationId {
140141
#[inline]
141142
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
142143
match self {
143-
LintExpectationId::Stable { hir_id, attr_index, lint_index, .. } => {
144+
LintExpectationId::Stable { hir_id, target_span, attr_index, lint_index, .. } => {
144145
hir_id.hash_stable(hcx, hasher);
146+
target_span.hash_stable(hcx, hasher);
145147
attr_index.hash_stable(hcx, hasher);
146148
lint_index.hash_stable(hcx, hasher);
147149
}
148-
_ => {
150+
LintExpectationId::Unstable { .. } => {
149151
unreachable!(
150152
"HashStable should only be called for filled and stable `LintExpectationId`"
151153
)
@@ -155,16 +157,16 @@ impl<Hcx: HashStableContext> HashStable<Hcx> for LintExpectationId {
155157
}
156158

157159
impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for LintExpectationId {
158-
type KeyType = (DefPathHash, ItemLocalId, u16, u16);
160+
type KeyType = (DefPathHash, ItemLocalId, Span, u16, u16);
159161

160162
#[inline]
161163
fn to_stable_hash_key(&self, hcx: &mut Hcx) -> Self::KeyType {
162164
match self {
163-
LintExpectationId::Stable { hir_id, attr_index, lint_index, .. } => {
165+
LintExpectationId::Stable { hir_id, attr_index, lint_index, target_span, .. } => {
164166
let (def_path_hash, lint_idx) = hir_id.to_stable_hash_key(hcx);
165-
(def_path_hash, lint_idx, *attr_index, *lint_index)
167+
(def_path_hash, lint_idx, *target_span, *attr_index, *lint_index)
166168
}
167-
_ => {
169+
LintExpectationId::Unstable { .. } => {
168170
unreachable!("HashStable should only be called for a filled `LintExpectationId`")
169171
}
170172
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Regression test for #154878
2+
//@ revisions: cpass1 cpass2
3+
4+
pub fn main() {
5+
let x = 42.0;
6+
#[expect(invalid_nan_comparisons)]
7+
let _b = x == f32::NAN;
8+
}

0 commit comments

Comments
 (0)