Skip to content

Commit 51b2338

Browse files
committed
rustc_lint: Reuse the set of registered tools from resolver
1 parent 452aa81 commit 51b2338

File tree

10 files changed

+70
-56
lines changed

10 files changed

+70
-56
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
88
use rustc_ast::visit::{AssocCtxt, Visitor};
99
use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind};
1010
use rustc_attr::{self as attr, Deprecation, Stability};
11-
use rustc_data_structures::fx::FxHashMap;
11+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1212
use rustc_data_structures::sync::{self, Lrc};
1313
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
1414
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
@@ -920,6 +920,9 @@ pub trait ResolverExpand {
920920
/// we generated proc macros harnesses, so that we can map
921921
/// HIR proc macros items back to their harness items.
922922
fn declare_proc_macro(&mut self, id: NodeId);
923+
924+
/// Tools registered with `#![register_tool]` and used by tool attributes and lints.
925+
fn registered_tools(&self) -> &FxHashSet<Ident>;
923926
}
924927

925928
#[derive(Clone, Default)]

compiler/rustc_interface/src/passes.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::parallel;
1111
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
1212
use rustc_data_structures::temp_dir::MaybeTempDir;
1313
use rustc_errors::{Applicability, ErrorReported, PResult};
14-
use rustc_expand::base::ExtCtxt;
14+
use rustc_expand::base::{ExtCtxt, ResolverExpand};
1515
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
1616
use rustc_hir::Crate;
1717
use rustc_lint::LintStore;
@@ -20,7 +20,7 @@ use rustc_metadata::{encode_metadata, EncodedMetadata};
2020
use rustc_middle::arena::Arena;
2121
use rustc_middle::dep_graph::DepGraph;
2222
use rustc_middle::ty::query::{ExternProviders, Providers};
23-
use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
23+
use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, ResolverOutputs, TyCtxt};
2424
use rustc_mir_build as mir_build;
2525
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
2626
use rustc_passes::{self, hir_stats, layout_test};
@@ -236,7 +236,7 @@ pub fn register_plugins<'a>(
236236
fn pre_expansion_lint(
237237
sess: &Session,
238238
lint_store: &LintStore,
239-
crate_attrs: &[ast::Attribute],
239+
registered_tools: &RegisteredTools,
240240
check_node: &ast::Crate,
241241
node_name: &str,
242242
) {
@@ -245,7 +245,7 @@ fn pre_expansion_lint(
245245
sess,
246246
true,
247247
lint_store,
248-
crate_attrs,
248+
registered_tools,
249249
None,
250250
rustc_lint::BuiltinCombinedPreExpansionLintPass::new(),
251251
check_node,
@@ -265,7 +265,7 @@ pub fn configure_and_expand(
265265
resolver: &mut Resolver<'_>,
266266
) -> Result<ast::Crate> {
267267
tracing::trace!("configure_and_expand");
268-
pre_expansion_lint(sess, lint_store, &krate.attrs, &krate, crate_name);
268+
pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name);
269269
rustc_builtin_macros::register_builtin_macros(resolver);
270270

271271
krate = sess.time("crate_injection", || {
@@ -321,10 +321,10 @@ pub fn configure_and_expand(
321321
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
322322
};
323323

324-
let crate_attrs = krate.attrs.clone();
324+
let registered_tools = resolver.registered_tools().clone();
325325
let extern_mod_loaded = |ident: Ident, attrs, items, span| {
326326
let krate = ast::Crate { attrs, items, span, id: DUMMY_NODE_ID, is_placeholder: false };
327-
pre_expansion_lint(sess, lint_store, &crate_attrs, &krate, ident.name.as_str());
327+
pre_expansion_lint(sess, lint_store, &registered_tools, &krate, ident.name.as_str());
328328
(krate.attrs, krate.items)
329329
};
330330
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&extern_mod_loaded));
@@ -499,12 +499,13 @@ pub fn lower_to_hir<'res, 'tcx>(
499499
);
500500

501501
sess.time("early_lint_checks", || {
502+
let lint_buffer = Some(std::mem::take(resolver.lint_buffer()));
502503
rustc_lint::check_ast_node(
503504
sess,
504505
false,
505506
lint_store,
506-
&krate.attrs,
507-
Some(std::mem::take(resolver.lint_buffer())),
507+
resolver.registered_tools(),
508+
lint_buffer,
508509
rustc_lint::BuiltinCombinedEarlyLintPass::new(),
509510
&krate,
510511
)

compiler/rustc_lint/src/context.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
1717
use self::TargetLint::*;
1818

19-
use crate::levels::{is_known_lint_tool, LintLevelsBuilder};
19+
use crate::levels::LintLevelsBuilder;
2020
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
21-
use ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
22-
use rustc_ast as ast;
21+
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
2322
use rustc_data_structures::fx::FxHashMap;
2423
use rustc_data_structures::sync;
2524
use rustc_errors::{struct_span_err, Applicability, SuggestionStyle};
@@ -32,13 +31,14 @@ use rustc_middle::middle::privacy::AccessLevels;
3231
use rustc_middle::middle::stability;
3332
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
3433
use rustc_middle::ty::print::with_no_trimmed_paths;
35-
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
34+
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt};
3635
use rustc_serialize::json::Json;
3736
use rustc_session::lint::{BuiltinLintDiagnostics, ExternDepSpec};
3837
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
3938
use rustc_session::Session;
4039
use rustc_span::lev_distance::find_best_match_for_name;
41-
use rustc_span::{symbol::Symbol, BytePos, MultiSpan, Span, DUMMY_SP};
40+
use rustc_span::symbol::{sym, Ident, Symbol};
41+
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
4242
use rustc_target::abi;
4343
use tracing::debug;
4444

@@ -313,7 +313,7 @@ impl LintStore {
313313
sess: &Session,
314314
lint_name: &str,
315315
level: Level,
316-
crate_attrs: &[ast::Attribute],
316+
registered_tools: &RegisteredTools,
317317
) {
318318
let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
319319
if lint_name_only == crate::WARNINGS.name_lower() && level == Level::ForceWarn {
@@ -326,7 +326,7 @@ impl LintStore {
326326
)
327327
.emit();
328328
}
329-
let db = match self.check_lint_name(sess, lint_name_only, tool_name, crate_attrs) {
329+
let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
330330
CheckLintNameResult::Ok(_) => None,
331331
CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)),
332332
CheckLintNameResult::NoLint(suggestion) => {
@@ -397,13 +397,16 @@ impl LintStore {
397397
/// printing duplicate warnings.
398398
pub fn check_lint_name(
399399
&self,
400-
sess: &Session,
401400
lint_name: &str,
402401
tool_name: Option<Symbol>,
403-
crate_attrs: &[ast::Attribute],
402+
registered_tools: &RegisteredTools,
404403
) -> CheckLintNameResult<'_> {
405404
if let Some(tool_name) = tool_name {
406-
if !is_known_lint_tool(tool_name, sess, crate_attrs) {
405+
// FIXME: rustc and rustdoc are considered tools for lints, but not for attributes.
406+
if tool_name != sym::rustc
407+
&& tool_name != sym::rustdoc
408+
&& !registered_tools.contains(&Ident::with_dummy_span(tool_name))
409+
{
407410
return CheckLintNameResult::NoTool;
408411
}
409412
}
@@ -794,11 +797,16 @@ impl<'a> EarlyContext<'a> {
794797
sess: &'a Session,
795798
warn_about_weird_lints: bool,
796799
lint_store: &'a LintStore,
797-
crate_attrs: &'a [ast::Attribute],
800+
registered_tools: &'a RegisteredTools,
798801
buffered: LintBuffer,
799802
) -> EarlyContext<'a> {
800803
EarlyContext {
801-
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, crate_attrs),
804+
builder: LintLevelsBuilder::new(
805+
sess,
806+
warn_about_weird_lints,
807+
lint_store,
808+
registered_tools,
809+
),
802810
buffered,
803811
}
804812
}

compiler/rustc_lint/src/early.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::passes::{EarlyLintPass, EarlyLintPassObject};
1919
use rustc_ast as ast;
2020
use rustc_ast::visit as ast_visit;
2121
use rustc_ast::AstLike;
22+
use rustc_middle::ty::RegisteredTools;
2223
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
2324
use rustc_session::Session;
2425
use rustc_span::symbol::Ident;
@@ -329,13 +330,19 @@ fn early_lint_node(
329330
sess: &Session,
330331
warn_about_weird_lints: bool,
331332
lint_store: &LintStore,
332-
crate_attrs: &[ast::Attribute],
333+
registered_tools: &RegisteredTools,
333334
buffered: LintBuffer,
334335
pass: impl EarlyLintPass,
335336
check_node: &ast::Crate,
336337
) -> LintBuffer {
337338
let mut cx = EarlyContextAndPass {
338-
context: EarlyContext::new(sess, warn_about_weird_lints, lint_store, crate_attrs, buffered),
339+
context: EarlyContext::new(
340+
sess,
341+
warn_about_weird_lints,
342+
lint_store,
343+
registered_tools,
344+
buffered,
345+
),
339346
pass,
340347
};
341348

@@ -351,7 +358,7 @@ pub fn check_ast_node(
351358
sess: &Session,
352359
pre_expansion: bool,
353360
lint_store: &LintStore,
354-
crate_attrs: &[ast::Attribute],
361+
registered_tools: &RegisteredTools,
355362
lint_buffer: Option<LintBuffer>,
356363
builtin_lints: impl EarlyLintPass,
357364
check_node: &ast::Crate,
@@ -366,7 +373,7 @@ pub fn check_ast_node(
366373
sess,
367374
pre_expansion,
368375
lint_store,
369-
crate_attrs,
376+
registered_tools,
370377
buffered,
371378
builtin_lints,
372379
check_node,
@@ -377,7 +384,7 @@ pub fn check_ast_node(
377384
sess,
378385
false,
379386
lint_store,
380-
crate_attrs,
387+
registered_tools,
381388
buffered,
382389
EarlyLintPassObjects { lints: &mut passes[..] },
383390
check_node,
@@ -391,7 +398,7 @@ pub fn check_ast_node(
391398
sess,
392399
pre_expansion && i == 0,
393400
lint_store,
394-
crate_attrs,
401+
registered_tools,
395402
buffered,
396403
EarlyLintPassObjects { lints: slice::from_mut(pass) },
397404
check_node,

compiler/rustc_lint/src/levels.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::lint::{
1414
COMMAND_LINE,
1515
};
1616
use rustc_middle::ty::query::Providers;
17-
use rustc_middle::ty::TyCtxt;
17+
use rustc_middle::ty::{RegisteredTools, TyCtxt};
1818
use rustc_session::lint::{
1919
builtin::{self, FORBIDDEN_LINT_GROUPS},
2020
Level, Lint, LintId,
@@ -27,8 +27,8 @@ use tracing::debug;
2727

2828
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
2929
let store = unerased_lint_store(tcx);
30-
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
31-
let levels = LintLevelsBuilder::new(tcx.sess, false, &store, crate_attrs);
30+
let levels =
31+
LintLevelsBuilder::new(tcx.sess, false, &store, &tcx.resolutions(()).registered_tools);
3232
let mut builder = LintLevelMapBuilder { levels, tcx };
3333
let krate = tcx.hir().krate();
3434

@@ -49,7 +49,7 @@ pub struct LintLevelsBuilder<'s> {
4949
cur: LintStackIndex,
5050
warn_about_weird_lints: bool,
5151
store: &'s LintStore,
52-
crate_attrs: &'s [ast::Attribute],
52+
registered_tools: &'s RegisteredTools,
5353
}
5454

5555
pub struct BuilderPush {
@@ -62,7 +62,7 @@ impl<'s> LintLevelsBuilder<'s> {
6262
sess: &'s Session,
6363
warn_about_weird_lints: bool,
6464
store: &'s LintStore,
65-
crate_attrs: &'s [ast::Attribute],
65+
registered_tools: &'s RegisteredTools,
6666
) -> Self {
6767
let mut builder = LintLevelsBuilder {
6868
sess,
@@ -71,7 +71,7 @@ impl<'s> LintLevelsBuilder<'s> {
7171
id_to_set: Default::default(),
7272
warn_about_weird_lints,
7373
store,
74-
crate_attrs,
74+
registered_tools,
7575
};
7676
builder.process_command_line(sess, store);
7777
assert_eq!(builder.sets.list.len(), 1);
@@ -91,7 +91,7 @@ impl<'s> LintLevelsBuilder<'s> {
9191
self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
9292

9393
for &(ref lint_name, level) in &sess.opts.lint_opts {
94-
store.check_lint_name_cmdline(sess, &lint_name, level, self.crate_attrs);
94+
store.check_lint_name_cmdline(sess, &lint_name, level, self.registered_tools);
9595
let orig_level = level;
9696
let lint_flag_val = Symbol::intern(lint_name);
9797

@@ -314,7 +314,7 @@ impl<'s> LintLevelsBuilder<'s> {
314314
let tool_name = tool_ident.map(|ident| ident.name);
315315
let name = pprust::path_to_string(&meta_item.path);
316316
let lint_result =
317-
self.store.check_lint_name(sess, &name, tool_name, self.crate_attrs);
317+
self.store.check_lint_name(&name, tool_name, self.registered_tools);
318318
match &lint_result {
319319
CheckLintNameResult::Ok(ids) => {
320320
let src = LintLevelSource::Node(
@@ -463,7 +463,7 @@ impl<'s> LintLevelsBuilder<'s> {
463463
// Ignore any errors or warnings that happen because the new name is inaccurate
464464
// NOTE: `new_name` already includes the tool name, so we don't have to add it again.
465465
if let CheckLintNameResult::Ok(ids) =
466-
self.store.check_lint_name(sess, &new_name, None, self.crate_attrs)
466+
self.store.check_lint_name(&new_name, None, self.registered_tools)
467467
{
468468
let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason);
469469
for &id in ids {
@@ -566,20 +566,6 @@ impl<'s> LintLevelsBuilder<'s> {
566566
}
567567
}
568568

569-
pub fn is_known_lint_tool(m_item: Symbol, sess: &Session, attrs: &[ast::Attribute]) -> bool {
570-
if [sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item) {
571-
return true;
572-
}
573-
// Look for registered tools
574-
// NOTE: does no error handling; error handling is done by rustc_resolve.
575-
sess.filter_by_name(attrs, sym::register_tool)
576-
.filter_map(|attr| attr.meta_item_list())
577-
.flatten()
578-
.filter_map(|nested_meta| nested_meta.ident())
579-
.map(|ident| ident.name)
580-
.any(|name| name == m_item)
581-
}
582-
583569
struct LintLevelMapBuilder<'tcx> {
584570
levels: LintLevelsBuilder<'tcx>,
585571
tcx: TyCtxt<'tcx>,

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ use unused::*;
9696
pub use builtin::SoftLints;
9797
pub use context::{CheckLintNameResult, FindLintError, LintStore};
9898
pub use context::{EarlyContext, LateContext, LintContext};
99-
pub use early::check_ast_node;
99+
pub use early::{check_ast_node, EarlyCheckNode};
100100
pub use late::check_crate;
101101
pub use passes::{EarlyLintPass, LateLintPass};
102102
pub use rustc_session::lint::Level::{self, *};

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ mod sty;
119119

120120
// Data types
121121

122+
pub type RegisteredTools = FxHashSet<Ident>;
123+
122124
#[derive(Debug)]
123125
pub struct ResolverOutputs {
124126
pub definitions: rustc_hir::definitions::Definitions,
@@ -141,6 +143,7 @@ pub struct ResolverOutputs {
141143
/// Mapping from ident span to path span for paths that don't exist as written, but that
142144
/// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
143145
pub confused_type_with_std_module: FxHashMap<Span, Span>,
146+
pub registered_tools: RegisteredTools,
144147
}
145148

146149
#[derive(Clone, Copy, Debug)]

0 commit comments

Comments
 (0)