Skip to content

Commit 918cc57

Browse files
committed
Move lint_store from GlobalCtxt to Session.
This was made possible by the removal of plugin support, which simplified lint store creation. This simplifies the places in rustc and rustdoc that call `describe_lints`, which are early on. The lint store is now built before those places, so they don't have to create their own lint store for temporary use, they can just use the main one. Note: there are two clippy test changes. clippy loads the `clippy.toml` file into the source map during lint registration, and this now happens earlier than it used to, before the Rust source code is loaded. This exposes some latent bugs in clippy where it assumes invalid things about spans and source map offsets. These are in the process of being fixed elsewhere, as described in #117649.
1 parent 0f0252c commit 918cc57

File tree

11 files changed

+56
-65
lines changed

11 files changed

+56
-65
lines changed

compiler/rustc_driver_impl/src/lib.rs

+6-16
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_feature::find_gated_cfg;
3333
use rustc_fluent_macro::fluent_messages;
3434
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
3535
use rustc_interface::{interface, Queries};
36-
use rustc_lint::{unerased_lint_store, LintStore};
36+
use rustc_lint::unerased_lint_store;
3737
use rustc_metadata::locator;
3838
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
3939
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
@@ -356,16 +356,7 @@ fn run_compiler(
356356
let handler = EarlyErrorHandler::new(sopts.error_format);
357357

358358
if sopts.describe_lints {
359-
let mut lint_store =
360-
rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
361-
let registered_lints =
362-
if let Some(register_lints) = compiler.register_lints() {
363-
register_lints(compiler.session(), &mut lint_store);
364-
true
365-
} else {
366-
false
367-
};
368-
describe_lints(compiler.session(), &lint_store, registered_lints);
359+
describe_lints(compiler.session());
369360
return;
370361
}
371362
let should_stop = print_crate_info(
@@ -442,9 +433,7 @@ fn run_compiler(
442433
}
443434

444435
if sess.opts.describe_lints {
445-
queries
446-
.global_ctxt()?
447-
.enter(|tcx| describe_lints(sess, unerased_lint_store(tcx), true));
436+
describe_lints(sess);
448437
return early_exit();
449438
}
450439

@@ -995,7 +984,7 @@ the command line flag directly.
995984
}
996985

997986
/// Write to stdout lint command options, together with a list of all available lints
998-
pub fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_lints: bool) {
987+
pub fn describe_lints(sess: &Session) {
999988
safe_println!(
1000989
"
1001990
Available lint options:
@@ -1021,6 +1010,7 @@ Available lint options:
10211010
lints
10221011
}
10231012

1013+
let lint_store = unerased_lint_store(sess);
10241014
let (loaded, builtin): (Vec<_>, _) =
10251015
lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_loaded);
10261016
let loaded = sort_lints(sess, loaded);
@@ -1098,7 +1088,7 @@ Available lint options:
10981088

10991089
print_lint_groups(builtin_groups, true);
11001090

1101-
match (loaded_lints, loaded.len(), loaded_groups.len()) {
1091+
match (sess.registered_lints, loaded.len(), loaded_groups.len()) {
11021092
(false, 0, _) | (false, _, 0) => {
11031093
safe_println!("Lint tools like Clippy can load additional lints and lint groups.");
11041094
}

compiler/rustc_interface/src/interface.rs

+9
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,15 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
452452
config.expanded_args,
453453
);
454454

455+
// Even though the session holds the lint store, we can't build the
456+
// lint store until the session exists. So do that now.
457+
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
458+
if let Some(register_lints) = config.register_lints.as_deref() {
459+
register_lints(&sess, &mut lint_store);
460+
sess.registered_lints = true;
461+
}
462+
sess.lint_store = Some(Lrc::new(lint_store));
463+
455464
codegen_backend.init(&sess);
456465

457466
let cfg = parse_cfg(&handler, config.crate_cfg);

compiler/rustc_interface/src/passes.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fn configure_and_expand(
127127
let tcx = resolver.tcx();
128128
let sess = tcx.sess;
129129
let features = tcx.features();
130-
let lint_store = unerased_lint_store(tcx);
130+
let lint_store = unerased_lint_store(&tcx.sess);
131131
let crate_name = tcx.crate_name(LOCAL_CRATE);
132132
let lint_check_node = (&krate, pre_configured_attrs);
133133
pre_expansion_lint(
@@ -319,7 +319,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
319319
}
320320
});
321321

322-
let lint_store = unerased_lint_store(tcx);
322+
let lint_store = unerased_lint_store(&tcx.sess);
323323
rustc_lint::check_ast_node(
324324
sess,
325325
tcx.features(),
@@ -634,7 +634,6 @@ pub fn create_global_ctxt<'tcx>(
634634
compiler: &'tcx Compiler,
635635
crate_types: Vec<CrateType>,
636636
stable_crate_id: StableCrateId,
637-
lint_store: Lrc<LintStore>,
638637
dep_graph: DepGraph,
639638
untracked: Untracked,
640639
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
@@ -665,7 +664,6 @@ pub fn create_global_ctxt<'tcx>(
665664
sess,
666665
crate_types,
667666
stable_crate_id,
668-
lint_store,
669667
arena,
670668
hir_arena,
671669
untracked,

compiler/rustc_interface/src/queries.rs

-7
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,6 @@ impl<'tcx> Queries<'tcx> {
148148
);
149149
let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
150150

151-
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
152-
if let Some(register_lints) = self.compiler.register_lints.as_deref() {
153-
register_lints(sess, &mut lint_store);
154-
}
155-
let lint_store = Lrc::new(lint_store);
156-
157151
let cstore = FreezeLock::new(Box::new(CStore::new(
158152
self.codegen_backend().metadata_loader(),
159153
stable_crate_id,
@@ -168,7 +162,6 @@ impl<'tcx> Queries<'tcx> {
168162
self.compiler,
169163
crate_types,
170164
stable_crate_id,
171-
lint_store,
172165
dep_graph,
173166
untracked,
174167
&self.gcx_cell,

compiler/rustc_lint/src/late.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,25 @@
1717
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
1818
use rustc_ast as ast;
1919
use rustc_data_structures::stack::ensure_sufficient_stack;
20-
use rustc_data_structures::sync::join;
20+
use rustc_data_structures::sync::{join, Lrc};
2121
use rustc_hir as hir;
2222
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
2323
use rustc_hir::intravisit as hir_visit;
2424
use rustc_middle::hir::nested_filter;
2525
use rustc_middle::ty::{self, TyCtxt};
2626
use rustc_session::lint::LintPass;
27+
use rustc_session::Session;
2728
use rustc_span::Span;
2829

2930
use std::any::Any;
3031
use std::cell::Cell;
3132

3233
/// Extract the `LintStore` from the query context.
33-
/// This function exists because we've erased `LintStore` as `dyn Any` in the context.
34-
pub fn unerased_lint_store(tcx: TyCtxt<'_>) -> &LintStore {
35-
let store: &dyn Any = &*tcx.lint_store;
34+
/// This function exists because we've erased `LintStore` as `dyn Any` in the session.
35+
pub fn unerased_lint_store(sess: &Session) -> &LintStore {
36+
assert!(sess.lint_store.is_some());
37+
let store: &Lrc<_> = sess.lint_store.as_ref().unwrap();
38+
let store: &dyn Any = &**store;
3639
store.downcast_ref().unwrap()
3740
}
3841

@@ -361,8 +364,11 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
361364
// Note: `passes` is often empty. In that case, it's faster to run
362365
// `builtin_lints` directly rather than bundling it up into the
363366
// `RuntimeCombinedLateLintPass`.
364-
let mut passes: Vec<_> =
365-
unerased_lint_store(tcx).late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
367+
let mut passes: Vec<_> = unerased_lint_store(&tcx.sess)
368+
.late_module_passes
369+
.iter()
370+
.map(|mk_pass| (mk_pass)(tcx))
371+
.collect();
366372
if passes.is_empty() {
367373
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
368374
} else {
@@ -399,7 +405,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>(
399405
fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) {
400406
// Note: `passes` is often empty.
401407
let mut passes: Vec<_> =
402-
unerased_lint_store(tcx).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
408+
unerased_lint_store(&tcx.sess).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
403409

404410
if passes.is_empty() {
405411
return;

compiler/rustc_lint/src/levels.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl LintLevelSets {
123123
}
124124

125125
fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> {
126-
let store = unerased_lint_store(tcx);
126+
let store = unerased_lint_store(&tcx.sess);
127127

128128
let mut builder = LintLevelsBuilder {
129129
sess: tcx.sess,
@@ -152,7 +152,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
152152

153153
#[instrument(level = "trace", skip(tcx), ret)]
154154
fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap {
155-
let store = unerased_lint_store(tcx);
155+
let store = unerased_lint_store(&tcx.sess);
156156
let attrs = tcx.hir_attrs(owner);
157157

158158
let mut levels = LintLevelsBuilder {

compiler/rustc_middle/src/ty/context.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
3939
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
4040
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4141
use rustc_data_structures::steal::Steal;
42-
use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, WorkerLocal};
42+
use rustc_data_structures::sync::{FreezeReadGuard, Lock, WorkerLocal};
4343
use rustc_data_structures::unord::UnordSet;
4444
use rustc_errors::{
4545
DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
@@ -69,7 +69,6 @@ use rustc_type_ir::TyKind::*;
6969
use rustc_type_ir::WithCachedTypeInfo;
7070
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
7171

72-
use std::any::Any;
7372
use std::borrow::Borrow;
7473
use std::cmp::Ordering;
7574
use std::fmt;
@@ -544,12 +543,6 @@ pub struct GlobalCtxt<'tcx> {
544543
/// `rustc_symbol_mangling` crate for more information.
545544
stable_crate_id: StableCrateId,
546545

547-
/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
548-
///
549-
/// FIXME(Centril): consider `dyn LintStoreMarker` once
550-
/// we can upcast to `Any` for some additional type safety.
551-
pub lint_store: Lrc<dyn Any + sync::DynSync + sync::DynSend>,
552-
553546
pub dep_graph: DepGraph,
554547

555548
pub prof: SelfProfilerRef,
@@ -709,7 +702,6 @@ impl<'tcx> TyCtxt<'tcx> {
709702
s: &'tcx Session,
710703
crate_types: Vec<CrateType>,
711704
stable_crate_id: StableCrateId,
712-
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
713705
arena: &'tcx WorkerLocal<Arena<'tcx>>,
714706
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
715707
untracked: Untracked,
@@ -730,7 +722,6 @@ impl<'tcx> TyCtxt<'tcx> {
730722
sess: s,
731723
crate_types,
732724
stable_crate_id,
733-
lint_store,
734725
arena,
735726
hir_arena,
736727
interners,

compiler/rustc_session/src/session.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
1717
use rustc_data_structures::jobserver::{self, Client};
1818
use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
1919
use rustc_data_structures::sync::{
20-
AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
20+
AtomicU64, AtomicUsize, DynSend, DynSync, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
2121
};
2222
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
2323
use rustc_errors::emitter::{DynEmitter, EmitterWriter, HumanReadableErrorType};
@@ -39,6 +39,7 @@ use rustc_target::spec::{
3939
DebuginfoKind, SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
4040
};
4141

42+
use std::any::Any;
4243
use std::cell::{self, RefCell};
4344
use std::env;
4445
use std::fmt;
@@ -173,6 +174,15 @@ pub struct Session {
173174
/// false positives about a job server in our environment.
174175
pub jobserver: Client,
175176

177+
/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
178+
///
179+
/// FIXME(Centril): consider `dyn LintStoreMarker` once
180+
/// we can upcast to `Any` for some additional type safety.
181+
pub lint_store: Option<Lrc<dyn Any + DynSync + DynSend>>,
182+
183+
/// Should be set if any lints are registered in `lint_store`.
184+
pub registered_lints: bool,
185+
176186
/// Cap lint level specified by a driver specifically.
177187
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
178188

@@ -1525,6 +1535,8 @@ pub fn build_session(
15251535
optimization_fuel,
15261536
print_fuel,
15271537
jobserver: jobserver::client(),
1538+
lint_store: None,
1539+
registered_lints: false,
15281540
driver_lint_caps,
15291541
ctfe_backtrace,
15301542
miri_unleashed_features: Lock::new(Default::default()),

src/librustdoc/lib.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -796,14 +796,7 @@ fn main_args(
796796
let sess = compiler.session();
797797

798798
if sess.opts.describe_lints {
799-
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
800-
let registered_lints = if let Some(register_lints) = compiler.register_lints() {
801-
register_lints(sess, &mut lint_store);
802-
true
803-
} else {
804-
false
805-
};
806-
rustc_driver::describe_lints(sess, &lint_store, registered_lints);
799+
rustc_driver::describe_lints(sess);
807800
return Ok(());
808801
}
809802

src/tools/clippy/tests/ui/dbg_macro.stderr

+3-4
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,12 @@ error: the `dbg!` macro is intended as a debugging tool
103103
--> $DIR/dbg_macro.rs:53:5
104104
|
105105
LL | dbg!();
106-
| ^^^^^^^
106+
| ^^^^^^
107107
|
108108
help: remove the invocation before committing it to a version control system
109109
|
110-
LL - dbg!();
111-
LL +
112-
|
110+
LL | ();
111+
| ~~
113112

114113
error: the `dbg!` macro is intended as a debugging tool
115114
--> $DIR/dbg_macro.rs:56:13

src/tools/clippy/tests/ui/macro_use_imports.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
2-
--> $DIR/macro_use_imports.rs:25:5
2+
--> $DIR/macro_use_imports.rs:23:5
33
|
44
LL | #[macro_use]
5-
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
5+
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};`
66
|
77
= note: `-D clippy::macro-use-imports` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]`
99

1010
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
11-
--> $DIR/macro_use_imports.rs:23:5
11+
--> $DIR/macro_use_imports.rs:21:5
1212
|
1313
LL | #[macro_use]
14-
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};`
14+
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
1515

1616
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
17-
--> $DIR/macro_use_imports.rs:21:5
17+
--> $DIR/macro_use_imports.rs:25:5
1818
|
1919
LL | #[macro_use]
20-
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
20+
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
2121

2222
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
2323
--> $DIR/macro_use_imports.rs:19:5

0 commit comments

Comments
 (0)