mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-05 19:43:24 +00:00
Rollup merge of #91526 - petrochenkov:earlint, r=cjgillot
rustc_lint: Some early linting refactorings The first one removes and renames some fields and methods from `EarlyContext`. The second one uses the set of registered tools (for tool attributes and tool lints) in a more centralized way. The third one removes creation of a fake `ast::Crate` from `fn pre_expansion_lint`. Pre-expansion linting is done with per-module granularity on freshly loaded modules, and it previously synthesized an `ast::Crate` to visit non-root modules, now they are visited as modules. The node ID used for pre-expansion linting is also made more precise (the loaded module ID is used).
This commit is contained in:
commit
89baf0f162
@ -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,8 +920,25 @@ 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>;
|
||||
}
|
||||
|
||||
pub trait LintStoreExpand {
|
||||
fn pre_expansion_lint(
|
||||
&self,
|
||||
sess: &Session,
|
||||
registered_tools: &FxHashSet<Ident>,
|
||||
node_id: NodeId,
|
||||
attrs: &[Attribute],
|
||||
items: &[P<Item>],
|
||||
name: &str,
|
||||
);
|
||||
}
|
||||
|
||||
type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ModuleData {
|
||||
/// Path to the module starting from the crate name, like `my_crate::foo::bar`.
|
||||
@ -956,9 +973,6 @@ pub struct ExpansionData {
|
||||
pub is_trailing_mac: bool,
|
||||
}
|
||||
|
||||
type OnExternModLoaded<'a> =
|
||||
Option<&'a dyn Fn(Ident, Vec<Attribute>, Vec<P<Item>>, Span) -> (Vec<Attribute>, Vec<P<Item>>)>;
|
||||
|
||||
/// One of these is made during expansion and incrementally updated as we go;
|
||||
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
|
||||
/// -> expn_data` of their expansion context stored into their span.
|
||||
@ -973,10 +987,8 @@ pub struct ExtCtxt<'a> {
|
||||
/// (or during eager expansion, but that's a hack).
|
||||
pub force_mode: bool,
|
||||
pub expansions: FxHashMap<Span, Vec<String>>,
|
||||
/// Called directly after having parsed an external `mod foo;` in expansion.
|
||||
///
|
||||
/// `Ident` is the module name.
|
||||
pub(super) extern_mod_loaded: OnExternModLoaded<'a>,
|
||||
/// Used for running pre-expansion lints on freshly loaded modules.
|
||||
pub(super) lint_store: LintStoreExpandDyn<'a>,
|
||||
/// When we 'expand' an inert attribute, we leave it
|
||||
/// in the AST, but insert it here so that we know
|
||||
/// not to expand it again.
|
||||
@ -988,14 +1000,14 @@ impl<'a> ExtCtxt<'a> {
|
||||
sess: &'a Session,
|
||||
ecfg: expand::ExpansionConfig<'a>,
|
||||
resolver: &'a mut dyn ResolverExpand,
|
||||
extern_mod_loaded: OnExternModLoaded<'a>,
|
||||
lint_store: LintStoreExpandDyn<'a>,
|
||||
) -> ExtCtxt<'a> {
|
||||
ExtCtxt {
|
||||
sess,
|
||||
ecfg,
|
||||
reduced_recursion_limit: None,
|
||||
resolver,
|
||||
extern_mod_loaded,
|
||||
lint_store,
|
||||
root_path: PathBuf::new(),
|
||||
current_expansion: ExpansionData {
|
||||
id: LocalExpnId::ROOT,
|
||||
|
@ -1097,7 +1097,7 @@ impl InvocationCollectorNode for P<ast::Item> {
|
||||
ModKind::Unloaded => {
|
||||
// We have an outline `mod foo;` so we need to parse the file.
|
||||
let old_attrs_len = attrs.len();
|
||||
let ParsedExternalMod { mut items, inner_span, file_path, dir_path, dir_ownership } =
|
||||
let ParsedExternalMod { items, inner_span, file_path, dir_path, dir_ownership } =
|
||||
parse_external_mod(
|
||||
&ecx.sess,
|
||||
ident,
|
||||
@ -1107,8 +1107,15 @@ impl InvocationCollectorNode for P<ast::Item> {
|
||||
&mut attrs,
|
||||
);
|
||||
|
||||
if let Some(extern_mod_loaded) = ecx.extern_mod_loaded {
|
||||
(attrs, items) = extern_mod_loaded(ident, attrs, items, inner_span);
|
||||
if let Some(lint_store) = ecx.lint_store {
|
||||
lint_store.pre_expansion_lint(
|
||||
ecx.sess,
|
||||
ecx.resolver.registered_tools(),
|
||||
ecx.current_expansion.lint_node_id,
|
||||
&attrs,
|
||||
&items,
|
||||
ident.name.as_str(),
|
||||
);
|
||||
}
|
||||
|
||||
*mod_kind = ModKind::Loaded(items, Inline::No, inner_span);
|
||||
|
@ -3,7 +3,7 @@ use crate::proc_macro_decls;
|
||||
use crate::util;
|
||||
|
||||
use rustc_ast::mut_visit::MutVisitor;
|
||||
use rustc_ast::{self as ast, visit, DUMMY_NODE_ID};
|
||||
use rustc_ast::{self as ast, visit};
|
||||
use rustc_borrowck as mir_borrowck;
|
||||
use rustc_codegen_ssa::back::link::emit_metadata;
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
@ -11,16 +11,16 @@ 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, LintStoreExpand, ResolverExpand};
|
||||
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
|
||||
use rustc_hir::Crate;
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_lint::{EarlyCheckNode, LintStore};
|
||||
use rustc_metadata::creader::CStore;
|
||||
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};
|
||||
@ -34,7 +34,7 @@ use rustc_session::lint;
|
||||
use rustc_session::output::{filename_for_input, filename_for_metadata};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::{Limit, Session};
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{FileName, MultiSpan};
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_typeck as typeck;
|
||||
@ -233,26 +233,43 @@ pub fn register_plugins<'a>(
|
||||
Ok((krate, lint_store))
|
||||
}
|
||||
|
||||
fn pre_expansion_lint(
|
||||
fn pre_expansion_lint<'a>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_attrs: &[ast::Attribute],
|
||||
crate_name: &str,
|
||||
registered_tools: &RegisteredTools,
|
||||
check_node: impl EarlyCheckNode<'a>,
|
||||
node_name: &str,
|
||||
) {
|
||||
sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", crate_name).run(|| {
|
||||
rustc_lint::check_ast_crate(
|
||||
sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", node_name).run(|| {
|
||||
rustc_lint::check_ast_node(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
true,
|
||||
lint_store,
|
||||
registered_tools,
|
||||
None,
|
||||
rustc_lint::BuiltinCombinedPreExpansionLintPass::new(),
|
||||
check_node,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Cannot implement directly for `LintStore` due to trait coherence.
|
||||
struct LintStoreExpandImpl<'a>(&'a LintStore);
|
||||
|
||||
impl LintStoreExpand for LintStoreExpandImpl<'_> {
|
||||
fn pre_expansion_lint(
|
||||
&self,
|
||||
sess: &Session,
|
||||
registered_tools: &RegisteredTools,
|
||||
node_id: ast::NodeId,
|
||||
attrs: &[ast::Attribute],
|
||||
items: &[rustc_ast::ptr::P<ast::Item>],
|
||||
name: &str,
|
||||
) {
|
||||
pre_expansion_lint(sess, self.0, registered_tools, (node_id, attrs, items), name);
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
|
||||
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
|
||||
/// harness if one is to be provided, injection of a dependency on the
|
||||
@ -265,7 +282,7 @@ pub fn configure_and_expand(
|
||||
resolver: &mut Resolver<'_>,
|
||||
) -> Result<ast::Crate> {
|
||||
tracing::trace!("configure_and_expand");
|
||||
pre_expansion_lint(sess, lint_store, &krate, &krate.attrs, 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,13 +338,8 @@ pub fn configure_and_expand(
|
||||
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
|
||||
};
|
||||
|
||||
let crate_attrs = krate.attrs.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, &krate, &crate_attrs, ident.name.as_str());
|
||||
(krate.attrs, krate.items)
|
||||
};
|
||||
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&extern_mod_loaded));
|
||||
let lint_store = LintStoreExpandImpl(lint_store);
|
||||
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&lint_store));
|
||||
|
||||
// Expand macros now!
|
||||
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
|
||||
@ -499,14 +511,15 @@ pub fn lower_to_hir<'res, 'tcx>(
|
||||
);
|
||||
|
||||
sess.time("early_lint_checks", || {
|
||||
rustc_lint::check_ast_crate(
|
||||
let lint_buffer = Some(std::mem::take(resolver.lint_buffer()));
|
||||
rustc_lint::check_ast_node(
|
||||
sess,
|
||||
lint_store,
|
||||
&krate,
|
||||
&krate.attrs,
|
||||
false,
|
||||
Some(std::mem::take(resolver.lint_buffer())),
|
||||
lint_store,
|
||||
resolver.registered_tools(),
|
||||
lint_buffer,
|
||||
rustc_lint::BuiltinCombinedEarlyLintPass::new(),
|
||||
&*krate,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -912,7 +912,7 @@ declare_lint_pass!(
|
||||
|
||||
impl EarlyLintPass for AnonymousParameters {
|
||||
fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
|
||||
if cx.sess.edition() != Edition::Edition2015 {
|
||||
if cx.sess().edition() != Edition::Edition2015 {
|
||||
// This is a hard error in future editions; avoid linting and erroring
|
||||
return;
|
||||
}
|
||||
@ -921,7 +921,7 @@ impl EarlyLintPass for AnonymousParameters {
|
||||
if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
|
||||
if ident.name == kw::Empty {
|
||||
cx.struct_span_lint(ANONYMOUS_PARAMETERS, arg.pat.span, |lint| {
|
||||
let ty_snip = cx.sess.source_map().span_to_snippet(arg.ty.span);
|
||||
let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span);
|
||||
|
||||
let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
|
||||
(snip.as_str(), Applicability::MachineApplicable)
|
||||
@ -1775,7 +1775,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
||||
};
|
||||
if join.edition() >= Edition::Edition2021 {
|
||||
let mut err =
|
||||
rustc_errors::struct_span_err!(cx.sess, pat.span, E0783, "{}", msg,);
|
||||
rustc_errors::struct_span_err!(cx.sess(), pat.span, E0783, "{}", msg,);
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
suggestion,
|
||||
@ -1799,7 +1799,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
||||
let replace = "..=".to_owned();
|
||||
if join.edition() >= Edition::Edition2021 {
|
||||
let mut err =
|
||||
rustc_errors::struct_span_err!(cx.sess, pat.span, E0783, "{}", msg,);
|
||||
rustc_errors::struct_span_err!(cx.sess(), pat.span, E0783, "{}", msg,);
|
||||
err.span_suggestion_short(
|
||||
join,
|
||||
suggestion,
|
||||
@ -1983,7 +1983,7 @@ impl KeywordIdents {
|
||||
UnderMacro(under_macro): UnderMacro,
|
||||
ident: Ident,
|
||||
) {
|
||||
let next_edition = match cx.sess.edition() {
|
||||
let next_edition = match cx.sess().edition() {
|
||||
Edition::Edition2015 => {
|
||||
match ident.name {
|
||||
kw::Async | kw::Await | kw::Try => Edition::Edition2018,
|
||||
@ -2011,7 +2011,7 @@ impl KeywordIdents {
|
||||
};
|
||||
|
||||
// Don't lint `r#foo`.
|
||||
if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span) {
|
||||
if cx.sess().parse_sess.raw_identifier_spans.borrow().contains(&ident.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2379,7 +2379,7 @@ declare_lint_pass!(
|
||||
|
||||
impl EarlyLintPass for IncompleteFeatures {
|
||||
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
|
||||
let features = cx.sess.features_untracked();
|
||||
let features = cx.sess().features_untracked();
|
||||
features
|
||||
.declared_lang_features
|
||||
.iter()
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
@ -553,20 +556,9 @@ pub struct LateContext<'tcx> {
|
||||
pub only_module: bool,
|
||||
}
|
||||
|
||||
/// Context for lint checking of the AST, after expansion, before lowering to
|
||||
/// HIR.
|
||||
/// Context for lint checking of the AST, after expansion, before lowering to HIR.
|
||||
pub struct EarlyContext<'a> {
|
||||
/// Type context we're checking in.
|
||||
pub sess: &'a Session,
|
||||
|
||||
/// The crate being checked.
|
||||
pub krate: &'a ast::Crate,
|
||||
|
||||
pub builder: LintLevelsBuilder<'a>,
|
||||
|
||||
/// The store of registered lints and the lint levels.
|
||||
pub lint_store: &'a LintStore,
|
||||
|
||||
pub buffered: LintBuffer,
|
||||
}
|
||||
|
||||
@ -801,19 +793,20 @@ pub trait LintContext: Sized {
|
||||
}
|
||||
|
||||
impl<'a> EarlyContext<'a> {
|
||||
pub fn new(
|
||||
pub(crate) fn new(
|
||||
sess: &'a Session,
|
||||
lint_store: &'a LintStore,
|
||||
krate: &'a ast::Crate,
|
||||
crate_attrs: &'a [ast::Attribute],
|
||||
buffered: LintBuffer,
|
||||
warn_about_weird_lints: bool,
|
||||
lint_store: &'a LintStore,
|
||||
registered_tools: &'a RegisteredTools,
|
||||
buffered: LintBuffer,
|
||||
) -> EarlyContext<'a> {
|
||||
EarlyContext {
|
||||
sess,
|
||||
krate,
|
||||
lint_store,
|
||||
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,
|
||||
}
|
||||
}
|
||||
@ -851,11 +844,11 @@ impl LintContext for EarlyContext<'_> {
|
||||
|
||||
/// Gets the overall compiler `Session` object.
|
||||
fn sess(&self) -> &Session {
|
||||
&self.sess
|
||||
&self.builder.sess()
|
||||
}
|
||||
|
||||
fn lints(&self) -> &LintStore {
|
||||
&*self.lint_store
|
||||
self.builder.lint_store()
|
||||
}
|
||||
|
||||
fn lookup<S: Into<MultiSpan>>(
|
||||
|
@ -16,9 +16,11 @@
|
||||
|
||||
use crate::context::{EarlyContext, LintContext, LintStore};
|
||||
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::visit as ast_visit;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self as ast_visit, Visitor};
|
||||
use rustc_ast::AstLike;
|
||||
use rustc_ast::{self as ast, walk_list};
|
||||
use rustc_middle::ty::RegisteredTools;
|
||||
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
@ -31,7 +33,7 @@ macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
|
||||
$cx.pass.$f(&$cx.context, $($args),*);
|
||||
}) }
|
||||
|
||||
struct EarlyContextAndPass<'a, T: EarlyLintPass> {
|
||||
pub struct EarlyContextAndPass<'a, T: EarlyLintPass> {
|
||||
context: EarlyContext<'a>,
|
||||
pass: T,
|
||||
}
|
||||
@ -57,7 +59,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
|
||||
F: FnOnce(&mut Self),
|
||||
{
|
||||
let is_crate_node = id == ast::CRATE_NODE_ID;
|
||||
let push = self.context.builder.push(attrs, &self.context.lint_store, is_crate_node);
|
||||
let push = self.context.builder.push(attrs, is_crate_node);
|
||||
self.check_id(id);
|
||||
self.enter_attrs(attrs);
|
||||
f(self);
|
||||
@ -325,48 +327,89 @@ macro_rules! early_lint_pass_impl {
|
||||
|
||||
crate::early_lint_methods!(early_lint_pass_impl, []);
|
||||
|
||||
fn early_lint_crate<T: EarlyLintPass>(
|
||||
/// Early lints work on different nodes - either on the crate root, or on freshly loaded modules.
|
||||
/// This trait generalizes over those nodes.
|
||||
pub trait EarlyCheckNode<'a>: Copy {
|
||||
fn id(self) -> ast::NodeId;
|
||||
fn attrs<'b>(self) -> &'b [ast::Attribute]
|
||||
where
|
||||
'a: 'b;
|
||||
fn check<'b>(self, cx: &mut EarlyContextAndPass<'b, impl EarlyLintPass>)
|
||||
where
|
||||
'a: 'b;
|
||||
}
|
||||
|
||||
impl<'a> EarlyCheckNode<'a> for &'a ast::Crate {
|
||||
fn id(self) -> ast::NodeId {
|
||||
ast::CRATE_NODE_ID
|
||||
}
|
||||
fn attrs<'b>(self) -> &'b [ast::Attribute]
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
&self.attrs
|
||||
}
|
||||
fn check<'b>(self, cx: &mut EarlyContextAndPass<'b, impl EarlyLintPass>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
run_early_pass!(cx, check_crate, self);
|
||||
ast_visit::walk_crate(cx, self);
|
||||
run_early_pass!(cx, check_crate_post, self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::Item>]) {
|
||||
fn id(self) -> ast::NodeId {
|
||||
self.0
|
||||
}
|
||||
fn attrs<'b>(self) -> &'b [ast::Attribute]
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
self.1
|
||||
}
|
||||
fn check<'b>(self, cx: &mut EarlyContextAndPass<'b, impl EarlyLintPass>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
walk_list!(cx, visit_attribute, self.1);
|
||||
walk_list!(cx, visit_item, self.2);
|
||||
}
|
||||
}
|
||||
|
||||
fn early_lint_node<'a>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_attrs: &[ast::Attribute],
|
||||
pass: T,
|
||||
buffered: LintBuffer,
|
||||
warn_about_weird_lints: bool,
|
||||
lint_store: &LintStore,
|
||||
registered_tools: &RegisteredTools,
|
||||
buffered: LintBuffer,
|
||||
pass: impl EarlyLintPass,
|
||||
check_node: impl EarlyCheckNode<'a>,
|
||||
) -> LintBuffer {
|
||||
let mut cx = EarlyContextAndPass {
|
||||
context: EarlyContext::new(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
buffered,
|
||||
warn_about_weird_lints,
|
||||
lint_store,
|
||||
registered_tools,
|
||||
buffered,
|
||||
),
|
||||
pass,
|
||||
};
|
||||
|
||||
// Visit the whole crate.
|
||||
cx.with_lint_attrs(ast::CRATE_NODE_ID, &krate.attrs, |cx| {
|
||||
// since the root module isn't visited as an item (because it isn't an
|
||||
// item), warn for it here.
|
||||
run_early_pass!(cx, check_crate, krate);
|
||||
|
||||
ast_visit::walk_crate(cx, krate);
|
||||
|
||||
run_early_pass!(cx, check_crate_post, krate);
|
||||
});
|
||||
cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));
|
||||
cx.context.buffered
|
||||
}
|
||||
|
||||
pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
pub fn check_ast_node<'a>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_attrs: &[ast::Attribute],
|
||||
pre_expansion: bool,
|
||||
lint_store: &LintStore,
|
||||
registered_tools: &RegisteredTools,
|
||||
lint_buffer: Option<LintBuffer>,
|
||||
builtin_lints: T,
|
||||
builtin_lints: impl EarlyLintPass,
|
||||
check_node: impl EarlyCheckNode<'a>,
|
||||
) {
|
||||
let passes =
|
||||
if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
|
||||
@ -374,39 +417,39 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
let mut buffered = lint_buffer.unwrap_or_default();
|
||||
|
||||
if !sess.opts.debugging_opts.no_interleave_lints {
|
||||
buffered = early_lint_crate(
|
||||
buffered = early_lint_node(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
builtin_lints,
|
||||
buffered,
|
||||
pre_expansion,
|
||||
lint_store,
|
||||
registered_tools,
|
||||
buffered,
|
||||
builtin_lints,
|
||||
check_node,
|
||||
);
|
||||
|
||||
if !passes.is_empty() {
|
||||
buffered = early_lint_crate(
|
||||
buffered = early_lint_node(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
EarlyLintPassObjects { lints: &mut passes[..] },
|
||||
buffered,
|
||||
false,
|
||||
lint_store,
|
||||
registered_tools,
|
||||
buffered,
|
||||
EarlyLintPassObjects { lints: &mut passes[..] },
|
||||
check_node,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (i, pass) in passes.iter_mut().enumerate() {
|
||||
buffered =
|
||||
sess.prof.extra_verbose_generic_activity("run_lint", pass.name()).run(|| {
|
||||
early_lint_crate(
|
||||
early_lint_node(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
EarlyLintPassObjects { lints: slice::from_mut(pass) },
|
||||
buffered,
|
||||
pre_expansion && i == 0,
|
||||
lint_store,
|
||||
registered_tools,
|
||||
buffered,
|
||||
EarlyLintPassObjects { lints: slice::from_mut(pass) },
|
||||
check_node,
|
||||
)
|
||||
});
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{intravisit, HirId, CRATE_HIR_ID};
|
||||
use rustc_hir::{intravisit, HirId};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::lint::LevelAndSource;
|
||||
use rustc_middle::lint::LintDiagnosticBuilder;
|
||||
@ -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,14 +27,14 @@ 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 mut builder = LintLevelMapBuilder { levels, tcx, store };
|
||||
let levels =
|
||||
LintLevelsBuilder::new(tcx.sess, false, &store, &tcx.resolutions(()).registered_tools);
|
||||
let mut builder = LintLevelMapBuilder { levels, tcx };
|
||||
let krate = tcx.hir().krate();
|
||||
|
||||
builder.levels.id_to_set.reserve(krate.owners.len() + 1);
|
||||
|
||||
let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), &store, true);
|
||||
let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), true);
|
||||
builder.levels.register_id(hir::CRATE_HIR_ID);
|
||||
tcx.hir().walk_toplevel_module(&mut builder);
|
||||
builder.levels.pop(push);
|
||||
@ -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,19 +71,27 @@ 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);
|
||||
builder
|
||||
}
|
||||
|
||||
pub(crate) fn sess(&self) -> &Session {
|
||||
self.sess
|
||||
}
|
||||
|
||||
pub(crate) fn lint_store(&self) -> &LintStore {
|
||||
self.store
|
||||
}
|
||||
|
||||
fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
|
||||
let mut specs = FxHashMap::default();
|
||||
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);
|
||||
|
||||
@ -217,12 +225,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
/// `#[allow]`
|
||||
///
|
||||
/// Don't forget to call `pop`!
|
||||
pub(crate) fn push(
|
||||
&mut self,
|
||||
attrs: &[ast::Attribute],
|
||||
store: &LintStore,
|
||||
is_crate_node: bool,
|
||||
) -> BuilderPush {
|
||||
pub(crate) fn push(&mut self, attrs: &[ast::Attribute], is_crate_node: bool) -> BuilderPush {
|
||||
let mut specs = FxHashMap::default();
|
||||
let sess = self.sess;
|
||||
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
|
||||
@ -310,7 +313,8 @@ 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 = store.check_lint_name(sess, &name, tool_name, self.crate_attrs);
|
||||
let lint_result =
|
||||
self.store.check_lint_name(&name, tool_name, self.registered_tools);
|
||||
match &lint_result {
|
||||
CheckLintNameResult::Ok(ids) => {
|
||||
let src = LintLevelSource::Node(
|
||||
@ -459,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) =
|
||||
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 {
|
||||
@ -562,34 +566,19 @@ 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<'a, 'tcx> {
|
||||
struct LintLevelMapBuilder<'tcx> {
|
||||
levels: LintLevelsBuilder<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
store: &'a LintStore,
|
||||
}
|
||||
|
||||
impl LintLevelMapBuilder<'_, '_> {
|
||||
impl LintLevelMapBuilder<'_> {
|
||||
fn with_lint_attrs<F>(&mut self, id: hir::HirId, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Self),
|
||||
{
|
||||
let is_crate_hir = id == hir::CRATE_HIR_ID;
|
||||
let attrs = self.tcx.hir().attrs(id);
|
||||
let push = self.levels.push(attrs, self.store, is_crate_hir);
|
||||
let push = self.levels.push(attrs, is_crate_hir);
|
||||
if push.changed {
|
||||
self.levels.register_id(id);
|
||||
}
|
||||
@ -598,7 +587,7 @@ impl LintLevelMapBuilder<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
|
||||
impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
|
||||
type NestedFilter = nested_filter::All;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
|
@ -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_crate;
|
||||
pub use early::{check_ast_node, EarlyCheckNode};
|
||||
pub use late::check_crate;
|
||||
pub use passes::{EarlyLintPass, LateLintPass};
|
||||
pub use rustc_session::lint::Level::{self, *};
|
||||
|
@ -166,7 +166,7 @@ impl EarlyLintPass for NonAsciiIdents {
|
||||
}
|
||||
|
||||
let mut has_non_ascii_idents = false;
|
||||
let symbols = cx.sess.parse_sess.symbol_gallery.symbols.lock();
|
||||
let symbols = cx.sess().parse_sess.symbol_gallery.symbols.lock();
|
||||
|
||||
// Sort by `Span` so that error messages make sense with respect to the
|
||||
// order of identifier locations in the code.
|
||||
|
@ -164,7 +164,7 @@ impl EarlyLintPass for NonCamelCaseTypes {
|
||||
let has_repr_c = it
|
||||
.attrs
|
||||
.iter()
|
||||
.any(|attr| attr::find_repr_attrs(&cx.sess, attr).contains(&attr::ReprC));
|
||||
.any(|attr| attr::find_repr_attrs(cx.sess(), attr).contains(&attr::ReprC));
|
||||
|
||||
if has_repr_c {
|
||||
return;
|
||||
|
@ -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)]
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
@ -48,7 +48,7 @@ declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
|
||||
|
||||
impl EarlyLintPass for AsConversions {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::ast;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, Level};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use unicode_script::{Script, UnicodeScript};
|
||||
|
||||
@ -72,7 +72,7 @@ impl EarlyLintPass for DisallowedScriptIdents {
|
||||
return;
|
||||
}
|
||||
|
||||
let symbols = cx.sess.parse_sess.symbol_gallery.symbols.lock();
|
||||
let symbols = cx.sess().parse_sess.symbol_gallery.symbols.lock();
|
||||
// Sort by `Span` so that error messages make sense with respect to the
|
||||
// order of identifier locations in the code.
|
||||
let mut symbols: Vec<_> = symbols.iter().collect();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
@ -50,7 +50,7 @@ declare_lint_pass!(ElseIfWithoutElse => [ELSE_IF_WITHOUT_ELSE]);
|
||||
|
||||
impl EarlyLintPass for ElseIfWithoutElse {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, mut item: &Expr) {
|
||||
if in_external_macro(cx.sess, item.span) {
|
||||
if in_external_macro(cx.sess(), item.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use clippy_utils::differing_macro_contexts;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::source_map::Span;
|
||||
@ -207,7 +207,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if let ExprKind::If(_, then, Some(else_)) = &expr.kind;
|
||||
if is_block(else_) || is_if(else_);
|
||||
if !differing_macro_contexts(then.span, else_.span);
|
||||
if !then.span.from_expansion() && !in_external_macro(cx.sess, expr.span);
|
||||
if !then.span.from_expansion() && !in_external_macro(cx.sess(), expr.span);
|
||||
|
||||
// workaround for rust-lang/rust#43081
|
||||
if expr.span.lo().0 != 0 && expr.span.hi().0 != 0;
|
||||
@ -259,7 +259,7 @@ fn has_unary_equivalent(bin_op: BinOpKind) -> bool {
|
||||
}
|
||||
|
||||
fn indentation(cx: &EarlyContext<'_>, span: Span) -> usize {
|
||||
cx.sess.source_map().lookup_char_pos(span.lo()).col.0
|
||||
cx.sess().source_map().lookup_char_pos(span.lo()).col.0
|
||||
}
|
||||
|
||||
/// Implementation of the `POSSIBLE_MISSING_COMMA` lint for array
|
||||
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::ast::{Block, ItemKind, StmtKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
@ -55,7 +55,7 @@ declare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]);
|
||||
|
||||
impl EarlyLintPass for ItemsAfterStatements {
|
||||
fn check_block(&mut self, cx: &EarlyContext<'_>, item: &Block) {
|
||||
if in_external_macro(cx.sess, item.span) {
|
||||
if in_external_macro(cx.sess(), item.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ impl EarlyLintPass for ItemsAfterStatements {
|
||||
// lint on all further items
|
||||
for stmt in stmts {
|
||||
if let StmtKind::Item(ref it) = *stmt {
|
||||
if in_external_macro(cx.sess, it.span) {
|
||||
if in_external_macro(cx.sess(), it.span) {
|
||||
return;
|
||||
}
|
||||
if let ItemKind::MacroDef(..) = it.kind {
|
||||
|
@ -7,7 +7,7 @@ use clippy_utils::source::snippet_opt;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{Expr, ExprKind, Lit, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use std::iter;
|
||||
@ -225,7 +225,7 @@ impl_lint_pass!(LiteralDigitGrouping => [
|
||||
|
||||
impl EarlyLintPass for LiteralDigitGrouping {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ impl_lint_pass!(DecimalLiteralRepresentation => [DECIMAL_LITERAL_REPRESENTATION]
|
||||
|
||||
impl EarlyLintPass for DecimalLiteralRepresentation {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use clippy_utils::{meets_msrv, msrvs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{FieldDef, Item, ItemKind, Variant, VariantData, VisibilityKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{sym, Span};
|
||||
@ -116,7 +116,7 @@ fn check_manual_non_exhaustive_enum(cx: &EarlyContext<'_>, item: &Item, variants
|
||||
|diag| {
|
||||
if_chain! {
|
||||
if !item.attrs.iter().any(|attr| attr.has_name(sym::non_exhaustive));
|
||||
let header_span = cx.sess.source_map().span_until_char(item.span, '{');
|
||||
let header_span = cx.sess().source_map().span_until_char(item.span, '{');
|
||||
if let Some(snippet) = snippet_opt(cx, header_span);
|
||||
then {
|
||||
diag.span_suggestion(
|
||||
@ -149,7 +149,7 @@ fn check_manual_non_exhaustive_struct(cx: &EarlyContext<'_>, item: &Item, data:
|
||||
VariantData::Unit(_) => unreachable!("`VariantData::Unit` is already handled above"),
|
||||
};
|
||||
|
||||
cx.sess.source_map().span_until_char(item.span, delimiter)
|
||||
cx.sess().source_map().span_until_char(item.span, delimiter)
|
||||
}
|
||||
|
||||
let fields = data.fields();
|
||||
|
@ -9,7 +9,7 @@ use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::BinOpKind;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -25,7 +25,7 @@ use rustc_hir::{
|
||||
Mutability, Node, Pat, PatKind, PathSegment, QPath, RangeEnd, TyKind,
|
||||
};
|
||||
use rustc_hir::{HirIdMap, HirIdSet};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self, Ty, TyS, VariantDef};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -6,7 +6,7 @@ use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -12,7 +12,7 @@ use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
|
||||
use rustc_ast::visit::FnKind;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::source_map::Span;
|
||||
@ -342,7 +342,7 @@ impl EarlyLintPass for MiscEarlyLints {
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, meets_msrv, msr
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -80,9 +80,9 @@ impl EarlyLintPass for ModStyle {
|
||||
return;
|
||||
}
|
||||
|
||||
let files = cx.sess.source_map().files();
|
||||
let files = cx.sess().source_map().files();
|
||||
|
||||
let trim_to_src = if let RealFileName::LocalPath(p) = &cx.sess.opts.working_dir {
|
||||
let trim_to_src = if let RealFileName::LocalPath(p) = &cx.sess().opts.working_dir {
|
||||
p.to_string_lossy()
|
||||
} else {
|
||||
return;
|
||||
|
@ -3,7 +3,7 @@ use rustc_ast::ast::{
|
||||
self, Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, Pat, PatKind,
|
||||
};
|
||||
use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::source_map::Span;
|
||||
@ -356,7 +356,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {
|
||||
|
||||
impl EarlyLintPass for NonExpressiveNames {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
if in_external_macro(cx.sess, item.span) {
|
||||
if in_external_macro(cx.sess(), item.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -371,7 +371,7 @@ impl EarlyLintPass for NonExpressiveNames {
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
|
||||
if in_external_macro(cx.sess, item.span) {
|
||||
if in_external_macro(cx.sess(), item.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_ast::token::{Lit, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::Span;
|
||||
@ -51,7 +51,7 @@ declare_lint_pass!(OctalEscapes => [OCTAL_ESCAPES]);
|
||||
|
||||
impl EarlyLintPass for OctalEscapes {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use if_chain::if_chain;
|
||||
use rustc_ast::ast::RangeLimits;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -8,7 +8,7 @@ use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit as hir_visit;
|
||||
use rustc_hir::intravisit::Visitor as HirVisitor;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -62,7 +62,7 @@ impl<'ast> ast_visit::Visitor<'ast> for ReturnVisitor {
|
||||
|
||||
impl EarlyLintPass for RedundantClosureCall {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
if_chain! {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustc_ast::visit::{walk_expr, Visitor};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
@ -46,7 +46,7 @@ declare_lint_pass!(RedundantElse => [REDUNDANT_ELSE]);
|
||||
|
||||
impl EarlyLintPass for RedundantElse {
|
||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
|
||||
if in_external_macro(cx.sess, stmt.span) {
|
||||
if in_external_macro(cx.sess(), stmt.span) {
|
||||
return;
|
||||
}
|
||||
// Only look at expressions that are a whole statement
|
||||
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
@ -55,7 +55,7 @@ impl EarlyLintPass for RedundantFieldNames {
|
||||
return;
|
||||
}
|
||||
|
||||
if in_external_macro(cx.sess, expr.span) {
|
||||
if in_external_macro(cx.sess(), expr.span) {
|
||||
return;
|
||||
}
|
||||
if let ExprKind::Struct(ref se) = expr.kind {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_ast::ast::{GenericParam, GenericParamKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
@ -43,7 +43,7 @@ declare_lint_pass!(SingleCharLifetimeNames => [SINGLE_CHAR_LIFETIME_NAMES]);
|
||||
|
||||
impl EarlyLintPass for SingleCharLifetimeNames {
|
||||
fn check_generic_param(&mut self, ctx: &EarlyContext<'_>, param: &GenericParam) {
|
||||
if in_external_macro(ctx.sess, param.ident.span) {
|
||||
if in_external_macro(ctx.sess(), param.ident.span) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
|
||||
use rustc_ast::{ptr::P, Crate, Item, ItemKind, MacroDef, ModKind, UseTreeKind, VisibilityKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{edition::Edition, symbol::kw, Span, Symbol};
|
||||
|
||||
@ -37,7 +37,7 @@ declare_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]
|
||||
|
||||
impl EarlyLintPass for SingleComponentPathImports {
|
||||
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
|
||||
if cx.sess.opts.edition < Edition::Edition2018 {
|
||||
if cx.sess().opts.edition < Edition::Edition2018 {
|
||||
return;
|
||||
}
|
||||
check_mod(cx, &krate.items);
|
||||
|
@ -11,7 +11,7 @@ use rustc_hir::{
|
||||
intravisit::{walk_inf, walk_ty, Visitor},
|
||||
Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
|
@ -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()) {
|
||||
|
@ -9,7 +9,7 @@ use rustc_ast::token::{self, LitKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lexer::unescape::{self, EscapeError};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_parse::parser;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::symbol::{kw, Symbol};
|
||||
@ -290,7 +290,7 @@ impl EarlyLintPass for Write {
|
||||
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &MacCall) {
|
||||
fn is_build_script(cx: &EarlyContext<'_>) -> bool {
|
||||
// Cargo sets the crate name for build scripts to `build_script_build`
|
||||
cx.sess
|
||||
cx.sess()
|
||||
.opts
|
||||
.crate_name
|
||||
.as_ref()
|
||||
@ -529,7 +529,7 @@ impl Write {
|
||||
/// ```
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn check_tts<'a>(&self, cx: &EarlyContext<'a>, tts: TokenStream, is_write: bool) -> (Option<StrLit>, Option<Expr>) {
|
||||
let mut parser = parser::Parser::new(&cx.sess.parse_sess, tts, false, None);
|
||||
let mut parser = parser::Parser::new(&cx.sess().parse_sess, tts, false, None);
|
||||
let expr = if is_write {
|
||||
match parser
|
||||
.parse_expr()
|
||||
|
@ -117,25 +117,15 @@ pub fn meets_msrv(msrv: Option<&RustcVersion>, lint_msrv: &RustcVersion) -> bool
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! extract_msrv_attr {
|
||||
(LateContext) => {
|
||||
extract_msrv_attr!(@LateContext, ());
|
||||
};
|
||||
(EarlyContext) => {
|
||||
extract_msrv_attr!(@EarlyContext);
|
||||
};
|
||||
(@$context:ident$(, $call:tt)?) => {
|
||||
($context:ident) => {
|
||||
fn enter_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
|
||||
use $crate::get_unique_inner_attr;
|
||||
match get_unique_inner_attr(cx.sess$($call)?, attrs, "msrv") {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
match $crate::get_unique_inner_attr(sess, attrs, "msrv") {
|
||||
Some(msrv_attr) => {
|
||||
if let Some(msrv) = msrv_attr.value_str() {
|
||||
self.msrv = $crate::parse_msrv(
|
||||
&msrv.to_string(),
|
||||
Some(cx.sess$($call)?),
|
||||
Some(msrv_attr.span),
|
||||
);
|
||||
self.msrv = $crate::parse_msrv(&msrv.to_string(), Some(sess), Some(msrv_attr.span));
|
||||
} else {
|
||||
cx.sess$($call)?.span_err(msrv_attr.span, "bad clippy attribute");
|
||||
sess.span_err(msrv_attr.span, "bad clippy attribute");
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
|
Loading…
Reference in New Issue
Block a user