Skip to content

Commit

Permalink
Auto merge of rust-lang#121625 - Urgau:non-local-defs_recover_perf, r…
Browse files Browse the repository at this point in the history
…=<try>

Recover most of the perf loss of rust-lang#120393

[rust-lang#120393](rust-lang#120393 (comment))

draft for perf
  • Loading branch information
bors committed Feb 29, 2024
2 parents c475e23 + 7c21492 commit 112fbb5
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 41 deletions.
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4097,7 +4097,6 @@ dependencies = [
"rustc_target",
"rustc_trait_selection",
"rustc_type_ir",
"smallvec",
"tracing",
"unicode-security",
]
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_lint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
unicode-security = "0.1.0"
# tidy-alphabetical-end
90 changes: 52 additions & 38 deletions compiler/rustc_lint/src/non_local_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};

use smallvec::{smallvec, SmallVec};

use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
use crate::{LateContext, LateLintPass, LintContext};

Expand Down Expand Up @@ -67,24 +65,23 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
return;
}

let parent = cx.tcx.parent(item.owner_id.def_id.into());
let parent_def_kind = cx.tcx.def_kind(parent);
let parent_opt_item_name = cx.tcx.opt_item_name(parent);

// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in top-level module.
if self.body_depth == 1
&& parent_def_kind == DefKind::Const
&& parent_opt_item_name == Some(kw::Underscore)
{
return;
macro_rules! lazy {
($ident:ident = $closure:expr) => {
let cache = ::std::cell::RefCell::new(None);
let $ident = || *cache.borrow_mut().get_or_insert_with($closure);
};
}

lazy!(parent = || cx.tcx.parent(item.owner_id.def_id.into()));
lazy!(parent_def_kind = || cx.tcx.def_kind(parent()));
lazy!(parent_opt_item_name = || cx.tcx.opt_item_name(parent()));

let cargo_update = || {
let oexpn = item.span.ctxt().outer_expn_data();
if let Some(def_id) = oexpn.macro_def_id
&& let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
&& def_id.krate != LOCAL_CRATE
&& std::env::var_os("CARGO").is_some()
&& rustc_session::utils::was_invoked_from_cargo()
{
Some(NonLocalDefinitionsCargoUpdateNote {
macro_kind: macro_kind.descr(),
Expand Down Expand Up @@ -112,26 +109,24 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
// If that's the case this means that this impl block declaration
// is using local items and so we don't lint on it.

// We also ignore anon-const in item by including the anon-const
// parent as well; and since it's quite uncommon, we use smallvec
// to avoid unnecessary heap allocations.
let local_parents: SmallVec<[DefId; 1]> = if parent_def_kind == DefKind::Const
&& parent_opt_item_name == Some(kw::Underscore)
{
smallvec![parent, cx.tcx.parent(parent)]
} else {
smallvec![parent]
};
lazy!(
parent_is_anon_const = || parent_def_kind() == DefKind::Const
&& parent_opt_item_name() == Some(kw::Underscore)
);
lazy!(
extra_local_parent = || parent_is_anon_const().then(|| cx.tcx.parent(parent()))
);

let self_ty_has_local_parent = match impl_.self_ty.kind {
TyKind::Path(QPath::Resolved(_, ty_path)) => {
path_has_local_parent(ty_path, cx, &*local_parents)
path_has_local_parent(ty_path, cx, &parent, &extra_local_parent)
}
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
path_has_local_parent(
principle_poly_trait_ref.trait_ref.path,
cx,
&*local_parents,
&parent,
&extra_local_parent,
)
}
TyKind::TraitObject([], _, _)
Expand All @@ -151,18 +146,27 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
| TyKind::Err(_) => false,
};

let of_trait_has_local_parent = impl_
.of_trait
.map(|of_trait| path_has_local_parent(of_trait.path, cx, &*local_parents))
.unwrap_or(false);
let of_trait_has_local_parent = self_ty_has_local_parent
|| impl_
.of_trait
.map(|of_trait| {
path_has_local_parent(of_trait.path, cx, &parent, &extra_local_parent)
})
.unwrap_or(false);

// If none of them have a local parent (LOGICAL NOR) this means that
// this impl definition is a non-local definition and so we lint on it.
if !(self_ty_has_local_parent || of_trait_has_local_parent) {
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in
// top-level module.
if self.body_depth == 1 && parent_is_anon_const() {
return;
}

let const_anon = if self.body_depth == 1
&& parent_def_kind == DefKind::Const
&& parent_opt_item_name != Some(kw::Underscore)
&& let Some(parent) = parent.as_local()
&& parent_def_kind() == DefKind::Const
&& parent_opt_item_name() != Some(kw::Underscore)
&& let Some(parent) = parent().as_local()
&& let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
&& let ItemKind::Const(ty, _, _) = item.kind
&& let TyKind::Tup(&[]) = ty.kind
Expand All @@ -177,8 +181,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
item.span,
NonLocalDefinitionsDiag::Impl {
depth: self.body_depth,
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
body_name: parent_opt_item_name
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind(), parent()),
body_name: parent_opt_item_name()
.map(|s| s.to_ident_string())
.unwrap_or_else(|| "<unnameable>".to_string()),
cargo_update: cargo_update(),
Expand All @@ -195,8 +199,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
item.span,
NonLocalDefinitionsDiag::MacroRules {
depth: self.body_depth,
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
body_name: parent_opt_item_name
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind(), parent()),
body_name: parent_opt_item_name()
.map(|s| s.to_ident_string())
.unwrap_or_else(|| "<unnameable>".to_string()),
cargo_update: cargo_update(),
Expand All @@ -217,6 +221,16 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
/// std::convert::PartialEq<Foo<Bar>>
/// ^^^^^^^^^^^^^^^^^^^^^^^
/// ```
fn path_has_local_parent(path: &Path<'_>, cx: &LateContext<'_>, local_parents: &[DefId]) -> bool {
path.res.opt_def_id().is_some_and(|did| local_parents.contains(&cx.tcx.parent(did)))
fn path_has_local_parent(
path: &Path<'_>,
cx: &LateContext<'_>,
parent: impl Fn() -> DefId,
extra_local_parent: impl Fn() -> Option<DefId>,
) -> bool {
path.res.opt_def_id().is_some_and(|did| {
did.is_local() && {
let res_parent = cx.tcx.parent(did);
res_parent == parent() || Some(res_parent) == extra_local_parent()
}
})
}
2 changes: 1 addition & 1 deletion tests/ui/lint/non_local_definitions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ check-pass
//@ edition:2021
//@ aux-build:non_local_macro.rs
//@ rustc-env:CARGO=/usr/bin/cargo
//@ rustc-env:CARGO_CRATE_NAME=non_local_def

#![feature(inline_const)]

Expand Down

0 comments on commit 112fbb5

Please sign in to comment.