Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_attr_parsing/src/attributes/lint.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use rustc_ast::LitKind;
use rustc_hir::HashIgnoredAttrId;
use rustc_hir::attrs::{LintAttribute, LintAttributeKind, LintInstance};
use rustc_hir::lints::AttributeLintKind;
use rustc_hir::target::GenericParamKind;
Expand Down Expand Up @@ -251,7 +250,7 @@ fn validate_lint_attr<T: Lint, S: Stage>(
lint_instances,
attr_span: cx.attr_span,
attr_style: cx.attr_style,
attr_id: HashIgnoredAttrId { attr_id: cx.attr_id },
target_span: cx.target_span,
kind: T::KIND,
})
}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_hir::{AttrPath, HirId};
use rustc_parse::parser::Recovery;
use rustc_session::Session;
use rustc_session::lint::{Lint, LintId};
use rustc_span::{AttrId, ErrorGuaranteed, Span, Symbol};
use rustc_span::{ErrorGuaranteed, Span, Symbol};

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

/// The name of the attribute we're currently accepting.
pub(crate) attr_path: AttrPath,

pub(crate) attr_id: AttrId,
}

impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_attr_parsing/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ impl<'sess> AttributeParser<'sess, Early> {
if let Some(safety) = attr_safety {
parser.check_attribute_safety(&attr_path, inner_span, safety, &mut emit_lint)
}
let attr_id = sess.psess.attr_id_generator.mk_attr_id();
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
shared: SharedContext {
cx: &mut parser,
Expand All @@ -254,7 +253,6 @@ impl<'sess> AttributeParser<'sess, Early> {
parsed_description,
template,
attr_path,
attr_id,
};
parse_fn(&mut cx, args)
}
Expand Down Expand Up @@ -420,7 +418,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
parsed_description: ParsedDescription::Attribute,
template: &accept.template,
attr_path: attr_path.clone(),
attr_id: attr.id,
};

(accept.accept_fn)(&mut cx, &args);
Expand Down
32 changes: 32 additions & 0 deletions compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,38 @@ impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}

impl<T1, T2, T3, T4, T5, Hcx> HashStable<Hcx> for (T1, T2, T3, T4, T5)
where
T1: HashStable<Hcx>,
T2: HashStable<Hcx>,
T3: HashStable<Hcx>,
T4: HashStable<Hcx>,
T5: HashStable<Hcx>,
{
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
let (ref _0, ref _1, ref _2, ref _3, ref _4) = *self;
_0.hash_stable(hcx, hasher);
_1.hash_stable(hcx, hasher);
_2.hash_stable(hcx, hasher);
_3.hash_stable(hcx, hasher);
_4.hash_stable(hcx, hasher);
}
}

impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd, T5: StableOrd> StableOrd
for (T1, T2, T3, T4, T5)
{
const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
&& T2::CAN_USE_UNSTABLE_SORT
&& T3::CAN_USE_UNSTABLE_SORT
&& T4::CAN_USE_UNSTABLE_SORT
&& T5::CAN_USE_UNSTABLE_SORT;

// Ordering of tuples is a pure function of their elements' ordering, and since
// the ordering of each element is stable so must be the ordering of the tuple.
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}

impl<T: HashStable<Hcx>, Hcx> HashStable<Hcx> for [T] {
default fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
self.len().hash_stable(hcx, hasher);
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ use thin_vec::ThinVec;
use crate::attrs::diagnostic::*;
use crate::attrs::pretty_printing::PrintAttribute;
use crate::limit::Limit;
use crate::{
DefaultBodyStability, HashIgnoredAttrId, PartialConstStability, RustcVersion, Stability,
};
use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability};

#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub enum EiiImplResolution {
Expand Down Expand Up @@ -903,8 +901,7 @@ pub struct LintAttribute {
pub kind: LintAttributeKind,
pub attr_style: AttrStyle,
pub attr_span: Span,
/// Needed by `LintExpectationId` to track fulfilled expectations
pub attr_id: HashIgnoredAttrId,
pub target_span: Span,
pub lint_instances: ThinVec<LintInstance>,
}

Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_lint/src/expect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::LintExpectationId;
use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
use rustc_span::Symbol;
use rustc_span::{Span, Symbol};

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

Expand Down Expand Up @@ -33,10 +33,12 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
expectations
}

fn canonicalize_id(expect_id: &LintExpectationId) -> (rustc_span::AttrId, u16) {
fn canonicalize_id(expect_id: &LintExpectationId) -> (Span, u16, u16) {
match *expect_id {
LintExpectationId::Unstable { attr_id, lint_index, .. } => (attr_id, lint_index),
LintExpectationId::Stable { attr_id, lint_index, .. } => (attr_id, lint_index),
LintExpectationId::Unstable { target_span, lint_index, attr_index }
| LintExpectationId::Stable { target_span, lint_index, attr_index, .. } => {
(target_span, lint_index, attr_index)
}
}
}

Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,10 +723,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
return;
};

for (attr_index, LintAttribute { reason, lint_instances, attr_id, kind, .. }) in
for (attr_index, LintAttribute { reason, lint_instances, kind, target_span, .. }) in
attrs.enumerate()
{
let attr_id = attr_id.attr_id;
let level = match kind {
LintAttributeKind::Allow => Level::Allow,
LintAttributeKind::Deny => Level::Deny,
Expand All @@ -737,12 +736,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
let lint_index = lint.lint_index().try_into().unwrap();
let attr_index = attr_index.try_into().unwrap();
let expectation_id = match source_hir_id {
None => LintExpectationId::Unstable { attr_id, lint_index },
None => LintExpectationId::Unstable {
target_span: *target_span,
lint_index,
attr_index,
},
Some(hir_id) => LintExpectationId::Stable {
hir_id,
attr_id,
lint_index,
attr_index,
target_span: *target_span,
},
};

Expand Down
22 changes: 12 additions & 10 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::borrow::Cow;
use std::fmt::Display;
use std::hash::Hash;

use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::stable_hasher::{
Expand All @@ -10,7 +11,7 @@ use rustc_hir_id::{HirId, ItemLocalId};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::def_id::DefPathHash;
pub use rustc_span::edition::Edition;
use rustc_span::{AttrId, HashStableContext, Ident, Span, Symbol, sym};
use rustc_span::{HashStableContext, Ident, Span, Symbol, sym};
use serde::{Deserialize, Serialize};

pub use self::Level::*;
Expand Down Expand Up @@ -91,7 +92,7 @@ pub enum Applicability {
/// instances might be loaded from cache. Lint messages can be emitted during an
/// `EarlyLintPass` operating on the AST and during a `LateLintPass` traversing the
/// HIR tree. The AST doesn't have enough information to create a stable id. The
/// `LintExpectationId` will instead store the [`AttrId`] defining the expectation.
/// `LintExpectationId` will instead store the `target_span` defining the expectation.
/// These `LintExpectationId` will be updated to use the stable [`HirId`] once the
/// AST has been lowered. The transformation is done by the `LintLevelsBuilder`
///
Expand All @@ -105,12 +106,12 @@ pub enum Applicability {
pub enum LintExpectationId {
/// Used for lints emitted during the `EarlyLintPass`. This id is not
/// hash stable and should not be cached.
Unstable { attr_id: AttrId, lint_index: u16 },
Unstable { target_span: Span, lint_index: u16, attr_index: u16 },
/// The [`HirId`] that the lint expectation is attached to. This id is
/// stable and can be cached. The additional index ensures that nodes with
/// several expectations can correctly match diagnostics to the individual
/// expectation.
Stable { hir_id: HirId, attr_id: AttrId, attr_index: u16, lint_index: u16 },
Stable { hir_id: HirId, attr_index: u16, lint_index: u16, target_span: Span },
}

impl LintExpectationId {
Expand Down Expand Up @@ -140,12 +141,13 @@ impl<Hcx: HashStableContext> HashStable<Hcx> for LintExpectationId {
#[inline]
fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
match self {
LintExpectationId::Stable { hir_id, attr_index, lint_index, .. } => {
LintExpectationId::Stable { hir_id, target_span, attr_index, lint_index, .. } => {
hir_id.hash_stable(hcx, hasher);
target_span.hash_stable(hcx, hasher);
attr_index.hash_stable(hcx, hasher);
lint_index.hash_stable(hcx, hasher);
}
_ => {
LintExpectationId::Unstable { .. } => {
unreachable!(
"HashStable should only be called for filled and stable `LintExpectationId`"
)
Expand All @@ -155,16 +157,16 @@ impl<Hcx: HashStableContext> HashStable<Hcx> for LintExpectationId {
}

impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for LintExpectationId {
type KeyType = (DefPathHash, ItemLocalId, u16, u16);
type KeyType = (DefPathHash, ItemLocalId, Span, u16, u16);

#[inline]
fn to_stable_hash_key(&self, hcx: &mut Hcx) -> Self::KeyType {
match self {
LintExpectationId::Stable { hir_id, attr_index, lint_index, .. } => {
LintExpectationId::Stable { hir_id, attr_index, lint_index, target_span, .. } => {
let (def_path_hash, lint_idx) = hir_id.to_stable_hash_key(hcx);
(def_path_hash, lint_idx, *attr_index, *lint_index)
(def_path_hash, lint_idx, *target_span, *attr_index, *lint_index)
}
_ => {
LintExpectationId::Unstable { .. } => {
unreachable!("HashStable should only be called for a filled `LintExpectationId`")
}
}
Expand Down
8 changes: 8 additions & 0 deletions tests/incremental/cache-lint-expectation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Regression test for #154878
//@ revisions: cpass1 cpass2

pub fn main() {
let x = 42.0;
#[expect(invalid_nan_comparisons)]
let _b = x == f32::NAN;
}
Loading