Optimize incompatible_msrv lint
This limits repeated lookups in pre-checks (to determine if a MSRV should be checked), especially when those require locking up an interner: - The `core` crate is looked up once when creating the lint, instead of comparing the crate name with `sym::core` at every check. - `span.ctxt().outer_expn_data()` is lookup up only once.
This commit is contained in:
parent
7673826138
commit
26911aa32c
2 changed files with 12 additions and 13 deletions
|
|
@ -9,7 +9,7 @@ use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, QPath};
|
|||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::def_id::{CrateNum, DefId};
|
||||
use rustc_span::{ExpnKind, Span, sym};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
@ -83,16 +83,22 @@ pub struct IncompatibleMsrv {
|
|||
msrv: Msrv,
|
||||
availability_cache: FxHashMap<(DefId, bool), Availability>,
|
||||
check_in_tests: bool,
|
||||
core_crate: Option<CrateNum>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]);
|
||||
|
||||
impl IncompatibleMsrv {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
|
||||
Self {
|
||||
msrv: conf.msrv,
|
||||
availability_cache: FxHashMap::default(),
|
||||
check_in_tests: conf.check_incompatible_msrv_in_tests,
|
||||
core_crate: tcx
|
||||
.crates(())
|
||||
.iter()
|
||||
.find(|krate| tcx.crate_name(**krate) == sym::core)
|
||||
.copied(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,23 +146,16 @@ impl IncompatibleMsrv {
|
|||
// We don't check local items since their MSRV is supposed to always be valid.
|
||||
return;
|
||||
}
|
||||
if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = span.ctxt().outer_expn_data().kind {
|
||||
let expn_data = span.ctxt().outer_expn_data();
|
||||
if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = expn_data.kind {
|
||||
// Desugared expressions get to cheat and stability is ignored.
|
||||
// Intentionally not using `.from_expansion()`, since we do still care about macro expansions
|
||||
return;
|
||||
}
|
||||
|
||||
// Functions coming from `core` while expanding a macro such as `assert*!()` get to cheat too: the
|
||||
// macros may have existed prior to the checked MSRV, but their expansion with a recent compiler
|
||||
// might use recent functions or methods. Compiling with an older compiler would not use those.
|
||||
if span.from_expansion()
|
||||
&& cx.tcx.crate_name(def_id.krate) == sym::core
|
||||
&& span
|
||||
.ctxt()
|
||||
.outer_expn_data()
|
||||
.macro_def_id
|
||||
.is_some_and(|def_id| cx.tcx.crate_name(def_id.krate) == sym::core)
|
||||
{
|
||||
if Some(def_id.krate) == self.core_crate && expn_data.macro_def_id.map(|did| did.krate) == self.core_crate {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -797,7 +797,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
|
|||
store.register_late_pass(|_| Box::<unconditional_recursion::UnconditionalRecursion>::default());
|
||||
store.register_late_pass(move |_| Box::new(pub_underscore_fields::PubUnderscoreFields::new(conf)));
|
||||
store.register_late_pass(move |_| Box::new(missing_const_for_thread_local::MissingConstForThreadLocal::new(conf)));
|
||||
store.register_late_pass(move |_| Box::new(incompatible_msrv::IncompatibleMsrv::new(conf)));
|
||||
store.register_late_pass(move |tcx| Box::new(incompatible_msrv::IncompatibleMsrv::new(tcx, conf)));
|
||||
store.register_late_pass(|_| Box::new(to_string_trait_impl::ToStringTraitImpl));
|
||||
store.register_early_pass(|| Box::new(multiple_bound_locations::MultipleBoundLocations));
|
||||
store.register_late_pass(move |_| Box::new(assigning_clones::AssigningClones::new(conf)));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue