Skip to content

Commit 8ecf8fb

Browse files
committed
Use nearly exclusively HIR and avoid at all cost unnecessary query calls
1 parent 301ce36 commit 8ecf8fb

File tree

2 files changed

+118
-84
lines changed

2 files changed

+118
-84
lines changed

compiler/rustc_lint/src/non_local_def.rs

+68-34
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
1+
use rustc_hir::{Body, Item, ItemKind, OwnerNode, Path, QPath, TyKind};
22
use rustc_span::def_id::{DefId, LOCAL_CRATE};
3-
use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
4-
5-
use smallvec::{smallvec, SmallVec};
3+
use rustc_span::{sym, symbol::kw, symbol::Ident, ExpnKind, MacroKind};
64

75
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
86
use crate::{LateContext, LateLintPass, LintContext};
@@ -71,15 +69,20 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
7169
return;
7270
}
7371

74-
let parent = cx.tcx.parent(item.owner_id.def_id.into());
75-
let parent_def_kind = cx.tcx.def_kind(parent);
76-
let parent_opt_item_name = cx.tcx.opt_item_name(parent);
72+
let Some((_, parent_node)) = cx.tcx.hir().parent_owner_iter(item.hir_id()).next() else {
73+
return;
74+
};
75+
let parent_is_anon_const = matches!(
76+
parent_node,
77+
OwnerNode::Item(Item {
78+
ident: Ident { name: kw::Underscore, .. },
79+
kind: ItemKind::Const(..),
80+
..
81+
})
82+
);
7783

7884
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in top-level module.
79-
if self.body_depth == 1
80-
&& parent_def_kind == DefKind::Const
81-
&& parent_opt_item_name == Some(kw::Underscore)
82-
{
85+
if self.body_depth == 1 && parent_is_anon_const {
8386
return;
8487
}
8588

@@ -119,23 +122,34 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
119122
// We also ignore anon-const in item by including the anon-const
120123
// parent as well; and since it's quite uncommon, we use smallvec
121124
// to avoid unnecessary heap allocations.
122-
let local_parents: SmallVec<[DefId; 1]> = if parent_def_kind == DefKind::Const
123-
&& parent_opt_item_name == Some(kw::Underscore)
124-
{
125-
smallvec![parent, cx.tcx.parent(parent)]
126-
} else {
127-
smallvec![parent]
125+
let mut local_parent = {
126+
let mut local_parent_cache = None;
127+
move || {
128+
*local_parent_cache
129+
.get_or_insert_with(|| cx.tcx.parent(item.owner_id.to_def_id()))
130+
}
131+
};
132+
let mut extra_local_parent = {
133+
let mut extra_parent_cache = None;
134+
move |did| {
135+
*extra_parent_cache
136+
.get_or_insert_with(|| parent_is_anon_const.then(|| cx.tcx.parent(did)))
137+
}
128138
};
129139

130140
let self_ty_has_local_parent = match impl_.self_ty.kind {
131-
TyKind::Path(QPath::Resolved(_, ty_path)) => {
132-
path_has_local_parent(ty_path, cx, &*local_parents)
133-
}
141+
TyKind::Path(QPath::Resolved(_, ty_path)) => path_has_local_parent(
142+
ty_path,
143+
cx,
144+
&mut local_parent,
145+
&mut extra_local_parent,
146+
),
134147
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
135148
path_has_local_parent(
136149
principle_poly_trait_ref.trait_ref.path,
137150
cx,
138-
&*local_parents,
151+
&mut local_parent,
152+
&mut extra_local_parent,
139153
)
140154
}
141155
TyKind::TraitObject([], _, _)
@@ -157,17 +171,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
157171

158172
let of_trait_has_local_parent = impl_
159173
.of_trait
160-
.map(|of_trait| path_has_local_parent(of_trait.path, cx, &*local_parents))
174+
.map(|of_trait| {
175+
path_has_local_parent(
176+
of_trait.path,
177+
cx,
178+
&mut local_parent,
179+
&mut extra_local_parent,
180+
)
181+
})
161182
.unwrap_or(false);
162183

163184
// If none of them have a local parent (LOGICAL NOR) this means that
164185
// this impl definition is a non-local definition and so we lint on it.
165186
if !(self_ty_has_local_parent || of_trait_has_local_parent) {
166187
let const_anon = if self.body_depth == 1
167-
&& parent_def_kind == DefKind::Const
168-
&& parent_opt_item_name != Some(kw::Underscore)
169-
&& let Some(parent) = parent.as_local()
170-
&& let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
188+
&& let OwnerNode::Item(item) = parent_node
171189
&& let ItemKind::Const(ty, _, _) = item.kind
172190
&& let TyKind::Tup(&[]) = ty.kind
173191
{
@@ -181,9 +199,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
181199
item.span,
182200
NonLocalDefinitionsDiag::Impl {
183201
depth: self.body_depth,
184-
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
185-
body_name: parent_opt_item_name
186-
.map(|s| s.to_ident_string())
202+
body_kind_descr: "?" /* FIXME: cx.tcx.def_kind_descr(parent_def_kind, parent) */,
203+
body_name: parent_node
204+
.ident()
205+
.map(|s| s.name.to_ident_string())
187206
.unwrap_or_else(|| "<unnameable>".to_string()),
188207
cargo_update: cargo_update(),
189208
const_anon,
@@ -199,9 +218,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
199218
item.span,
200219
NonLocalDefinitionsDiag::MacroRules {
201220
depth: self.body_depth,
202-
body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
203-
body_name: parent_opt_item_name
204-
.map(|s| s.to_ident_string())
221+
body_kind_descr: "?" /* FIXME: cx.tcx.def_kind_descr(parent_def_kind, parent) */,
222+
body_name: parent_node
223+
.ident()
224+
.map(|s| s.name.to_ident_string())
205225
.unwrap_or_else(|| "<unnameable>".to_string()),
206226
cargo_update: cargo_update(),
207227
},
@@ -221,6 +241,20 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
221241
/// std::convert::PartialEq<Foo<Bar>>
222242
/// ^^^^^^^^^^^^^^^^^^^^^^^
223243
/// ```
224-
fn path_has_local_parent(path: &Path<'_>, cx: &LateContext<'_>, local_parents: &[DefId]) -> bool {
225-
path.res.opt_def_id().is_some_and(|did| local_parents.contains(&cx.tcx.parent(did)))
244+
fn path_has_local_parent(
245+
path: &Path<'_>,
246+
cx: &LateContext<'_>,
247+
local_parent: &mut impl FnMut() -> DefId,
248+
extra_local_parent: &mut impl FnMut(DefId) -> Option<DefId>,
249+
) -> bool {
250+
if let Some(did) = path.res.opt_def_id() {
251+
if !did.is_local() {
252+
false
253+
} else {
254+
let res_parent = cx.tcx.parent(did);
255+
res_parent == local_parent() || Some(res_parent) == extra_local_parent(local_parent())
256+
}
257+
} else {
258+
true
259+
}
226260
}

0 commit comments

Comments
 (0)