Skip to content

Commit 112fbb5

Browse files
committed
Auto merge of rust-lang#121625 - Urgau:non-local-defs_recover_perf, r=<try>
Recover most of the perf loss of rust-lang#120393 [rust-lang#120393](rust-lang#120393 (comment)) draft for perf
2 parents c475e23 + 7c21492 commit 112fbb5

File tree

4 files changed

+53
-41
lines changed

4 files changed

+53
-41
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -4097,7 +4097,6 @@ dependencies = [
40974097
"rustc_target",
40984098
"rustc_trait_selection",
40994099
"rustc_type_ir",
4100-
"smallvec",
41014100
"tracing",
41024101
"unicode-security",
41034102
]

compiler/rustc_lint/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ rustc_span = { path = "../rustc_span" }
2323
rustc_target = { path = "../rustc_target" }
2424
rustc_trait_selection = { path = "../rustc_trait_selection" }
2525
rustc_type_ir = { path = "../rustc_type_ir" }
26-
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
2726
tracing = "0.1"
2827
unicode-security = "0.1.0"
2928
# tidy-alphabetical-end

compiler/rustc_lint/src/non_local_def.rs

+52-38
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
22
use rustc_span::def_id::{DefId, LOCAL_CRATE};
33
use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
44

5-
use smallvec::{smallvec, SmallVec};
6-
75
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
86
use crate::{LateContext, LateLintPass, LintContext};
97

@@ -67,24 +65,23 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
6765
return;
6866
}
6967

70-
let parent = cx.tcx.parent(item.owner_id.def_id.into());
71-
let parent_def_kind = cx.tcx.def_kind(parent);
72-
let parent_opt_item_name = cx.tcx.opt_item_name(parent);
73-
74-
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in top-level module.
75-
if self.body_depth == 1
76-
&& parent_def_kind == DefKind::Const
77-
&& parent_opt_item_name == Some(kw::Underscore)
78-
{
79-
return;
68+
macro_rules! lazy {
69+
($ident:ident = $closure:expr) => {
70+
let cache = ::std::cell::RefCell::new(None);
71+
let $ident = || *cache.borrow_mut().get_or_insert_with($closure);
72+
};
8073
}
8174

75+
lazy!(parent = || cx.tcx.parent(item.owner_id.def_id.into()));
76+
lazy!(parent_def_kind = || cx.tcx.def_kind(parent()));
77+
lazy!(parent_opt_item_name = || cx.tcx.opt_item_name(parent()));
78+
8279
let cargo_update = || {
8380
let oexpn = item.span.ctxt().outer_expn_data();
8481
if let Some(def_id) = oexpn.macro_def_id
8582
&& let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
8683
&& def_id.krate != LOCAL_CRATE
87-
&& std::env::var_os("CARGO").is_some()
84+
&& rustc_session::utils::was_invoked_from_cargo()
8885
{
8986
Some(NonLocalDefinitionsCargoUpdateNote {
9087
macro_kind: macro_kind.descr(),
@@ -112,26 +109,24 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
112109
// If that's the case this means that this impl block declaration
113110
// is using local items and so we don't lint on it.
114111

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

126120
let self_ty_has_local_parent = match impl_.self_ty.kind {
127121
TyKind::Path(QPath::Resolved(_, ty_path)) => {
128-
path_has_local_parent(ty_path, cx, &*local_parents)
122+
path_has_local_parent(ty_path, cx, &parent, &extra_local_parent)
129123
}
130124
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
131125
path_has_local_parent(
132126
principle_poly_trait_ref.trait_ref.path,
133127
cx,
134-
&*local_parents,
128+
&parent,
129+
&extra_local_parent,
135130
)
136131
}
137132
TyKind::TraitObject([], _, _)
@@ -151,18 +146,27 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
151146
| TyKind::Err(_) => false,
152147
};
153148

154-
let of_trait_has_local_parent = impl_
155-
.of_trait
156-
.map(|of_trait| path_has_local_parent(of_trait.path, cx, &*local_parents))
157-
.unwrap_or(false);
149+
let of_trait_has_local_parent = self_ty_has_local_parent
150+
|| impl_
151+
.of_trait
152+
.map(|of_trait| {
153+
path_has_local_parent(of_trait.path, cx, &parent, &extra_local_parent)
154+
})
155+
.unwrap_or(false);
158156

159157
// If none of them have a local parent (LOGICAL NOR) this means that
160158
// this impl definition is a non-local definition and so we lint on it.
161159
if !(self_ty_has_local_parent || of_trait_has_local_parent) {
160+
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in
161+
// top-level module.
162+
if self.body_depth == 1 && parent_is_anon_const() {
163+
return;
164+
}
165+
162166
let const_anon = if self.body_depth == 1
163-
&& parent_def_kind == DefKind::Const
164-
&& parent_opt_item_name != Some(kw::Underscore)
165-
&& let Some(parent) = parent.as_local()
167+
&& parent_def_kind() == DefKind::Const
168+
&& parent_opt_item_name() != Some(kw::Underscore)
169+
&& let Some(parent) = parent().as_local()
166170
&& let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
167171
&& let ItemKind::Const(ty, _, _) = item.kind
168172
&& let TyKind::Tup(&[]) = ty.kind
@@ -177,8 +181,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
177181
item.span,
178182
NonLocalDefinitionsDiag::Impl {
179183
depth: self.body_depth,
180-
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
181-
body_name: parent_opt_item_name
184+
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind(), parent()),
185+
body_name: parent_opt_item_name()
182186
.map(|s| s.to_ident_string())
183187
.unwrap_or_else(|| "<unnameable>".to_string()),
184188
cargo_update: cargo_update(),
@@ -195,8 +199,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
195199
item.span,
196200
NonLocalDefinitionsDiag::MacroRules {
197201
depth: self.body_depth,
198-
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
199-
body_name: parent_opt_item_name
202+
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind(), parent()),
203+
body_name: parent_opt_item_name()
200204
.map(|s| s.to_ident_string())
201205
.unwrap_or_else(|| "<unnameable>".to_string()),
202206
cargo_update: cargo_update(),
@@ -217,6 +221,16 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
217221
/// std::convert::PartialEq<Foo<Bar>>
218222
/// ^^^^^^^^^^^^^^^^^^^^^^^
219223
/// ```
220-
fn path_has_local_parent(path: &Path<'_>, cx: &LateContext<'_>, local_parents: &[DefId]) -> bool {
221-
path.res.opt_def_id().is_some_and(|did| local_parents.contains(&cx.tcx.parent(did)))
224+
fn path_has_local_parent(
225+
path: &Path<'_>,
226+
cx: &LateContext<'_>,
227+
parent: impl Fn() -> DefId,
228+
extra_local_parent: impl Fn() -> Option<DefId>,
229+
) -> bool {
230+
path.res.opt_def_id().is_some_and(|did| {
231+
did.is_local() && {
232+
let res_parent = cx.tcx.parent(did);
233+
res_parent == parent() || Some(res_parent) == extra_local_parent()
234+
}
235+
})
222236
}

tests/ui/lint/non_local_definitions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ check-pass
22
//@ edition:2021
33
//@ aux-build:non_local_macro.rs
4-
//@ rustc-env:CARGO=/usr/bin/cargo
4+
//@ rustc-env:CARGO_CRATE_NAME=non_local_def
55

66
#![feature(inline_const)]
77

0 commit comments

Comments
 (0)