diff --git a/Cargo.lock b/Cargo.lock index 2522eb85a7c..5b9db979750 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3630,6 +3630,7 @@ dependencies = [ "rustc_plugin_impl", "rustc_privacy", "rustc_resolve", + "rustc_session", "rustc_span", "rustc_target", "rustc_traits", diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index de4992d8e70..548b3e27ac6 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -9,10 +9,9 @@ use crate::middle::stability; use crate::session::Session; use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_session::declare_lint; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::edition::Edition; use rustc_span::source_map::Span; -use rustc_span::symbol::Symbol; -use syntax::ast; use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; declare_lint! { @@ -516,22 +515,6 @@ declare_lint_pass! { impl LateLintPass<'_, '_> for HardwiredLints {} -// This could be a closure, but then implementing derive trait -// becomes hacky (and it gets allocated). -#[derive(PartialEq)] -pub enum BuiltinLintDiagnostics { - Normal, - BareTraitObject(Span, /* is_global */ bool), - AbsPathWithModule(Span), - ProcMacroDeriveResolutionFallback(Span), - MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), - ElidedLifetimesInPaths(usize, Span, bool, Span, String), - UnknownCrateTypes(Span, String, String), - UnusedImports(String, Vec<(Span, String)>), - RedundantImport(Vec<(Span, bool)>, ast::Ident), - DeprecatedMacro(Option, Span), -} - pub fn add_elided_lifetime_in_path_suggestion( sess: &Session, db: &mut DiagnosticBuilder<'_>, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 90575f71ff5..759ab3749d2 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -17,10 +17,8 @@ use self::TargetLint::*; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; -use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::lint::{EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use crate::middle::privacy::AccessLevels; use crate::session::Session; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; @@ -31,6 +29,8 @@ use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, DefId}; +use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId}; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -64,17 +64,6 @@ pub struct LintStore { lint_groups: FxHashMap<&'static str, LintGroup>, } -/// Lints that are buffered up early on in the `Session` before the -/// `LintLevels` is calculated -#[derive(PartialEq)] -pub struct BufferedEarlyLint { - pub lint_id: LintId, - pub ast_id: ast::NodeId, - pub span: MultiSpan, - pub msg: String, - pub diagnostic: BuiltinLintDiagnostics, -} - /// The target of the `by_name` map, which accounts for renaming/deprecation. enum TargetLint { /// A direct lint target diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index a8c1f9a664f..e59e8ce1c0a 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -21,12 +21,10 @@ pub use self::Level::*; pub use self::LintSource::*; -use crate::lint::builtin::BuiltinLintDiagnostics; use crate::ty::TyCtxt; use rustc_data_structures::sync; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; -use rustc_session::node_id::NodeMap; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; @@ -35,10 +33,10 @@ use rustc_span::Span; use syntax::ast; pub use crate::lint::context::{ - BufferedEarlyLint, CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore, + CheckLintNameResult, EarlyContext, LateContext, LintContext, LintStore, }; -pub use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintId}; +pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Level, Lint, LintId}; /// Declares a static `LintArray` and return it as an expression. #[macro_export] @@ -373,59 +371,6 @@ mod levels; pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder}; -#[derive(Default)] -pub struct LintBuffer { - pub map: NodeMap>, -} - -impl LintBuffer { - pub fn add_lint( - &mut self, - lint: &'static Lint, - id: ast::NodeId, - sp: MultiSpan, - msg: &str, - diagnostic: BuiltinLintDiagnostics, - ) { - let early_lint = BufferedEarlyLint { - lint_id: LintId::of(lint), - ast_id: id, - span: sp, - msg: msg.to_string(), - diagnostic, - }; - let arr = self.map.entry(id).or_default(); - if !arr.contains(&early_lint) { - arr.push(early_lint); - } - } - - pub fn take(&mut self, id: ast::NodeId) -> Vec { - self.map.remove(&id).unwrap_or_default() - } - - pub fn buffer_lint>( - &mut self, - lint: &'static Lint, - id: ast::NodeId, - sp: S, - msg: &str, - ) { - self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal) - } - - pub fn buffer_lint_with_diagnostic>( - &mut self, - lint: &'static Lint, - id: ast::NodeId, - sp: S, - msg: &str, - diagnostic: BuiltinLintDiagnostics, - ) { - self.add_lint(lint, id, sp.into(), msg, diagnostic) - } -} - pub fn struct_lint_level<'a>( sess: &'a Session, lint: &'static Lint, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 4874d65b2b0..17e84c24881 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,7 +3,6 @@ pub use self::StabilityLevel::*; -use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::{self, in_derive_expansion, Lint}; use crate::session::{DiagnosticMessageId, Session}; use crate::ty::{self, TyCtxt}; @@ -14,6 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_hir::{self, HirId}; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{MultiSpan, Span}; use syntax::ast::CRATE_NODE_ID; @@ -195,7 +195,7 @@ pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String } pub fn early_report_deprecation( - lint_buffer: &'a mut lint::LintBuffer, + lint_buffer: &'a mut LintBuffer, message: &str, suggestion: Option, lint: &'static Lint, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 527aa6796bc..77cb9ee35ff 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -37,7 +37,6 @@ use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::Map; -use rustc::lint; use rustc::lint::builtin; use rustc::{bug, span_bug}; use rustc_data_structures::captures::Captures; @@ -52,6 +51,7 @@ use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_index::vec::IndexVec; use rustc_session::config::nightly_options; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_session::node_id::NodeMap; use rustc_session::Session; use rustc_span::hygiene::ExpnId; @@ -198,7 +198,7 @@ pub trait Resolver { ns: Namespace, ) -> (ast::Path, Res); - fn lint_buffer(&mut self) -> &mut lint::LintBuffer; + fn lint_buffer(&mut self) -> &mut LintBuffer; fn next_node_id(&mut self) -> NodeId; } @@ -2617,7 +2617,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { id, span, "trait objects without an explicit `dyn` are deprecated", - builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global), + BuiltinLintDiagnostics::BareTraitObject(span, is_global), ) } } diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs index 9b504704ae0..b50295ebaae 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/src/librustc_ast_lowering/path.rs @@ -1,7 +1,7 @@ use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode}; use super::{GenericArgsCtor, ParenthesizedGenericArgs}; -use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS}; +use rustc::lint::builtin::ELIDED_LIFETIMES_IN_PATHS; use rustc::span_bug; use rustc_error_codes::*; use rustc_errors::{struct_span_err, Applicability}; @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::def_id::DefId; use rustc_hir::GenericArg; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::Span; use syntax::ast::{self, *}; @@ -304,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { E0726, "implicit elided lifetime not allowed here" ); - crate::lint::builtin::add_elided_lifetime_in_path_suggestion( + rustc::lint::builtin::add_elided_lifetime_in_path_suggestion( &self.sess, &mut err, expected_lifetimes, @@ -321,7 +322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { CRATE_NODE_ID, path_span, "hidden lifetime parameters in types are deprecated", - builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths( + BuiltinLintDiagnostics::ElidedLifetimesInPaths( expected_lifetimes, path_span, incl_angl_brckt, diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index be60b75bc47..9bd19fb38e7 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -17,6 +17,7 @@ syntax = { path = "../libsyntax" } rustc_builtin_macros = { path = "../librustc_builtin_macros" } rustc_expand = { path = "../librustc_expand" } rustc_parse = { path = "../librustc_parse" } +rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc = { path = "../librustc" } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a7e174f0455..e8210bfacd3 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -37,7 +37,6 @@ use rustc_span::symbol::Symbol; use rustc_span::FileName; use rustc_traits; use rustc_typeck as typeck; -use syntax::early_buffered_lints::BufferedEarlyLint; use syntax::mut_visit::MutVisitor; use syntax::util::node_count::NodeCounter; use syntax::{self, ast, visit}; @@ -411,8 +410,8 @@ fn configure_and_expand_inner<'a>( // Add all buffered lints from the `ParseSess` to the `Session`. sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { info!("{} parse sess buffered_lints", buffered_lints.len()); - for BufferedEarlyLint { id, span, msg, lint_id } in buffered_lints.drain(..) { - resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg); + for early_lint in buffered_lints.drain(..) { + resolver.lint_buffer().add_early_lint(early_lint); } }); diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 8e381a27b41..2fafd3af7a5 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -1,8 +1,5 @@ use log::info; use rustc::lint; -use rustc::session::config::{ErrorOutputType, Input, OutputFilenames}; -use rustc::session::CrateDisambiguator; -use rustc::session::{self, config, early_error, filesearch, DiagnosticOutput, Session}; use rustc::ty; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::fingerprint::Fingerprint; @@ -14,6 +11,11 @@ use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::registry::Registry; use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_resolve::{self, Resolver}; +use rustc_session as session; +use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; +use rustc_session::CrateDisambiguator; +use rustc_session::{config, early_error, filesearch, DiagnosticOutput, Session}; use rustc_span::edition::Edition; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap}; use rustc_span::symbol::{sym, Symbol}; @@ -420,7 +422,7 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat CrateDisambiguator::from(hasher.finish::()) } -pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut lint::LintBuffer) { +pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut LintBuffer) { // Unconditionally collect crate types from attributes to make them used for a in attrs.iter() { if a.check_name(sym::crate_type) { @@ -442,7 +444,7 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut ast::CRATE_NODE_ID, span, "invalid `crate_type` value", - lint::builtin::BuiltinLintDiagnostics::UnknownCrateTypes( + BuiltinLintDiagnostics::UnknownCrateTypes( span, "did you mean".to_string(), format!("\"{}\"", candidate), diff --git a/src/librustc_lint/early.rs b/src/librustc_lint/early.rs index 67c0c98b203..9a901719851 100644 --- a/src/librustc_lint/early.rs +++ b/src/librustc_lint/early.rs @@ -16,15 +16,15 @@ use rustc::lint::{EarlyContext, LintStore}; use rustc::lint::{EarlyLintPass, EarlyLintPassObject}; -use rustc::lint::{LintBuffer, LintContext, LintPass}; -use rustc::session::Session; - +use rustc::lint::{LintContext, LintPass}; +use rustc_session::lint::LintBuffer; +use rustc_session::Session; use rustc_span::Span; -use std::slice; use syntax::ast; use syntax::visit as ast_visit; use log::debug; +use std::slice; macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 9cd7d9a89fd..bc8d8a414c4 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -6,10 +6,11 @@ // This pass is supposed to perform only simple checks not requiring name resolution // or type checking or some other kind of complex analysis. -use rustc::lint; +use rustc::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_parse::validate_attr; +use rustc_session::lint::LintBuffer; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; @@ -65,7 +66,7 @@ struct AstValidator<'a> { /// certain positions. is_assoc_ty_bound_banned: bool, - lint_buffer: &'a mut lint::LintBuffer, + lint_buffer: &'a mut LintBuffer, } impl<'a> AstValidator<'a> { @@ -992,7 +993,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { Self::check_decl_no_pat(&sig.decl, |span, mut_ident| { if mut_ident { self.lint_buffer.buffer_lint( - lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY, + PATTERNS_IN_FNS_WITHOUT_BODY, ti.id, span, "patterns aren't allowed in methods without bodies", @@ -1021,7 +1022,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } -pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffer) -> bool { +pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool { let mut validator = AstValidator { session, has_proc_macro_decls: false, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index d6f365fce79..4a6df92d822 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -29,6 +29,7 @@ use crate::Resolver; use rustc::{lint, ty}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc_session::node_id::NodeMap; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use syntax::ast; @@ -317,7 +318,7 @@ impl Resolver<'_> { unused.use_tree_id, ms, &msg, - lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), + BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), ); } } diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 813e6ac9691..ecd51b1ee05 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -12,9 +12,9 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding}; use rustc::hir::exports::Export; -use rustc::lint::builtin::BuiltinLintDiagnostics; use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS}; -use rustc::session::DiagnosticMessageId; +use rustc_session::DiagnosticMessageId; +use rustc_session::lint::BuiltinLintDiagnostics; use rustc::ty; use rustc::{bug, span_bug}; use rustc_data_structures::fx::FxHashSet; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e6be9f6d328..8e4630cf7d6 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -24,7 +24,6 @@ use rustc::hir::exports::ExportMap; use rustc::hir::map::{DefKey, Definitions}; use rustc::lint; use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; -use rustc::session::Session; use rustc::span_bug; use rustc::ty::query::Providers; use rustc::ty::{self, DefIdTree, ResolverOutputs}; @@ -39,7 +38,9 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE} use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; use rustc_hir::{GlobMap, TraitMap}; use rustc_metadata::creader::{CStore, CrateLoader}; +use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer}; use rustc_session::node_id::{NodeMap, NodeSet}; +use rustc_session::Session; use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; @@ -960,7 +961,7 @@ pub struct Resolver<'a> { /// when visiting the correspondent variants. variant_vis: DefIdMap, - lint_buffer: lint::LintBuffer, + lint_buffer: LintBuffer, next_node_id: NodeId, } @@ -1082,7 +1083,7 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> { &mut self.definitions } - fn lint_buffer(&mut self) -> &mut lint::LintBuffer { + fn lint_buffer(&mut self) -> &mut LintBuffer { &mut self.lint_buffer } @@ -1241,7 +1242,7 @@ impl<'a> Resolver<'a> { .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat)) .collect(), variant_vis: Default::default(), - lint_buffer: lint::LintBuffer::default(), + lint_buffer: LintBuffer::default(), next_node_id: NodeId::from_u32(1), } } @@ -1256,7 +1257,7 @@ impl<'a> Resolver<'a> { self.next_node_id } - pub fn lint_buffer(&mut self) -> &mut lint::LintBuffer { + pub fn lint_buffer(&mut self) -> &mut LintBuffer { &mut self.lint_buffer } @@ -1713,10 +1714,10 @@ impl<'a> Resolver<'a> { if let Some(node_id) = poisoned { self.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, - node_id, ident.span, + node_id, + ident.span, &format!("cannot find {} `{}` in this scope", ns.descr(), ident), - lint::builtin::BuiltinLintDiagnostics:: - ProcMacroDeriveResolutionFallback(ident.span), + BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(ident.span), ); } return Some(LexicalScopeBinding::Item(binding)); @@ -2267,7 +2268,7 @@ impl<'a> Resolver<'a> { } } - let diag = lint::builtin::BuiltinLintDiagnostics::AbsPathWithModule(diag_span); + let diag = BuiltinLintDiagnostics::AbsPathWithModule(diag_span); self.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, diag_id, @@ -2562,9 +2563,10 @@ impl<'a> Resolver<'a> { cannot be referred to by absolute paths"; self.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, - CRATE_NODE_ID, span_use, msg, - lint::builtin::BuiltinLintDiagnostics:: - MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def), + CRATE_NODE_ID, + span_use, + msg, + BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def), ); } diff --git a/src/librustc_session/lint.rs b/src/librustc_session/lint.rs index 0cce7e848fd..24e42928f63 100644 --- a/src/librustc_session/lint.rs +++ b/src/librustc_session/lint.rs @@ -1,8 +1,8 @@ pub use self::Level::*; -use crate::node_id::NodeId; +use crate::node_id::{NodeId, NodeMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_span::edition::Edition; -use rustc_span::{sym, MultiSpan, Symbol}; +use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol}; /// Setting for how to handle a lint. #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] @@ -174,7 +174,25 @@ impl ToStableHashKey for LintId { } } -/// Stores buffered lint info which can later be passed to `librustc`. +// This could be a closure, but then implementing derive trait +// becomes hacky (and it gets allocated). +#[derive(PartialEq)] +pub enum BuiltinLintDiagnostics { + Normal, + BareTraitObject(Span, /* is_global */ bool), + AbsPathWithModule(Span), + ProcMacroDeriveResolutionFallback(Span), + MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), + ElidedLifetimesInPaths(usize, Span, bool, Span, String), + UnknownCrateTypes(Span, String, String), + UnusedImports(String, Vec<(Span, String)>), + RedundantImport(Vec<(Span, bool)>, Ident), + DeprecatedMacro(Option, Span), +} + +/// Lints that are buffered up early on in the `Session` before the +/// `LintLevels` is calculated. These are later passed to `librustc`. +#[derive(PartialEq)] pub struct BufferedEarlyLint { /// The span of code that we are linting on. pub span: MultiSpan, @@ -183,10 +201,65 @@ pub struct BufferedEarlyLint { pub msg: String, /// The `NodeId` of the AST node that generated the lint. - pub id: NodeId, + pub node_id: NodeId, /// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`. - pub lint_id: &'static Lint, + pub lint_id: LintId, + + /// Customization of the `DiagnosticBuilder<'_>` for the lint. + pub diagnostic: BuiltinLintDiagnostics, +} + +#[derive(Default)] +pub struct LintBuffer { + pub map: NodeMap>, +} + +impl LintBuffer { + pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) { + let arr = self.map.entry(early_lint.node_id).or_default(); + if !arr.contains(&early_lint) { + arr.push(early_lint); + } + } + + pub fn add_lint( + &mut self, + lint: &'static Lint, + node_id: NodeId, + span: MultiSpan, + msg: &str, + diagnostic: BuiltinLintDiagnostics, + ) { + let lint_id = LintId::of(lint); + let msg = msg.to_string(); + self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic }); + } + + pub fn take(&mut self, id: NodeId) -> Vec { + self.map.remove(&id).unwrap_or_default() + } + + pub fn buffer_lint( + &mut self, + lint: &'static Lint, + id: NodeId, + sp: impl Into, + msg: &str, + ) { + self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal) + } + + pub fn buffer_lint_with_diagnostic( + &mut self, + lint: &'static Lint, + id: NodeId, + sp: impl Into, + msg: &str, + diagnostic: BuiltinLintDiagnostics, + ) { + self.add_lint(lint, id, sp.into(), msg, diagnostic) + } } /// Declares a static item of type `&'static Lint`. diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index b0c6aefc00c..0e342939ff1 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -1,7 +1,7 @@ //! Contains `ParseSess` which holds state living beyond what one `Parser` might. //! It also serves as an input to the parser itself. -use crate::lint::BufferedEarlyLint; +use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId}; use crate::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -210,17 +210,18 @@ impl ParseSess { pub fn buffer_lint( &self, - lint_id: &'static crate::lint::Lint, + lint: &'static Lint, span: impl Into, - id: NodeId, + node_id: NodeId, msg: &str, ) { self.buffered_lints.with_lock(|buffered_lints| { buffered_lints.push(BufferedEarlyLint { span: span.into(), - id, + node_id, msg: msg.into(), - lint_id, + lint_id: LintId::of(lint), + diagnostic: BuiltinLintDiagnostics::Normal, }); }); }