1
Fork 0

buffered lint infra -> rustc_session

This commit is contained in:
Mazdak Farrokhzad 2020-01-05 09:40:16 +01:00
parent 82eeb8573a
commit 7dbccf5b55
17 changed files with 136 additions and 137 deletions

View file

@ -3630,6 +3630,7 @@ dependencies = [
"rustc_plugin_impl", "rustc_plugin_impl",
"rustc_privacy", "rustc_privacy",
"rustc_resolve", "rustc_resolve",
"rustc_session",
"rustc_span", "rustc_span",
"rustc_target", "rustc_target",
"rustc_traits", "rustc_traits",

View file

@ -9,10 +9,9 @@ use crate::middle::stability;
use crate::session::Session; use crate::session::Session;
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
use rustc_session::declare_lint; use rustc_session::declare_lint;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::source_map::Span; 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}; use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
declare_lint! { declare_lint! {
@ -516,22 +515,6 @@ declare_lint_pass! {
impl LateLintPass<'_, '_> for HardwiredLints {} 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<Symbol>, Span),
}
pub fn add_elided_lifetime_in_path_suggestion( pub fn add_elided_lifetime_in_path_suggestion(
sess: &Session, sess: &Session,
db: &mut DiagnosticBuilder<'_>, db: &mut DiagnosticBuilder<'_>,

View file

@ -17,10 +17,8 @@
use self::TargetLint::*; use self::TargetLint::*;
use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
use crate::lint::{EarlyLintPassObject, LateLintPassObject}; use crate::lint::{EarlyLintPassObject, LateLintPassObject};
use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use crate::middle::privacy::AccessLevels; use crate::middle::privacy::AccessLevels;
use crate::session::Session; use crate::session::Session;
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
@ -31,6 +29,8 @@ use rustc_error_codes::*;
use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId}; 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 rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
use syntax::ast; use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name; use syntax::util::lev_distance::find_best_match_for_name;
@ -64,17 +64,6 @@ pub struct LintStore {
lint_groups: FxHashMap<&'static str, LintGroup>, 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. /// The target of the `by_name` map, which accounts for renaming/deprecation.
enum TargetLint { enum TargetLint {
/// A direct lint target /// A direct lint target

View file

@ -21,12 +21,10 @@
pub use self::Level::*; pub use self::Level::*;
pub use self::LintSource::*; pub use self::LintSource::*;
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::ty::TyCtxt; use crate::ty::TyCtxt;
use rustc_data_structures::sync; use rustc_data_structures::sync;
use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_session::node_id::NodeMap;
use rustc_session::{DiagnosticMessageId, Session}; use rustc_session::{DiagnosticMessageId, Session};
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
@ -35,10 +33,10 @@ use rustc_span::Span;
use syntax::ast; use syntax::ast;
pub use crate::lint::context::{ 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. /// Declares a static `LintArray` and return it as an expression.
#[macro_export] #[macro_export]
@ -373,59 +371,6 @@ mod levels;
pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder}; pub use self::levels::{LintLevelMap, LintLevelSets, LintLevelsBuilder};
#[derive(Default)]
pub struct LintBuffer {
pub map: NodeMap<Vec<BufferedEarlyLint>>,
}
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<BufferedEarlyLint> {
self.map.remove(&id).unwrap_or_default()
}
pub fn buffer_lint<S: Into<MultiSpan>>(
&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<S: Into<MultiSpan>>(
&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>( pub fn struct_lint_level<'a>(
sess: &'a Session, sess: &'a Session,
lint: &'static Lint, lint: &'static Lint,

View file

@ -3,7 +3,6 @@
pub use self::StabilityLevel::*; pub use self::StabilityLevel::*;
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::lint::{self, in_derive_expansion, Lint}; use crate::lint::{self, in_derive_expansion, Lint};
use crate::session::{DiagnosticMessageId, Session}; use crate::session::{DiagnosticMessageId, Session};
use crate::ty::{self, TyCtxt}; use crate::ty::{self, TyCtxt};
@ -14,6 +13,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
use rustc_hir::{self, HirId}; use rustc_hir::{self, HirId};
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_span::{MultiSpan, Span}; use rustc_span::{MultiSpan, Span};
use syntax::ast::CRATE_NODE_ID; 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( pub fn early_report_deprecation(
lint_buffer: &'a mut lint::LintBuffer, lint_buffer: &'a mut LintBuffer,
message: &str, message: &str,
suggestion: Option<Symbol>, suggestion: Option<Symbol>,
lint: &'static Lint, lint: &'static Lint,

View file

@ -37,7 +37,6 @@ use rustc::arena::Arena;
use rustc::dep_graph::DepGraph; use rustc::dep_graph::DepGraph;
use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions}; use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions};
use rustc::hir::map::Map; use rustc::hir::map::Map;
use rustc::lint;
use rustc::lint::builtin; use rustc::lint::builtin;
use rustc::{bug, span_bug}; use rustc::{bug, span_bug};
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
@ -52,6 +51,7 @@ use rustc_hir::intravisit;
use rustc_hir::{ConstArg, GenericArg, ParamName}; use rustc_hir::{ConstArg, GenericArg, ParamName};
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_session::config::nightly_options; use rustc_session::config::nightly_options;
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
use rustc_session::node_id::NodeMap; use rustc_session::node_id::NodeMap;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::hygiene::ExpnId; use rustc_span::hygiene::ExpnId;
@ -198,7 +198,7 @@ pub trait Resolver {
ns: Namespace, ns: Namespace,
) -> (ast::Path, Res<NodeId>); ) -> (ast::Path, Res<NodeId>);
fn lint_buffer(&mut self) -> &mut lint::LintBuffer; fn lint_buffer(&mut self) -> &mut LintBuffer;
fn next_node_id(&mut self) -> NodeId; fn next_node_id(&mut self) -> NodeId;
} }
@ -2617,7 +2617,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
id, id,
span, span,
"trait objects without an explicit `dyn` are deprecated", "trait objects without an explicit `dyn` are deprecated",
builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global), BuiltinLintDiagnostics::BareTraitObject(span, is_global),
) )
} }
} }

View file

@ -1,7 +1,7 @@
use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode}; use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
use super::{GenericArgsCtor, ParenthesizedGenericArgs}; 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::span_bug;
use rustc_error_codes::*; use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability}; 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::{DefKind, PartialRes, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::GenericArg; use rustc_hir::GenericArg;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_span::Span; use rustc_span::Span;
use syntax::ast::{self, *}; use syntax::ast::{self, *};
@ -304,7 +305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
E0726, E0726,
"implicit elided lifetime not allowed here" "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, &self.sess,
&mut err, &mut err,
expected_lifetimes, expected_lifetimes,
@ -321,7 +322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
CRATE_NODE_ID, CRATE_NODE_ID,
path_span, path_span,
"hidden lifetime parameters in types are deprecated", "hidden lifetime parameters in types are deprecated",
builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths( BuiltinLintDiagnostics::ElidedLifetimesInPaths(
expected_lifetimes, expected_lifetimes,
path_span, path_span,
incl_angl_brckt, incl_angl_brckt,

View file

@ -17,6 +17,7 @@ syntax = { path = "../libsyntax" }
rustc_builtin_macros = { path = "../librustc_builtin_macros" } rustc_builtin_macros = { path = "../librustc_builtin_macros" }
rustc_expand = { path = "../librustc_expand" } rustc_expand = { path = "../librustc_expand" }
rustc_parse = { path = "../librustc_parse" } rustc_parse = { path = "../librustc_parse" }
rustc_session = { path = "../librustc_session" }
rustc_span = { path = "../librustc_span" } rustc_span = { path = "../librustc_span" }
rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc = { path = "../librustc" } rustc = { path = "../librustc" }

View file

@ -37,7 +37,6 @@ use rustc_span::symbol::Symbol;
use rustc_span::FileName; use rustc_span::FileName;
use rustc_traits; use rustc_traits;
use rustc_typeck as typeck; use rustc_typeck as typeck;
use syntax::early_buffered_lints::BufferedEarlyLint;
use syntax::mut_visit::MutVisitor; use syntax::mut_visit::MutVisitor;
use syntax::util::node_count::NodeCounter; use syntax::util::node_count::NodeCounter;
use syntax::{self, ast, visit}; 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`. // Add all buffered lints from the `ParseSess` to the `Session`.
sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { sess.parse_sess.buffered_lints.with_lock(|buffered_lints| {
info!("{} parse sess buffered_lints", buffered_lints.len()); info!("{} parse sess buffered_lints", buffered_lints.len());
for BufferedEarlyLint { id, span, msg, lint_id } in buffered_lints.drain(..) { for early_lint in buffered_lints.drain(..) {
resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg); resolver.lint_buffer().add_early_lint(early_lint);
} }
}); });

View file

@ -1,8 +1,5 @@
use log::info; use log::info;
use rustc::lint; 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::ty;
use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::codegen_backend::CodegenBackend;
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
@ -14,6 +11,11 @@ use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::registry::Registry; use rustc_errors::registry::Registry;
use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_metadata::dynamic_lib::DynamicLibrary;
use rustc_resolve::{self, Resolver}; 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::edition::Edition;
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap}; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
@ -420,7 +422,7 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat
CrateDisambiguator::from(hasher.finish::<Fingerprint>()) CrateDisambiguator::from(hasher.finish::<Fingerprint>())
} }
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 // Unconditionally collect crate types from attributes to make them used
for a in attrs.iter() { for a in attrs.iter() {
if a.check_name(sym::crate_type) { 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, ast::CRATE_NODE_ID,
span, span,
"invalid `crate_type` value", "invalid `crate_type` value",
lint::builtin::BuiltinLintDiagnostics::UnknownCrateTypes( BuiltinLintDiagnostics::UnknownCrateTypes(
span, span,
"did you mean".to_string(), "did you mean".to_string(),
format!("\"{}\"", candidate), format!("\"{}\"", candidate),

View file

@ -16,15 +16,15 @@
use rustc::lint::{EarlyContext, LintStore}; use rustc::lint::{EarlyContext, LintStore};
use rustc::lint::{EarlyLintPass, EarlyLintPassObject}; use rustc::lint::{EarlyLintPass, EarlyLintPassObject};
use rustc::lint::{LintBuffer, LintContext, LintPass}; use rustc::lint::{LintContext, LintPass};
use rustc::session::Session; use rustc_session::lint::LintBuffer;
use rustc_session::Session;
use rustc_span::Span; use rustc_span::Span;
use std::slice;
use syntax::ast; use syntax::ast;
use syntax::visit as ast_visit; use syntax::visit as ast_visit;
use log::debug; use log::debug;
use std::slice;
macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({ macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
$cx.pass.$f(&$cx.context, $($args),*); $cx.pass.$f(&$cx.context, $($args),*);

View file

@ -6,10 +6,11 @@
// This pass is supposed to perform only simple checks not requiring name resolution // This pass is supposed to perform only simple checks not requiring name resolution
// or type checking or some other kind of complex analysis. // 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_data_structures::fx::FxHashMap;
use rustc_errors::{struct_span_err, Applicability, FatalError}; use rustc_errors::{struct_span_err, Applicability, FatalError};
use rustc_parse::validate_attr; use rustc_parse::validate_attr;
use rustc_session::lint::LintBuffer;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::{kw, sym};
@ -65,7 +66,7 @@ struct AstValidator<'a> {
/// certain positions. /// certain positions.
is_assoc_ty_bound_banned: bool, is_assoc_ty_bound_banned: bool,
lint_buffer: &'a mut lint::LintBuffer, lint_buffer: &'a mut LintBuffer,
} }
impl<'a> AstValidator<'a> { 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| { Self::check_decl_no_pat(&sig.decl, |span, mut_ident| {
if mut_ident { if mut_ident {
self.lint_buffer.buffer_lint( self.lint_buffer.buffer_lint(
lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY, PATTERNS_IN_FNS_WITHOUT_BODY,
ti.id, ti.id,
span, span,
"patterns aren't allowed in methods without bodies", "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 { let mut validator = AstValidator {
session, session,
has_proc_macro_decls: false, has_proc_macro_decls: false,

View file

@ -29,6 +29,7 @@ use crate::Resolver;
use rustc::{lint, ty}; use rustc::{lint, ty};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::pluralize; use rustc_errors::pluralize;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::node_id::NodeMap; use rustc_session::node_id::NodeMap;
use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_span::{MultiSpan, Span, DUMMY_SP};
use syntax::ast; use syntax::ast;
@ -317,7 +318,7 @@ impl Resolver<'_> {
unused.use_tree_id, unused.use_tree_id,
ms, ms,
&msg, &msg,
lint::builtin::BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes), BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes),
); );
} }
} }

View file

@ -12,9 +12,9 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet
use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding}; use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
use rustc::hir::exports::Export; use rustc::hir::exports::Export;
use rustc::lint::builtin::BuiltinLintDiagnostics;
use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS}; 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::ty;
use rustc::{bug, span_bug}; use rustc::{bug, span_bug};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;

View file

@ -24,7 +24,6 @@ use rustc::hir::exports::ExportMap;
use rustc::hir::map::{DefKey, Definitions}; use rustc::hir::map::{DefKey, Definitions};
use rustc::lint; use rustc::lint;
use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
use rustc::session::Session;
use rustc::span_bug; use rustc::span_bug;
use rustc::ty::query::Providers; use rustc::ty::query::Providers;
use rustc::ty::{self, DefIdTree, ResolverOutputs}; 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::PrimTy::{self, Bool, Char, Float, Int, Str, Uint};
use rustc_hir::{GlobMap, TraitMap}; use rustc_hir::{GlobMap, TraitMap};
use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
use rustc_session::node_id::{NodeMap, NodeSet}; use rustc_session::node_id::{NodeMap, NodeSet};
use rustc_session::Session;
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency}; use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::{kw, sym};
@ -960,7 +961,7 @@ pub struct Resolver<'a> {
/// when visiting the correspondent variants. /// when visiting the correspondent variants.
variant_vis: DefIdMap<ty::Visibility>, variant_vis: DefIdMap<ty::Visibility>,
lint_buffer: lint::LintBuffer, lint_buffer: LintBuffer,
next_node_id: NodeId, next_node_id: NodeId,
} }
@ -1082,7 +1083,7 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> {
&mut self.definitions &mut self.definitions
} }
fn lint_buffer(&mut self) -> &mut lint::LintBuffer { fn lint_buffer(&mut self) -> &mut LintBuffer {
&mut self.lint_buffer &mut self.lint_buffer
} }
@ -1241,7 +1242,7 @@ impl<'a> Resolver<'a> {
.chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat)) .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
.collect(), .collect(),
variant_vis: Default::default(), variant_vis: Default::default(),
lint_buffer: lint::LintBuffer::default(), lint_buffer: LintBuffer::default(),
next_node_id: NodeId::from_u32(1), next_node_id: NodeId::from_u32(1),
} }
} }
@ -1256,7 +1257,7 @@ impl<'a> Resolver<'a> {
self.next_node_id 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 &mut self.lint_buffer
} }
@ -1713,10 +1714,10 @@ impl<'a> Resolver<'a> {
if let Some(node_id) = poisoned { if let Some(node_id) = poisoned {
self.lint_buffer.buffer_lint_with_diagnostic( self.lint_buffer.buffer_lint_with_diagnostic(
lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
node_id, ident.span, node_id,
ident.span,
&format!("cannot find {} `{}` in this scope", ns.descr(), ident), &format!("cannot find {} `{}` in this scope", ns.descr(), ident),
lint::builtin::BuiltinLintDiagnostics:: BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(ident.span),
ProcMacroDeriveResolutionFallback(ident.span),
); );
} }
return Some(LexicalScopeBinding::Item(binding)); 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( self.lint_buffer.buffer_lint_with_diagnostic(
lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
diag_id, diag_id,
@ -2562,9 +2563,10 @@ impl<'a> Resolver<'a> {
cannot be referred to by absolute paths"; cannot be referred to by absolute paths";
self.lint_buffer.buffer_lint_with_diagnostic( self.lint_buffer.buffer_lint_with_diagnostic(
lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
CRATE_NODE_ID, span_use, msg, CRATE_NODE_ID,
lint::builtin::BuiltinLintDiagnostics:: span_use,
MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def), msg,
BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def),
); );
} }

View file

@ -1,8 +1,8 @@
pub use self::Level::*; 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_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_span::edition::Edition; 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. /// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
@ -174,7 +174,25 @@ impl<HCX> ToStableHashKey<HCX> 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<Symbol>, 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 { pub struct BufferedEarlyLint {
/// The span of code that we are linting on. /// The span of code that we are linting on.
pub span: MultiSpan, pub span: MultiSpan,
@ -183,10 +201,65 @@ pub struct BufferedEarlyLint {
pub msg: String, pub msg: String,
/// The `NodeId` of the AST node that generated the lint. /// 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`. /// 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<Vec<BufferedEarlyLint>>,
}
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<BufferedEarlyLint> {
self.map.remove(&id).unwrap_or_default()
}
pub fn buffer_lint(
&mut self,
lint: &'static Lint,
id: NodeId,
sp: impl Into<MultiSpan>,
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<MultiSpan>,
msg: &str,
diagnostic: BuiltinLintDiagnostics,
) {
self.add_lint(lint, id, sp.into(), msg, diagnostic)
}
} }
/// Declares a static item of type `&'static Lint`. /// Declares a static item of type `&'static Lint`.

View file

@ -1,7 +1,7 @@
//! Contains `ParseSess` which holds state living beyond what one `Parser` might. //! Contains `ParseSess` which holds state living beyond what one `Parser` might.
//! It also serves as an input to the parser itself. //! 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 crate::node_id::NodeId;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -210,17 +210,18 @@ impl ParseSess {
pub fn buffer_lint( pub fn buffer_lint(
&self, &self,
lint_id: &'static crate::lint::Lint, lint: &'static Lint,
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
id: NodeId, node_id: NodeId,
msg: &str, msg: &str,
) { ) {
self.buffered_lints.with_lock(|buffered_lints| { self.buffered_lints.with_lock(|buffered_lints| {
buffered_lints.push(BufferedEarlyLint { buffered_lints.push(BufferedEarlyLint {
span: span.into(), span: span.into(),
id, node_id,
msg: msg.into(), msg: msg.into(),
lint_id, lint_id: LintId::of(lint),
diagnostic: BuiltinLintDiagnostics::Normal,
}); });
}); });
} }