Skip to content

Commit 24d06a9

Browse files
committed
Add cache-based fast path for cfgs and check-cfgs
1 parent aa029ce commit 24d06a9

File tree

3 files changed

+55
-32
lines changed

3 files changed

+55
-32
lines changed

compiler/rustc_attr/src/builtin.rs

+32-30
Original file line numberDiff line numberDiff line change
@@ -525,38 +525,40 @@ pub fn cfg_matches(
525525
) -> bool {
526526
eval_condition(cfg, sess, features, &mut |cfg| {
527527
try_gate_cfg(cfg.name, cfg.span, sess, features);
528-
match sess.psess.check_config.expecteds.get(&cfg.name) {
529-
Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => {
530-
sess.psess.buffer_lint_with_diagnostic(
531-
UNEXPECTED_CFGS,
532-
cfg.span,
533-
lint_node_id,
534-
if let Some(value) = cfg.value {
535-
format!("unexpected `cfg` condition value: `{value}`")
536-
} else {
537-
format!("unexpected `cfg` condition value: (none)")
538-
},
539-
BuiltinLintDiag::UnexpectedCfgValue(
540-
(cfg.name, cfg.name_span),
541-
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
542-
),
543-
);
544-
}
545-
None if sess.psess.check_config.exhaustive_names => {
546-
sess.psess.buffer_lint_with_diagnostic(
547-
UNEXPECTED_CFGS,
548-
cfg.span,
549-
lint_node_id,
550-
format!("unexpected `cfg` condition name: `{}`", cfg.name),
551-
BuiltinLintDiag::UnexpectedCfgName(
552-
(cfg.name, cfg.name_span),
553-
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
554-
),
555-
);
528+
sess.psess.config_cache.contains(&(cfg.name, cfg.value)) || {
529+
match sess.psess.check_config.expecteds.get(&cfg.name) {
530+
Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => {
531+
sess.psess.buffer_lint_with_diagnostic(
532+
UNEXPECTED_CFGS,
533+
cfg.span,
534+
lint_node_id,
535+
if let Some(value) = cfg.value {
536+
format!("unexpected `cfg` condition value: `{value}`")
537+
} else {
538+
format!("unexpected `cfg` condition value: (none)")
539+
},
540+
BuiltinLintDiag::UnexpectedCfgValue(
541+
(cfg.name, cfg.name_span),
542+
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
543+
),
544+
);
545+
}
546+
None if sess.psess.check_config.exhaustive_names => {
547+
sess.psess.buffer_lint_with_diagnostic(
548+
UNEXPECTED_CFGS,
549+
cfg.span,
550+
lint_node_id,
551+
format!("unexpected `cfg` condition name: `{}`", cfg.name),
552+
BuiltinLintDiag::UnexpectedCfgName(
553+
(cfg.name, cfg.name_span),
554+
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
555+
),
556+
);
557+
}
558+
_ => { /* not unexpected */ }
556559
}
557-
_ => { /* not unexpected */ }
560+
sess.psess.config.contains(&(cfg.name, cfg.value))
558561
}
559-
sess.psess.config.contains(&(cfg.name, cfg.value))
560562
})
561563
}
562564

compiler/rustc_interface/src/interface.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_query_impl::QueryCtxt;
1717
use rustc_query_system::query::print_query_stack;
1818
use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
1919
use rustc_session::filesearch::sysroot_candidates;
20-
use rustc_session::parse::ParseSess;
20+
use rustc_session::parse::{CfgCache, ParseSess};
2121
use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
2222
use rustc_span::source_map::FileLoader;
2323
use rustc_span::symbol::sym;
@@ -402,6 +402,23 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
402402
check_cfg.fill_well_known(&sess.target);
403403
sess.psess.check_config = check_cfg;
404404

405+
let mut config_cache = CfgCache::default();
406+
if sess.psess.check_config.expecteds.is_empty() {
407+
config_cache.extend(sess.psess.config.iter().copied());
408+
} else {
409+
#[allow(rustc::potential_query_instability)]
410+
for (n, v) in &sess.psess.check_config.expecteds {
411+
if let ExpectedValues::Some(v) = v {
412+
for v in v {
413+
if sess.psess.config.contains(&(*n, *v)) {
414+
config_cache.insert((*n, *v));
415+
}
416+
}
417+
}
418+
}
419+
}
420+
sess.psess.config_cache = config_cache;
421+
405422
if let Some(psess_created) = config.psess_created {
406423
psess_created(&mut sess.psess);
407424
}

compiler/rustc_session/src/parse.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::lint::{
1111
};
1212
use crate::Session;
1313
use rustc_ast::node_id::NodeId;
14-
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
14+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
1515
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
1616
use rustc_errors::emitter::{stderr_destination, HumanEmitter, SilentEmitter};
1717
use rustc_errors::{
@@ -196,12 +196,15 @@ pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
196196
}
197197
}
198198

199+
pub type CfgCache = FxHashSet<(Symbol, Option<Symbol>)>;
200+
199201
/// Info about a parsing session.
200202
pub struct ParseSess {
201203
pub dcx: DiagCtxt,
202204
pub unstable_features: UnstableFeatures,
203205
pub config: Cfg,
204206
pub check_config: CheckCfg,
207+
pub config_cache: CfgCache,
205208
pub edition: Edition,
206209
/// Places where raw identifiers were used. This is used to avoid complaining about idents
207210
/// clashing with keywords in new editions.
@@ -250,6 +253,7 @@ impl ParseSess {
250253
unstable_features: UnstableFeatures::from_environment(None),
251254
config: Cfg::default(),
252255
check_config: CheckCfg::default(),
256+
config_cache: CfgCache::default(),
253257
edition: ExpnId::root().expn_data().edition,
254258
raw_identifier_spans: Default::default(),
255259
bad_unicode_identifiers: Lock::new(Default::default()),

0 commit comments

Comments
 (0)