Skip to content

Commit bb5a016

Browse files
committedSep 24, 2022
Auto merge of #102064 - cjgillot:revert, r=Mark-Simulacrum
Revert perf-regression 101620 Reverts #101862 #101620 r? `@Mark-Simulacrum`
2 parents 199fe1d + fc43df0 commit bb5a016

File tree

19 files changed

+496
-682
lines changed

19 files changed

+496
-682
lines changed
 

‎compiler/rustc_errors/src/diagnostic.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,9 @@ impl Diagnostic {
339339
// The lint index inside the attribute is manually transferred here.
340340
let lint_index = expectation_id.get_lint_index();
341341
expectation_id.set_lint_index(None);
342-
let mut stable_id = unstable_to_stable
342+
let mut stable_id = *unstable_to_stable
343343
.get(&expectation_id)
344-
.expect("each unstable `LintExpectationId` must have a matching stable id")
345-
.normalize();
344+
.expect("each unstable `LintExpectationId` must have a matching stable id");
346345

347346
stable_id.set_lint_index(lint_index);
348347
*expectation_id = stable_id;

‎compiler/rustc_errors/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ impl HandlerInner {
12051205

12061206
if let Some(expectation_id) = diagnostic.level.get_expectation_id() {
12071207
self.suppressed_expected_diag = true;
1208-
self.fulfilled_expectations.insert(expectation_id.normalize());
1208+
self.fulfilled_expectations.insert(expectation_id);
12091209
}
12101210

12111211
if matches!(diagnostic.level, Warning(_))

‎compiler/rustc_lint/src/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ pub struct LateContext<'tcx> {
560560

561561
/// Context for lint checking of the AST, after expansion, before lowering to HIR.
562562
pub struct EarlyContext<'a> {
563-
pub builder: LintLevelsBuilder<'a, crate::levels::TopDown>,
563+
pub builder: LintLevelsBuilder<'a>,
564564
pub buffered: LintBuffer,
565565
}
566566

‎compiler/rustc_lint/src/early.rs

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
5959
F: FnOnce(&mut Self),
6060
{
6161
let is_crate_node = id == ast::CRATE_NODE_ID;
62-
debug!(?id);
6362
let push = self.context.builder.push(attrs, is_crate_node, None);
6463

6564
self.check_id(id);

‎compiler/rustc_lint/src/expect.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
1616
return;
1717
}
1818

19-
let lint_expectations = tcx.lint_expectations(());
2019
let fulfilled_expectations = tcx.sess.diagnostic().steal_fulfilled_expectation_ids();
21-
22-
tracing::debug!(?lint_expectations, ?fulfilled_expectations);
20+
let lint_expectations = &tcx.lint_levels(()).lint_expectations;
2321

2422
for (id, expectation) in lint_expectations {
2523
// This check will always be true, since `lint_expectations` only

‎compiler/rustc_lint/src/levels.rs

+284-396
Large diffs are not rendered by default.

‎compiler/rustc_lint/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#![feature(iter_order_by)]
3636
#![feature(let_chains)]
3737
#![cfg_attr(bootstrap, feature(let_else))]
38-
#![feature(min_specialization)]
3938
#![feature(never_type)]
4039
#![recursion_limit = "256"]
4140

‎compiler/rustc_lint_defs/src/lib.rs

+5-26
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub enum LintExpectationId {
9292
/// stable and can be cached. The additional index ensures that nodes with
9393
/// several expectations can correctly match diagnostics to the individual
9494
/// expectation.
95-
Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16>, attr_id: Option<AttrId> },
95+
Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16> },
9696
}
9797

9898
impl LintExpectationId {
@@ -116,31 +116,13 @@ impl LintExpectationId {
116116

117117
*lint_index = new_lint_index
118118
}
119-
120-
/// Prepares the id for hashing. Removes references to the ast.
121-
/// Should only be called when the id is stable.
122-
pub fn normalize(self) -> Self {
123-
match self {
124-
Self::Stable { hir_id, attr_index, lint_index, .. } => {
125-
Self::Stable { hir_id, attr_index, lint_index, attr_id: None }
126-
}
127-
Self::Unstable { .. } => {
128-
unreachable!("`normalize` called when `ExpectationId` is unstable")
129-
}
130-
}
131-
}
132119
}
133120

134121
impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId {
135122
#[inline]
136123
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
137124
match self {
138-
LintExpectationId::Stable {
139-
hir_id,
140-
attr_index,
141-
lint_index: Some(lint_index),
142-
attr_id: _,
143-
} => {
125+
LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
144126
hir_id.hash_stable(hcx, hasher);
145127
attr_index.hash_stable(hcx, hasher);
146128
lint_index.hash_stable(hcx, hasher);
@@ -160,12 +142,9 @@ impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectation
160142
#[inline]
161143
fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
162144
match self {
163-
LintExpectationId::Stable {
164-
hir_id,
165-
attr_index,
166-
lint_index: Some(lint_index),
167-
attr_id: _,
168-
} => (*hir_id, *attr_index, *lint_index),
145+
LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
146+
(*hir_id, *attr_index, *lint_index)
147+
}
169148
_ => {
170149
unreachable!("HashStable should only be called for a filled `LintExpectationId`")
171150
}

‎compiler/rustc_middle/src/dep_graph/dep_node.rs

+6-32
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use crate::ty::TyCtxt;
6262
use rustc_data_structures::fingerprint::Fingerprint;
6363
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
6464
use rustc_hir::definitions::DefPathHash;
65-
use rustc_hir::{HirId, ItemLocalId};
65+
use rustc_hir::HirId;
6666
use rustc_query_system::dep_graph::FingerprintStyle;
6767
use rustc_span::symbol::Symbol;
6868
use std::hash::Hash;
@@ -280,7 +280,7 @@ impl DepNodeExt for DepNode {
280280
let kind = dep_kind_from_label_string(label)?;
281281

282282
match kind.fingerprint_style(tcx) {
283-
FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()),
283+
FingerprintStyle::Opaque => Err(()),
284284
FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
285285
FingerprintStyle::DefPathHash => {
286286
Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind))
@@ -408,7 +408,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
408408
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
409409
#[inline(always)]
410410
fn fingerprint_style() -> FingerprintStyle {
411-
FingerprintStyle::HirId
411+
FingerprintStyle::Opaque
412412
}
413413

414414
// We actually would not need to specialize the implementation of this
@@ -417,36 +417,10 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
417417
#[inline(always)]
418418
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
419419
let HirId { owner, local_id } = *self;
420-
let def_path_hash = tcx.def_path_hash(owner.to_def_id());
421-
Fingerprint::new(
422-
// `owner` is local, so is completely defined by the local hash
423-
def_path_hash.local_hash(),
424-
local_id.as_u32().into(),
425-
)
426-
}
427420

428-
#[inline(always)]
429-
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
430-
let HirId { owner, local_id } = *self;
431-
format!("{}.{}", tcx.def_path_str(owner.to_def_id()), local_id.as_u32())
432-
}
421+
let def_path_hash = tcx.def_path_hash(owner.to_def_id());
422+
let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into());
433423

434-
#[inline(always)]
435-
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
436-
if dep_node.kind.fingerprint_style(tcx) == FingerprintStyle::HirId {
437-
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value();
438-
let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
439-
let owner = tcx
440-
.def_path_hash_to_def_id(def_path_hash, &mut || {
441-
panic!("Failed to extract HirId: {:?} {}", dep_node.kind, dep_node.hash)
442-
})
443-
.expect_local();
444-
let local_id = local_id
445-
.try_into()
446-
.unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id));
447-
Some(HirId { owner, local_id: ItemLocalId::from_u32(local_id) })
448-
} else {
449-
None
450-
}
424+
def_path_hash.0.combine(local_id)
451425
}
452426
}

‎compiler/rustc_middle/src/hir/map/mod.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub struct ParentHirIterator<'hir> {
6161
}
6262

6363
impl<'hir> Iterator for ParentHirIterator<'hir> {
64-
type Item = HirId;
64+
type Item = (HirId, Node<'hir>);
6565

6666
fn next(&mut self) -> Option<Self::Item> {
6767
if self.current_id == CRATE_HIR_ID {
@@ -77,7 +77,10 @@ impl<'hir> Iterator for ParentHirIterator<'hir> {
7777
}
7878

7979
self.current_id = parent_id;
80-
return Some(parent_id);
80+
if let Some(node) = self.map.find(parent_id) {
81+
return Some((parent_id, node));
82+
}
83+
// If this `HirId` doesn't have an entry, skip it and look for its `parent_id`.
8184
}
8285
}
8386
}
@@ -390,8 +393,8 @@ impl<'hir> Map<'hir> {
390393
}
391394

392395
pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId {
393-
for (_, node) in self.parent_iter(hir_id) {
394-
if let Some(body) = associated_body(node) {
396+
for (parent, _) in self.parent_iter(hir_id) {
397+
if let Some(body) = self.find(parent).map(associated_body).flatten() {
395398
return self.body_owner_def_id(body);
396399
}
397400
}
@@ -632,17 +635,10 @@ impl<'hir> Map<'hir> {
632635
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
633636
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
634637
#[inline]
635-
pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator<Item = HirId> + 'hir {
638+
pub fn parent_iter(self, current_id: HirId) -> ParentHirIterator<'hir> {
636639
ParentHirIterator { current_id, map: self }
637640
}
638641

639-
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
640-
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
641-
#[inline]
642-
pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
643-
self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?)))
644-
}
645-
646642
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
647643
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
648644
#[inline]

‎compiler/rustc_middle/src/lint.rs

+124-98
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
use std::cmp;
22

33
use rustc_data_structures::fx::FxHashMap;
4+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
45
use rustc_errors::{Diagnostic, DiagnosticId, LintDiagnosticBuilder, MultiSpan};
56
use rustc_hir::HirId;
7+
use rustc_index::vec::IndexVec;
8+
use rustc_query_system::ich::StableHashingContext;
69
use rustc_session::lint::{
710
builtin::{self, FORBIDDEN_LINT_GROUPS},
8-
FutureIncompatibilityReason, Level, Lint, LintId,
11+
FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId,
912
};
1013
use rustc_session::Session;
1114
use rustc_span::hygiene::MacroKind;
1215
use rustc_span::source_map::{DesugaringKind, ExpnKind};
1316
use rustc_span::{symbol, Span, Symbol, DUMMY_SP};
1417

15-
use crate::ty::TyCtxt;
16-
1718
/// How a lint level was set.
1819
#[derive(Clone, Copy, PartialEq, Eq, HashStable, Debug)]
1920
pub enum LintLevelSource {
@@ -22,12 +23,7 @@ pub enum LintLevelSource {
2223
Default,
2324

2425
/// Lint level was set by an attribute.
25-
Node {
26-
name: Symbol,
27-
span: Span,
28-
/// RFC 2383 reason
29-
reason: Option<Symbol>,
30-
},
26+
Node(Symbol, Span, Option<Symbol> /* RFC 2383 reason */),
3127

3228
/// Lint level was set by a command-line flag.
3329
/// The provided `Level` is the level specified on the command line.
@@ -39,15 +35,15 @@ impl LintLevelSource {
3935
pub fn name(&self) -> Symbol {
4036
match *self {
4137
LintLevelSource::Default => symbol::kw::Default,
42-
LintLevelSource::Node { name, .. } => name,
38+
LintLevelSource::Node(name, _, _) => name,
4339
LintLevelSource::CommandLine(name, _) => name,
4440
}
4541
}
4642

4743
pub fn span(&self) -> Span {
4844
match *self {
4945
LintLevelSource::Default => DUMMY_SP,
50-
LintLevelSource::Node { span, .. } => span,
46+
LintLevelSource::Node(_, span, _) => span,
5147
LintLevelSource::CommandLine(_, _) => DUMMY_SP,
5248
}
5349
}
@@ -56,115 +52,145 @@ impl LintLevelSource {
5652
/// A tuple of a lint level and its source.
5753
pub type LevelAndSource = (Level, LintLevelSource);
5854

59-
/// Return type for the `shallow_lint_levels_on` query.
60-
///
61-
/// This map represents the set of allowed lints and allowance levels given
62-
/// by the attributes for *a single HirId*.
63-
#[derive(Default, Debug, HashStable)]
64-
pub struct ShallowLintLevelMap {
55+
#[derive(Debug, HashStable)]
56+
pub struct LintLevelSets {
57+
pub list: IndexVec<LintStackIndex, LintSet>,
58+
pub lint_cap: Level,
59+
}
60+
61+
rustc_index::newtype_index! {
62+
#[derive(HashStable)]
63+
pub struct LintStackIndex {
64+
const COMMAND_LINE = 0,
65+
}
66+
}
67+
68+
#[derive(Debug, HashStable)]
69+
pub struct LintSet {
70+
// -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
71+
// flag.
6572
pub specs: FxHashMap<LintId, LevelAndSource>,
73+
74+
pub parent: LintStackIndex,
6675
}
6776

68-
/// From an initial level and source, verify the effect of special annotations:
69-
/// `warnings` lint level and lint caps.
70-
///
71-
/// The return of this function is suitable for diagnostics.
72-
pub fn reveal_actual_level(
73-
level: Option<Level>,
74-
src: &mut LintLevelSource,
75-
sess: &Session,
76-
lint: LintId,
77-
probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource),
78-
) -> Level {
79-
// If `level` is none then we actually assume the default level for this lint.
80-
let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition()));
81-
82-
// If we're about to issue a warning, check at the last minute for any
83-
// directives against the warnings "lint". If, for example, there's an
84-
// `allow(warnings)` in scope then we want to respect that instead.
85-
//
86-
// We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
87-
// triggers in cases (like #80988) where you have `forbid(warnings)`,
88-
// and so if we turned that into an error, it'd defeat the purpose of the
89-
// future compatibility warning.
90-
if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
91-
let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
92-
if let Some(configured_warning_level) = warnings_level {
93-
if configured_warning_level != Level::Warn {
94-
level = configured_warning_level;
95-
*src = warnings_src;
77+
impl LintLevelSets {
78+
pub fn new() -> Self {
79+
LintLevelSets { list: IndexVec::new(), lint_cap: Level::Forbid }
80+
}
81+
82+
pub fn get_lint_level(
83+
&self,
84+
lint: &'static Lint,
85+
idx: LintStackIndex,
86+
aux: Option<&FxHashMap<LintId, LevelAndSource>>,
87+
sess: &Session,
88+
) -> LevelAndSource {
89+
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
90+
91+
// If `level` is none then we actually assume the default level for this
92+
// lint.
93+
let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition()));
94+
95+
// If we're about to issue a warning, check at the last minute for any
96+
// directives against the warnings "lint". If, for example, there's an
97+
// `allow(warnings)` in scope then we want to respect that instead.
98+
//
99+
// We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
100+
// triggers in cases (like #80988) where you have `forbid(warnings)`,
101+
// and so if we turned that into an error, it'd defeat the purpose of the
102+
// future compatibility warning.
103+
if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) {
104+
let (warnings_level, warnings_src) =
105+
self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux);
106+
if let Some(configured_warning_level) = warnings_level {
107+
if configured_warning_level != Level::Warn {
108+
level = configured_warning_level;
109+
src = warnings_src;
110+
}
96111
}
97112
}
98-
}
99113

100-
// Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn
101-
level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
102-
level
103-
} else {
104-
cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
105-
};
114+
// Ensure that we never exceed the `--cap-lints` argument
115+
// unless the source is a --force-warn
116+
level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
117+
level
118+
} else {
119+
cmp::min(level, self.lint_cap)
120+
};
121+
122+
if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
123+
// Ensure that we never exceed driver level.
124+
level = cmp::min(*driver_level, level);
125+
}
106126

107-
if let Some(driver_level) = sess.driver_lint_caps.get(&lint) {
108-
// Ensure that we never exceed driver level.
109-
level = cmp::min(*driver_level, level);
127+
(level, src)
110128
}
111129

112-
level
113-
}
114-
115-
impl ShallowLintLevelMap {
116-
/// Perform a deep probe in the HIR tree looking for the actual level for the lint.
117-
/// This lint level is not usable for diagnostics, it needs to be corrected by
118-
/// `reveal_actual_level` beforehand.
119-
fn probe_for_lint_level(
130+
pub fn get_lint_id_level(
120131
&self,
121-
tcx: TyCtxt<'_>,
122132
id: LintId,
123-
start: HirId,
133+
mut idx: LintStackIndex,
134+
aux: Option<&FxHashMap<LintId, LevelAndSource>>,
124135
) -> (Option<Level>, LintLevelSource) {
125-
if let Some(&(level, src)) = self.specs.get(&id) {
126-
return (Some(level), src);
136+
if let Some(specs) = aux {
137+
if let Some(&(level, src)) = specs.get(&id) {
138+
return (Some(level), src);
139+
}
127140
}
128-
129-
for parent in tcx.hir().parent_id_iter(start) {
130-
let specs = tcx.shallow_lint_levels_on(parent);
131-
if let Some(&(level, src)) = specs.specs.get(&id) {
141+
loop {
142+
let LintSet { ref specs, parent } = self.list[idx];
143+
if let Some(&(level, src)) = specs.get(&id) {
132144
return (Some(level), src);
133145
}
146+
if idx == COMMAND_LINE {
147+
return (None, LintLevelSource::Default);
148+
}
149+
idx = parent;
134150
}
135-
(None, LintLevelSource::Default)
136151
}
152+
}
153+
154+
#[derive(Debug)]
155+
pub struct LintLevelMap {
156+
/// This is a collection of lint expectations as described in RFC 2383, that
157+
/// can be fulfilled during this compilation session. This means that at least
158+
/// one expected lint is currently registered in the lint store.
159+
///
160+
/// The [`LintExpectationId`] is stored as a part of the [`Expect`](Level::Expect)
161+
/// lint level.
162+
pub lint_expectations: Vec<(LintExpectationId, LintExpectation)>,
163+
pub sets: LintLevelSets,
164+
pub id_to_set: FxHashMap<HirId, LintStackIndex>,
165+
}
137166

138-
/// Fetch and return the user-visible lint level for the given lint at the given HirId.
139-
pub fn lint_level_id_at_node(
167+
impl LintLevelMap {
168+
/// If the `id` was previously registered with `register_id` when building
169+
/// this `LintLevelMap` this returns the corresponding lint level and source
170+
/// of the lint level for the lint provided.
171+
///
172+
/// If the `id` was not previously registered, returns `None`. If `None` is
173+
/// returned then the parent of `id` should be acquired and this function
174+
/// should be called again.
175+
pub fn level_and_source(
140176
&self,
141-
tcx: TyCtxt<'_>,
142-
lint: LintId,
177+
lint: &'static Lint,
143178
id: HirId,
144-
) -> (Level, LintLevelSource) {
145-
let (level, mut src) = self.probe_for_lint_level(tcx, lint, id);
146-
let level = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
147-
self.probe_for_lint_level(tcx, lint, id)
148-
});
149-
debug!(?id, ?level, ?src);
150-
(level, src)
179+
session: &Session,
180+
) -> Option<LevelAndSource> {
181+
self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session))
151182
}
152183
}
153184

154-
impl TyCtxt<'_> {
155-
/// Fetch and return the user-visible lint level for the given lint at the given HirId.
156-
pub fn lint_level_at_node(self, lint: &'static Lint, id: HirId) -> (Level, LintLevelSource) {
157-
self.shallow_lint_levels_on(id).lint_level_id_at_node(self, LintId::of(lint), id)
158-
}
185+
impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
186+
#[inline]
187+
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
188+
let LintLevelMap { ref sets, ref id_to_set, ref lint_expectations } = *self;
159189

160-
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
161-
/// It stops at `bound` and just returns it if reached.
162-
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
163-
let hir = self.hir();
164-
while id != bound && self.shallow_lint_levels_on(id).specs.is_empty() {
165-
id = hir.get_parent_node(id)
166-
}
167-
id
190+
id_to_set.hash_stable(hcx, hasher);
191+
lint_expectations.hash_stable(hcx, hasher);
192+
193+
hcx.while_hashing_spans(true, |hcx| sets.hash_stable(hcx, hasher))
168194
}
169195
}
170196

@@ -235,11 +261,11 @@ pub fn explain_lint_level_source(
235261
));
236262
}
237263
}
238-
LintLevelSource::Node { name: lint_attr_name, span, reason, .. } => {
264+
LintLevelSource::Node(lint_attr_name, src, reason) => {
239265
if let Some(rationale) = reason {
240266
err.note(rationale.as_str());
241267
}
242-
err.span_note_once(span, "the lint level is defined here");
268+
err.span_note_once(src, "the lint level is defined here");
243269
if lint_attr_name.as_str() != name {
244270
let level_str = level.as_str();
245271
err.note_once(&format!(

‎compiler/rustc_middle/src/query/mod.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -274,14 +274,10 @@ rustc_queries! {
274274
separate_provide_extern
275275
}
276276

277-
query shallow_lint_levels_on(key: HirId) -> rustc_middle::lint::ShallowLintLevelMap {
277+
query lint_levels(_: ()) -> LintLevelMap {
278278
arena_cache
279-
desc { |tcx| "looking up lint levels for `{}`", key }
280-
}
281-
282-
query lint_expectations(_: ()) -> Vec<(LintExpectationId, LintExpectation)> {
283-
arena_cache
284-
desc { "computing `#[expect]`ed lints in this crate" }
279+
eval_always
280+
desc { "computing the lint levels for items in this crate" }
285281
}
286282

287283
query parent_module_from_def_id(key: LocalDefId) -> LocalDefId {

‎compiler/rustc_middle/src/ty/context.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::arena::Arena;
44
use crate::dep_graph::{DepGraph, DepKind, DepKindStruct};
55
use crate::hir::place::Place as HirPlace;
66
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
7-
use crate::lint::struct_lint_level;
7+
use crate::lint::{struct_lint_level, LintLevelSource};
88
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
99
use crate::middle::resolve_lifetime;
1010
use crate::middle::stability;
@@ -54,7 +54,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
5454
use rustc_session::config::{CrateType, OutputFilenames};
5555
use rustc_session::cstore::CrateStoreDyn;
5656
use rustc_session::errors::TargetDataLayoutErrorsWrapper;
57-
use rustc_session::lint::Lint;
57+
use rustc_session::lint::{Level, Lint};
5858
use rustc_session::Limit;
5959
use rustc_session::Session;
6060
use rustc_span::def_id::{DefPathHash, StableCrateId};
@@ -2813,6 +2813,44 @@ impl<'tcx> TyCtxt<'tcx> {
28132813
iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
28142814
}
28152815

2816+
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
2817+
/// It stops at `bound` and just returns it if reached.
2818+
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
2819+
let hir = self.hir();
2820+
loop {
2821+
if id == bound {
2822+
return bound;
2823+
}
2824+
2825+
if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
2826+
return id;
2827+
}
2828+
let next = hir.get_parent_node(id);
2829+
if next == id {
2830+
bug!("lint traversal reached the root of the crate");
2831+
}
2832+
id = next;
2833+
}
2834+
}
2835+
2836+
pub fn lint_level_at_node(
2837+
self,
2838+
lint: &'static Lint,
2839+
mut id: hir::HirId,
2840+
) -> (Level, LintLevelSource) {
2841+
let sets = self.lint_levels(());
2842+
loop {
2843+
if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
2844+
return pair;
2845+
}
2846+
let next = self.hir().get_parent_node(id);
2847+
if next == id {
2848+
bug!("lint traversal reached the root of the crate");
2849+
}
2850+
id = next;
2851+
}
2852+
}
2853+
28162854
/// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
28172855
/// typically generated by `#[derive(LintDiagnostic)]`).
28182856
pub fn emit_spanned_lint(

‎compiler/rustc_middle/src/ty/query.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::dep_graph;
22
use crate::infer::canonical::{self, Canonical};
3-
use crate::lint::LintExpectation;
3+
use crate::lint::LintLevelMap;
44
use crate::metadata::ModChild;
55
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
66
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
@@ -44,14 +44,12 @@ use rustc_errors::ErrorGuaranteed;
4444
use rustc_hir as hir;
4545
use rustc_hir::def::DefKind;
4646
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
47-
use rustc_hir::hir_id::HirId;
4847
use rustc_hir::lang_items::{LangItem, LanguageItems};
4948
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
5049
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
5150
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
5251
use rustc_session::cstore::{CrateDepKind, CrateSource};
5352
use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
54-
use rustc_session::lint::LintExpectationId;
5553
use rustc_session::utils::NativeLibKind;
5654
use rustc_session::Limits;
5755
use rustc_span::symbol::Symbol;

‎compiler/rustc_query_impl/src/keys.rs

-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Defines the set of legal keys that can be used in queries.
22
33
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
4-
use rustc_hir::hir_id::HirId;
54
use rustc_middle::infer::canonical::Canonical;
65
use rustc_middle::mir;
76
use rustc_middle::traits;
@@ -544,19 +543,3 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) {
544543
DUMMY_SP
545544
}
546545
}
547-
548-
impl Key for HirId {
549-
#[inline(always)]
550-
fn query_crate_is_local(&self) -> bool {
551-
true
552-
}
553-
554-
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
555-
tcx.hir().span(*self)
556-
}
557-
558-
#[inline(always)]
559-
fn key_as_def_id(&self) -> Option<DefId> {
560-
None
561-
}
562-
}

‎compiler/rustc_query_system/src/dep_graph/mod.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ impl<T: DepContext> HasDepContext for T {
6767
pub enum FingerprintStyle {
6868
/// The fingerprint is actually a DefPathHash.
6969
DefPathHash,
70-
/// The fingerprint is actually a HirId.
71-
HirId,
7270
/// Query key was `()` or equivalent, so fingerprint is just zero.
7371
Unit,
7472
/// Some opaque hash.
@@ -79,9 +77,7 @@ impl FingerprintStyle {
7977
#[inline]
8078
pub fn reconstructible(self) -> bool {
8179
match self {
82-
FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => {
83-
true
84-
}
80+
FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true,
8581
FingerprintStyle::Opaque => false,
8682
}
8783
}

‎src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs

-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
#![deny(non_exhaustive_omitted_patterns)]
44
//~^ WARNING unknown lint: `non_exhaustive_omitted_patterns`
55
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
6-
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
76
#![allow(non_exhaustive_omitted_patterns)]
87
//~^ WARNING unknown lint: `non_exhaustive_omitted_patterns`
98
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
10-
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
119

1210
fn main() {
1311
enum Foo {
@@ -19,8 +17,6 @@ fn main() {
1917
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
2018
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
2119
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
22-
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
23-
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
2420
match Foo::A {
2521
Foo::A => {}
2622
Foo::B => {}
@@ -35,5 +31,4 @@ fn main() {
3531
}
3632
//~^^^ WARNING unknown lint: `non_exhaustive_omitted_patterns`
3733
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
38-
//~| WARNING unknown lint: `non_exhaustive_omitted_patterns`
3934
}

‎src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr

+11-61
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | #![deny(non_exhaustive_omitted_patterns)]
1010
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
1111

1212
warning: unknown lint: `non_exhaustive_omitted_patterns`
13-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:7:1
13+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:6:1
1414
|
1515
LL | #![allow(non_exhaustive_omitted_patterns)]
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL | #![allow(non_exhaustive_omitted_patterns)]
2020
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
2121

2222
warning: unknown lint: `non_exhaustive_omitted_patterns`
23-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:17:5
23+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5
2424
|
2525
LL | #[allow(non_exhaustive_omitted_patterns)]
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +30,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)]
3030
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
3131

3232
warning: unknown lint: `non_exhaustive_omitted_patterns`
33-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:17:5
33+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5
3434
|
3535
LL | #[allow(non_exhaustive_omitted_patterns)]
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)]
4040
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
4141

4242
warning: unknown lint: `non_exhaustive_omitted_patterns`
43-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:33:9
43+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:29:9
4444
|
4545
LL | #[warn(non_exhaustive_omitted_patterns)]
4646
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL | #![deny(non_exhaustive_omitted_patterns)]
6060
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
6161

6262
warning: unknown lint: `non_exhaustive_omitted_patterns`
63-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:7:1
63+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:6:1
6464
|
6565
LL | #![allow(non_exhaustive_omitted_patterns)]
6666
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL | #![allow(non_exhaustive_omitted_patterns)]
7070
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
7171

7272
warning: unknown lint: `non_exhaustive_omitted_patterns`
73-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:17:5
73+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5
7474
|
7575
LL | #[allow(non_exhaustive_omitted_patterns)]
7676
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)]
8080
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
8181

8282
warning: unknown lint: `non_exhaustive_omitted_patterns`
83-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:17:5
83+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5
8484
|
8585
LL | #[allow(non_exhaustive_omitted_patterns)]
8686
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | #[allow(non_exhaustive_omitted_patterns)]
9090
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
9191

9292
warning: unknown lint: `non_exhaustive_omitted_patterns`
93-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:33:9
93+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:29:9
9494
|
9595
LL | #[warn(non_exhaustive_omitted_patterns)]
9696
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,13 +100,13 @@ LL | #[warn(non_exhaustive_omitted_patterns)]
100100
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
101101

102102
error[E0004]: non-exhaustive patterns: `Foo::C` not covered
103-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:24:11
103+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:20:11
104104
|
105105
LL | match Foo::A {
106106
| ^^^^^^ pattern `Foo::C` not covered
107107
|
108108
note: `Foo` defined here
109-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:14:15
109+
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:12:15
110110
|
111111
LL | enum Foo {
112112
| ---
@@ -119,56 +119,6 @@ LL ~ Foo::B => {}
119119
LL + Foo::C => todo!()
120120
|
121121

122-
warning: unknown lint: `non_exhaustive_omitted_patterns`
123-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:3:1
124-
|
125-
LL | #![deny(non_exhaustive_omitted_patterns)]
126-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127-
|
128-
= note: the `non_exhaustive_omitted_patterns` lint is unstable
129-
= note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
130-
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
131-
132-
warning: unknown lint: `non_exhaustive_omitted_patterns`
133-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:7:1
134-
|
135-
LL | #![allow(non_exhaustive_omitted_patterns)]
136-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
137-
|
138-
= note: the `non_exhaustive_omitted_patterns` lint is unstable
139-
= note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
140-
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
141-
142-
warning: unknown lint: `non_exhaustive_omitted_patterns`
143-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:17:5
144-
|
145-
LL | #[allow(non_exhaustive_omitted_patterns)]
146-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
147-
|
148-
= note: the `non_exhaustive_omitted_patterns` lint is unstable
149-
= note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
150-
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
151-
152-
warning: unknown lint: `non_exhaustive_omitted_patterns`
153-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:17:5
154-
|
155-
LL | #[allow(non_exhaustive_omitted_patterns)]
156-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
157-
|
158-
= note: the `non_exhaustive_omitted_patterns` lint is unstable
159-
= note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
160-
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
161-
162-
warning: unknown lint: `non_exhaustive_omitted_patterns`
163-
--> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:33:9
164-
|
165-
LL | #[warn(non_exhaustive_omitted_patterns)]
166-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
167-
|
168-
= note: the `non_exhaustive_omitted_patterns` lint is unstable
169-
= note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
170-
= help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
171-
172-
error: aborting due to previous error; 15 warnings emitted
122+
error: aborting due to previous error; 10 warnings emitted
173123

174124
For more information about this error, try `rustc --explain E0004`.

‎src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/force_warn_expected_lints_fulfilled.rs:10:5
3+
|
4+
LL | while true {
5+
| ^^^^^^^^^^ help: use `loop`
6+
|
7+
= note: requested on the command line with `--force-warn while-true`
8+
19
warning: unused variable: `x`
210
--> $DIR/force_warn_expected_lints_fulfilled.rs:20:9
311
|
@@ -28,13 +36,5 @@ LL | let mut what_does_the_fox_say = "*ding* *deng* *dung*";
2836
|
2937
= note: requested on the command line with `--force-warn unused-mut`
3038

31-
warning: denote infinite loops with `loop { ... }`
32-
--> $DIR/force_warn_expected_lints_fulfilled.rs:10:5
33-
|
34-
LL | while true {
35-
| ^^^^^^^^^^ help: use `loop`
36-
|
37-
= note: requested on the command line with `--force-warn while-true`
38-
3939
warning: 5 warnings emitted
4040

0 commit comments

Comments
 (0)
Please sign in to comment.