Skip to content

Commit

Permalink
Move lint_store from GlobalCtxt to Session.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nnethercote committed Nov 8, 2023
1 parent 0f0252c commit 918cc57
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 65 deletions.
22 changes: 6 additions & 16 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use rustc_feature::find_gated_cfg;
use rustc_fluent_macro::fluent_messages;
use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
use rustc_interface::{interface, Queries};
use rustc_lint::{unerased_lint_store, LintStore};
use rustc_lint::unerased_lint_store;
use rustc_metadata::locator;
use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
Expand Down Expand Up @@ -356,16 +356,7 @@ fn run_compiler(
let handler = EarlyErrorHandler::new(sopts.error_format);

if sopts.describe_lints {
let mut lint_store =
rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
let registered_lints =
if let Some(register_lints) = compiler.register_lints() {
register_lints(compiler.session(), &mut lint_store);
true
} else {
false
};
describe_lints(compiler.session(), &lint_store, registered_lints);
describe_lints(compiler.session());
return;
}
let should_stop = print_crate_info(
Expand Down Expand Up @@ -442,9 +433,7 @@ fn run_compiler(
}

if sess.opts.describe_lints {
queries
.global_ctxt()?
.enter(|tcx| describe_lints(sess, unerased_lint_store(tcx), true));
describe_lints(sess);
return early_exit();
}

Expand Down Expand Up @@ -995,7 +984,7 @@ the command line flag directly.
}

/// Write to stdout lint command options, together with a list of all available lints
pub fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_lints: bool) {
pub fn describe_lints(sess: &Session) {
safe_println!(
"
Available lint options:
Expand All @@ -1021,6 +1010,7 @@ Available lint options:
lints
}

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

print_lint_groups(builtin_groups, true);

match (loaded_lints, loaded.len(), loaded_groups.len()) {
match (sess.registered_lints, loaded.len(), loaded_groups.len()) {
(false, 0, _) | (false, _, 0) => {
safe_println!("Lint tools like Clippy can load additional lints and lint groups.");
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,15 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
config.expanded_args,
);

// Even though the session holds the lint store, we can't build the
// lint store until the session exists. So do that now.
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
if let Some(register_lints) = config.register_lints.as_deref() {
register_lints(&sess, &mut lint_store);
sess.registered_lints = true;
}
sess.lint_store = Some(Lrc::new(lint_store));

codegen_backend.init(&sess);

let cfg = parse_cfg(&handler, config.crate_cfg);
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn configure_and_expand(
let tcx = resolver.tcx();
let sess = tcx.sess;
let features = tcx.features();
let lint_store = unerased_lint_store(tcx);
let lint_store = unerased_lint_store(&tcx.sess);
let crate_name = tcx.crate_name(LOCAL_CRATE);
let lint_check_node = (&krate, pre_configured_attrs);
pre_expansion_lint(
Expand Down Expand Up @@ -319,7 +319,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
}
});

let lint_store = unerased_lint_store(tcx);
let lint_store = unerased_lint_store(&tcx.sess);
rustc_lint::check_ast_node(
sess,
tcx.features(),
Expand Down Expand Up @@ -634,7 +634,6 @@ pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
crate_types: Vec<CrateType>,
stable_crate_id: StableCrateId,
lint_store: Lrc<LintStore>,
dep_graph: DepGraph,
untracked: Untracked,
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
Expand Down Expand Up @@ -665,7 +664,6 @@ pub fn create_global_ctxt<'tcx>(
sess,
crate_types,
stable_crate_id,
lint_store,
arena,
hir_arena,
untracked,
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,6 @@ impl<'tcx> Queries<'tcx> {
);
let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;

let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
if let Some(register_lints) = self.compiler.register_lints.as_deref() {
register_lints(sess, &mut lint_store);
}
let lint_store = Lrc::new(lint_store);

let cstore = FreezeLock::new(Box::new(CStore::new(
self.codegen_backend().metadata_loader(),
stable_crate_id,
Expand All @@ -168,7 +162,6 @@ impl<'tcx> Queries<'tcx> {
self.compiler,
crate_types,
stable_crate_id,
lint_store,
dep_graph,
untracked,
&self.gcx_cell,
Expand Down
20 changes: 13 additions & 7 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
use rustc_ast as ast;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::join;
use rustc_data_structures::sync::{join, Lrc};
use rustc_hir as hir;
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
use rustc_hir::intravisit as hir_visit;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::LintPass;
use rustc_session::Session;
use rustc_span::Span;

use std::any::Any;
use std::cell::Cell;

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

Expand Down Expand Up @@ -361,8 +364,11 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
// Note: `passes` is often empty. In that case, it's faster to run
// `builtin_lints` directly rather than bundling it up into the
// `RuntimeCombinedLateLintPass`.
let mut passes: Vec<_> =
unerased_lint_store(tcx).late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
let mut passes: Vec<_> = unerased_lint_store(&tcx.sess)
.late_module_passes
.iter()
.map(|mk_pass| (mk_pass)(tcx))
.collect();
if passes.is_empty() {
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
} else {
Expand Down Expand Up @@ -399,7 +405,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>(
fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) {
// Note: `passes` is often empty.
let mut passes: Vec<_> =
unerased_lint_store(tcx).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
unerased_lint_store(&tcx.sess).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();

if passes.is_empty() {
return;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl LintLevelSets {
}

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

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

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

let mut levels = LintLevelsBuilder {
Expand Down
11 changes: 1 addition & 10 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, WorkerLocal};
use rustc_data_structures::sync::{FreezeReadGuard, Lock, WorkerLocal};
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
Expand Down Expand Up @@ -69,7 +69,6 @@ use rustc_type_ir::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};

use std::any::Any;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt;
Expand Down Expand Up @@ -544,12 +543,6 @@ pub struct GlobalCtxt<'tcx> {
/// `rustc_symbol_mangling` crate for more information.
stable_crate_id: StableCrateId,

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

pub dep_graph: DepGraph,

pub prof: SelfProfilerRef,
Expand Down Expand Up @@ -709,7 +702,6 @@ impl<'tcx> TyCtxt<'tcx> {
s: &'tcx Session,
crate_types: Vec<CrateType>,
stable_crate_id: StableCrateId,
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
untracked: Untracked,
Expand All @@ -730,7 +722,6 @@ impl<'tcx> TyCtxt<'tcx> {
sess: s,
crate_types,
stable_crate_id,
lint_store,
arena,
hir_arena,
interners,
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::jobserver::{self, Client};
use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
use rustc_data_structures::sync::{
AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
AtomicU64, AtomicUsize, DynSend, DynSync, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
};
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
use rustc_errors::emitter::{DynEmitter, EmitterWriter, HumanReadableErrorType};
Expand All @@ -39,6 +39,7 @@ use rustc_target::spec::{
DebuginfoKind, SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
};

use std::any::Any;
use std::cell::{self, RefCell};
use std::env;
use std::fmt;
Expand Down Expand Up @@ -173,6 +174,15 @@ pub struct Session {
/// false positives about a job server in our environment.
pub jobserver: Client,

/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
///
/// FIXME(Centril): consider `dyn LintStoreMarker` once
/// we can upcast to `Any` for some additional type safety.
pub lint_store: Option<Lrc<dyn Any + DynSync + DynSend>>,

/// Should be set if any lints are registered in `lint_store`.
pub registered_lints: bool,

/// Cap lint level specified by a driver specifically.
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,

Expand Down Expand Up @@ -1525,6 +1535,8 @@ pub fn build_session(
optimization_fuel,
print_fuel,
jobserver: jobserver::client(),
lint_store: None,
registered_lints: false,
driver_lint_caps,
ctfe_backtrace,
miri_unleashed_features: Lock::new(Default::default()),
Expand Down
9 changes: 1 addition & 8 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,14 +796,7 @@ fn main_args(
let sess = compiler.session();

if sess.opts.describe_lints {
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
let registered_lints = if let Some(register_lints) = compiler.register_lints() {
register_lints(sess, &mut lint_store);
true
} else {
false
};
rustc_driver::describe_lints(sess, &lint_store, registered_lints);
rustc_driver::describe_lints(sess);
return Ok(());
}

Expand Down
7 changes: 3 additions & 4 deletions src/tools/clippy/tests/ui/dbg_macro.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,12 @@ error: the `dbg!` macro is intended as a debugging tool
--> $DIR/dbg_macro.rs:53:5
|
LL | dbg!();
| ^^^^^^^
| ^^^^^^
|
help: remove the invocation before committing it to a version control system
|
LL - dbg!();
LL +
|
LL | ();
| ~~

error: the `dbg!` macro is intended as a debugging tool
--> $DIR/dbg_macro.rs:56:13
Expand Down
12 changes: 6 additions & 6 deletions src/tools/clippy/tests/ui/macro_use_imports.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:25:5
--> $DIR/macro_use_imports.rs:23:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};`
|
= note: `-D clippy::macro-use-imports` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]`

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

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

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

0 comments on commit 918cc57

Please sign in to comment.