diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2021-09-29 01:17:54 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2022-01-23 18:51:51 +0800 |
| commit | 51b23386114ba7eba5dcbb5cbb7995575d7c0d8b (patch) | |
| tree | e16227b616bc2ddee787fc1a079e57f1e4873323 | |
| parent | 452aa81770d0f2aa05e874122cc15cc73e51235c (diff) | |
| download | rust-51b23386114ba7eba5dcbb5cbb7995575d7c0d8b.tar.gz rust-51b23386114ba7eba5dcbb5cbb7995575d7c0d8b.zip | |
rustc_lint: Reuse the set of registered tools from resolver
| -rw-r--r-- | compiler/rustc_expand/src/base.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/early.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 6 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs | 2 |
10 files changed, 70 insertions, 56 deletions
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 07b5e20b2dd..ce08d5d7f2f 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -8,7 +8,7 @@ use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream}; use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported}; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; @@ -920,6 +920,9 @@ pub trait ResolverExpand { /// we generated proc macros harnesses, so that we can map /// HIR proc macros items back to their harness items. fn declare_proc_macro(&mut self, id: NodeId); + + /// Tools registered with `#![register_tool]` and used by tool attributes and lints. + fn registered_tools(&self) -> &FxHashSet<Ident>; } #[derive(Clone, Default)] diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 93d1976eb1e..6ac73d06868 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -11,7 +11,7 @@ use rustc_data_structures::parallel; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{Applicability, ErrorReported, PResult}; -use rustc_expand::base::ExtCtxt; +use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE}; use rustc_hir::Crate; use rustc_lint::LintStore; @@ -20,7 +20,7 @@ use rustc_metadata::{encode_metadata, EncodedMetadata}; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::query::{ExternProviders, Providers}; -use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; +use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, ResolverOutputs, TyCtxt}; use rustc_mir_build as mir_build; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr}; use rustc_passes::{self, hir_stats, layout_test}; @@ -236,7 +236,7 @@ pub fn register_plugins<'a>( fn pre_expansion_lint( sess: &Session, lint_store: &LintStore, - crate_attrs: &[ast::Attribute], + registered_tools: &RegisteredTools, check_node: &ast::Crate, node_name: &str, ) { @@ -245,7 +245,7 @@ fn pre_expansion_lint( sess, true, lint_store, - crate_attrs, + registered_tools, None, rustc_lint::BuiltinCombinedPreExpansionLintPass::new(), check_node, @@ -265,7 +265,7 @@ pub fn configure_and_expand( resolver: &mut Resolver<'_>, ) -> Result<ast::Crate> { tracing::trace!("configure_and_expand"); - pre_expansion_lint(sess, lint_store, &krate.attrs, &krate, crate_name); + pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name); rustc_builtin_macros::register_builtin_macros(resolver); krate = sess.time("crate_injection", || { @@ -321,10 +321,10 @@ pub fn configure_and_expand( ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string()) }; - let crate_attrs = krate.attrs.clone(); + let registered_tools = resolver.registered_tools().clone(); let extern_mod_loaded = |ident: Ident, attrs, items, span| { let krate = ast::Crate { attrs, items, span, id: DUMMY_NODE_ID, is_placeholder: false }; - pre_expansion_lint(sess, lint_store, &crate_attrs, &krate, ident.name.as_str()); + pre_expansion_lint(sess, lint_store, ®istered_tools, &krate, ident.name.as_str()); (krate.attrs, krate.items) }; let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&extern_mod_loaded)); @@ -499,12 +499,13 @@ pub fn lower_to_hir<'res, 'tcx>( ); sess.time("early_lint_checks", || { + let lint_buffer = Some(std::mem::take(resolver.lint_buffer())); rustc_lint::check_ast_node( sess, false, lint_store, - &krate.attrs, - Some(std::mem::take(resolver.lint_buffer())), + resolver.registered_tools(), + lint_buffer, rustc_lint::BuiltinCombinedEarlyLintPass::new(), &krate, ) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d762ee2acd2..35c0abd73ba 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -16,10 +16,9 @@ use self::TargetLint::*; -use crate::levels::{is_known_lint_tool, LintLevelsBuilder}; +use crate::levels::LintLevelsBuilder; use crate::passes::{EarlyLintPassObject, LateLintPassObject}; -use ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_ast as ast; +use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; use rustc_errors::{struct_span_err, Applicability, SuggestionStyle}; @@ -32,13 +31,14 @@ use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::middle::stability; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; +use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt}; use rustc_serialize::json::Json; use rustc_session::lint::{BuiltinLintDiagnostics, ExternDepSpec}; use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use rustc_session::Session; use rustc_span::lev_distance::find_best_match_for_name; -use rustc_span::{symbol::Symbol, BytePos, MultiSpan, Span, DUMMY_SP}; +use rustc_span::symbol::{sym, Ident, Symbol}; +use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP}; use rustc_target::abi; use tracing::debug; @@ -313,7 +313,7 @@ impl LintStore { sess: &Session, lint_name: &str, level: Level, - crate_attrs: &[ast::Attribute], + registered_tools: &RegisteredTools, ) { let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name); if lint_name_only == crate::WARNINGS.name_lower() && level == Level::ForceWarn { @@ -326,7 +326,7 @@ impl LintStore { ) .emit(); } - let db = match self.check_lint_name(sess, lint_name_only, tool_name, crate_attrs) { + let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) { CheckLintNameResult::Ok(_) => None, CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)), CheckLintNameResult::NoLint(suggestion) => { @@ -397,13 +397,16 @@ impl LintStore { /// printing duplicate warnings. pub fn check_lint_name( &self, - sess: &Session, lint_name: &str, tool_name: Option<Symbol>, - crate_attrs: &[ast::Attribute], + registered_tools: &RegisteredTools, ) -> CheckLintNameResult<'_> { if let Some(tool_name) = tool_name { - if !is_known_lint_tool(tool_name, sess, crate_attrs) { + // FIXME: rustc and rustdoc are considered tools for lints, but not for attributes. + if tool_name != sym::rustc + && tool_name != sym::rustdoc + && !registered_tools.contains(&Ident::with_dummy_span(tool_name)) + { return CheckLintNameResult::NoTool; } } @@ -794,11 +797,16 @@ impl<'a> EarlyContext<'a> { sess: &'a Session, warn_about_weird_lints: bool, lint_store: &'a LintStore, - crate_attrs: &'a [ast::Attribute], + registered_tools: &'a RegisteredTools, buffered: LintBuffer, ) -> EarlyContext<'a> { EarlyContext { - builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, crate_attrs), + builder: LintLevelsBuilder::new( + sess, + warn_about_weird_lints, + lint_store, + registered_tools, + ), buffered, } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 9753bbfe752..6cf67922be7 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -19,6 +19,7 @@ use crate::passes::{EarlyLintPass, EarlyLintPassObject}; use rustc_ast as ast; use rustc_ast::visit as ast_visit; use rustc_ast::AstLike; +use rustc_middle::ty::RegisteredTools; use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass}; use rustc_session::Session; use rustc_span::symbol::Ident; @@ -329,13 +330,19 @@ fn early_lint_node( sess: &Session, warn_about_weird_lints: bool, lint_store: &LintStore, - crate_attrs: &[ast::Attribute], + registered_tools: &RegisteredTools, buffered: LintBuffer, pass: impl EarlyLintPass, check_node: &ast::Crate, ) -> LintBuffer { let mut cx = EarlyContextAndPass { - context: EarlyContext::new(sess, warn_about_weird_lints, lint_store, crate_attrs, buffered), + context: EarlyContext::new( + sess, + warn_about_weird_lints, + lint_store, + registered_tools, + buffered, + ), pass, }; @@ -351,7 +358,7 @@ pub fn check_ast_node( sess: &Session, pre_expansion: bool, lint_store: &LintStore, - crate_attrs: &[ast::Attribute], + registered_tools: &RegisteredTools, lint_buffer: Option<LintBuffer>, builtin_lints: impl EarlyLintPass, check_node: &ast::Crate, @@ -366,7 +373,7 @@ pub fn check_ast_node( sess, pre_expansion, lint_store, - crate_attrs, + registered_tools, buffered, builtin_lints, check_node, @@ -377,7 +384,7 @@ pub fn check_ast_node( sess, false, lint_store, - crate_attrs, + registered_tools, buffered, EarlyLintPassObjects { lints: &mut passes[..] }, check_node, @@ -391,7 +398,7 @@ pub fn check_ast_node( sess, pre_expansion && i == 0, lint_store, - crate_attrs, + registered_tools, buffered, EarlyLintPassObjects { lints: slice::from_mut(pass) }, check_node, diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 8e6ae2c60fd..080a38bae66 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -14,7 +14,7 @@ use rustc_middle::lint::{ COMMAND_LINE, }; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{RegisteredTools, TyCtxt}; use rustc_session::lint::{ builtin::{self, FORBIDDEN_LINT_GROUPS}, Level, Lint, LintId, @@ -27,8 +27,8 @@ use tracing::debug; fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { let store = unerased_lint_store(tcx); - let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); - let levels = LintLevelsBuilder::new(tcx.sess, false, &store, crate_attrs); + let levels = + LintLevelsBuilder::new(tcx.sess, false, &store, &tcx.resolutions(()).registered_tools); let mut builder = LintLevelMapBuilder { levels, tcx }; let krate = tcx.hir().krate(); @@ -49,7 +49,7 @@ pub struct LintLevelsBuilder<'s> { cur: LintStackIndex, warn_about_weird_lints: bool, store: &'s LintStore, - crate_attrs: &'s [ast::Attribute], + registered_tools: &'s RegisteredTools, } pub struct BuilderPush { @@ -62,7 +62,7 @@ impl<'s> LintLevelsBuilder<'s> { sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore, - crate_attrs: &'s [ast::Attribute], + registered_tools: &'s RegisteredTools, ) -> Self { let mut builder = LintLevelsBuilder { sess, @@ -71,7 +71,7 @@ impl<'s> LintLevelsBuilder<'s> { id_to_set: Default::default(), warn_about_weird_lints, store, - crate_attrs, + registered_tools, }; builder.process_command_line(sess, store); assert_eq!(builder.sets.list.len(), 1); @@ -91,7 +91,7 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); for &(ref lint_name, level) in &sess.opts.lint_opts { - store.check_lint_name_cmdline(sess, &lint_name, level, self.crate_attrs); + store.check_lint_name_cmdline(sess, &lint_name, level, self.registered_tools); let orig_level = level; let lint_flag_val = Symbol::intern(lint_name); @@ -314,7 +314,7 @@ impl<'s> LintLevelsBuilder<'s> { let tool_name = tool_ident.map(|ident| ident.name); let name = pprust::path_to_string(&meta_item.path); let lint_result = - self.store.check_lint_name(sess, &name, tool_name, self.crate_attrs); + self.store.check_lint_name(&name, tool_name, self.registered_tools); match &lint_result { CheckLintNameResult::Ok(ids) => { let src = LintLevelSource::Node( @@ -463,7 +463,7 @@ impl<'s> LintLevelsBuilder<'s> { // Ignore any errors or warnings that happen because the new name is inaccurate // NOTE: `new_name` already includes the tool name, so we don't have to add it again. if let CheckLintNameResult::Ok(ids) = - self.store.check_lint_name(sess, &new_name, None, self.crate_attrs) + self.store.check_lint_name(&new_name, None, self.registered_tools) { let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason); for &id in ids { @@ -566,20 +566,6 @@ impl<'s> LintLevelsBuilder<'s> { } } -pub fn is_known_lint_tool(m_item: Symbol, sess: &Session, attrs: &[ast::Attribute]) -> bool { - if [sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item) { - return true; - } - // Look for registered tools - // NOTE: does no error handling; error handling is done by rustc_resolve. - sess.filter_by_name(attrs, sym::register_tool) - .filter_map(|attr| attr.meta_item_list()) - .flatten() - .filter_map(|nested_meta| nested_meta.ident()) - .map(|ident| ident.name) - .any(|name| name == m_item) -} - struct LintLevelMapBuilder<'tcx> { levels: LintLevelsBuilder<'tcx>, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c36a233df91..a87f2b2768d 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -96,7 +96,7 @@ use unused::*; pub use builtin::SoftLints; pub use context::{CheckLintNameResult, FindLintError, LintStore}; pub use context::{EarlyContext, LateContext, LintContext}; -pub use early::check_ast_node; +pub use early::{check_ast_node, EarlyCheckNode}; pub use late::check_crate; pub use passes::{EarlyLintPass, LateLintPass}; pub use rustc_session::lint::Level::{self, *}; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8ed1533436e..64c00c353ca 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -119,6 +119,8 @@ mod sty; // Data types +pub type RegisteredTools = FxHashSet<Ident>; + #[derive(Debug)] pub struct ResolverOutputs { pub definitions: rustc_hir::definitions::Definitions, @@ -141,6 +143,7 @@ pub struct ResolverOutputs { /// Mapping from ident span to path span for paths that don't exist as written, but that /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`. pub confused_type_with_std_module: FxHashMap<Span, Span>, + pub registered_tools: RegisteredTools, } #[derive(Clone, Copy, Debug)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f5b2ba8fd72..f6625ac021b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -53,7 +53,7 @@ use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::span_bug; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, DefIdTree, MainDefinition, ResolverOutputs}; +use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools, ResolverOutputs}; use rustc_query_system::ich::StableHashingContext; use rustc_session::cstore::{CrateStore, MetadataLoaderDyn}; use rustc_session::lint; @@ -989,7 +989,7 @@ pub struct Resolver<'a> { macro_names: FxHashSet<Ident>, builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, registered_attrs: FxHashSet<Ident>, - registered_tools: FxHashSet<Ident>, + registered_tools: RegisteredTools, macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>, all_macros: FxHashMap<Symbol, Res>, macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>, @@ -1487,6 +1487,7 @@ impl<'a> Resolver<'a> { trait_impls: self.trait_impls, proc_macros, confused_type_with_std_module, + registered_tools: self.registered_tools, } } @@ -1511,6 +1512,7 @@ impl<'a> Resolver<'a> { trait_impls: self.trait_impls.clone(), proc_macros, confused_type_with_std_module: self.confused_type_with_std_module.clone(), + registered_tools: self.registered_tools.clone(), } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 52685ec697c..82807e2d0a2 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -23,7 +23,7 @@ use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{CrateNum, LocalDefId}; use rustc_hir::PrimTy; use rustc_middle::middle::stability; -use rustc_middle::ty; +use rustc_middle::ty::{self, RegisteredTools}; use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK}; use rustc_session::lint::builtin::{SOFT_UNSTABLE, UNUSED_MACROS}; use rustc_session::lint::BuiltinLintDiagnostics; @@ -447,6 +447,10 @@ impl<'a> ResolverExpand for Resolver<'a> { fn declare_proc_macro(&mut self, id: NodeId) { self.proc_macros.push(id) } + + fn registered_tools(&self) -> &RegisteredTools { + &self.registered_tools + } } impl<'a> Resolver<'a> { diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs index 5ee3146eaab..512c39389c1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -580,7 +580,7 @@ fn get_lint_group_and_level_or_lint( ) -> Option<(String, &'static str)> { let result = cx .lint_store - .check_lint_name(cx.sess(), lint_name, Some(sym::clippy), &[]); + .check_lint_name(lint_name, Some(sym::clippy), &[]); if let CheckLintNameResult::Tool(Ok(lint_lst)) = result { if let Some(group) = get_lint_group(cx, lint_lst[0]) { if EXCLUDED_LINT_GROUPS.contains(&group.as_str()) { |
