Skip to content

Commit 87a3a57

Browse files
committed
Only use the HIR, never tcx.parent
1 parent 7c21492 commit 87a3a57

File tree

3 files changed

+121
-83
lines changed

3 files changed

+121
-83
lines changed

compiler/rustc_lint/src/non_local_def.rs

+70-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
2-
use rustc_span::def_id::{DefId, LOCAL_CRATE};
1+
use rustc_hir::def_id::LocalDefId;
2+
use rustc_hir::{Body, Item, ItemKind, Path, QPath, TyKind};
3+
use rustc_hir::{OwnerId, OwnerNode};
4+
use rustc_span::def_id::LOCAL_CRATE;
5+
use rustc_span::symbol::Ident;
36
use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
47

58
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
@@ -72,9 +75,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
7275
};
7376
}
7477

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+
lazy!(
79+
parent_owner = || {
80+
// Unwrap safety: can only panic when reaching the crate root
81+
// but we made sure above that we are not at crate root.
82+
cx.tcx.hir().parent_owner_iter(item.hir_id()).next().unwrap()
83+
}
84+
);
7885

7986
let cargo_update = || {
8087
let oexpn = item.span.ctxt().outer_expn_data();
@@ -110,22 +117,37 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
110117
// is using local items and so we don't lint on it.
111118

112119
lazy!(
113-
parent_is_anon_const = || parent_def_kind() == DefKind::Const
114-
&& parent_opt_item_name() == Some(kw::Underscore)
120+
parent_owner_is_anon_const = || matches!(
121+
parent_owner().1,
122+
OwnerNode::Item(Item {
123+
ident: Ident { name: kw::Underscore, .. },
124+
kind: ItemKind::Const(..),
125+
..
126+
})
127+
)
115128
);
116129
lazy!(
117-
extra_local_parent = || parent_is_anon_const().then(|| cx.tcx.parent(parent()))
130+
extra_local_parent = || parent_owner_is_anon_const()
131+
.then(|| {
132+
cx.tcx
133+
.hir()
134+
.parent_owner_iter(item.hir_id())
135+
.skip(1)
136+
.next()
137+
.map(|(owner_id, _owner_node)| owner_id.def_id)
138+
})
139+
.flatten()
118140
);
119141

120142
let self_ty_has_local_parent = match impl_.self_ty.kind {
121143
TyKind::Path(QPath::Resolved(_, ty_path)) => {
122-
path_has_local_parent(ty_path, cx, &parent, &extra_local_parent)
144+
path_has_local_parent(ty_path, cx, &parent_owner, &extra_local_parent)
123145
}
124146
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
125147
path_has_local_parent(
126148
principle_poly_trait_ref.trait_ref.path,
127149
cx,
128-
&parent,
150+
&parent_owner,
129151
&extra_local_parent,
130152
)
131153
}
@@ -150,7 +172,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
150172
|| impl_
151173
.of_trait
152174
.map(|of_trait| {
153-
path_has_local_parent(of_trait.path, cx, &parent, &extra_local_parent)
175+
path_has_local_parent(
176+
of_trait.path,
177+
cx,
178+
&parent_owner,
179+
&extra_local_parent,
180+
)
154181
})
155182
.unwrap_or(false);
156183

@@ -159,15 +186,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
159186
if !(self_ty_has_local_parent || of_trait_has_local_parent) {
160187
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in
161188
// top-level module.
162-
if self.body_depth == 1 && parent_is_anon_const() {
189+
if self.body_depth == 1 && parent_owner_is_anon_const() {
163190
return;
164191
}
165192

166193
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)
194+
&& let OwnerNode::Item(item) = parent_owner().1
195+
&& item.ident.name != kw::Underscore
171196
&& let ItemKind::Const(ty, _, _) = item.kind
172197
&& let TyKind::Tup(&[]) = ty.kind
173198
{
@@ -181,9 +206,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
181206
item.span,
182207
NonLocalDefinitionsDiag::Impl {
183208
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())
209+
body_kind_descr: "?" /*cx.tcx.def_kind_descr(parent_def_kind(), parent())*/,
210+
body_name: parent_owner().1
211+
.ident()
212+
.map(|s| s.name.to_ident_string())
187213
.unwrap_or_else(|| "<unnameable>".to_string()),
188214
cargo_update: cargo_update(),
189215
const_anon,
@@ -199,9 +225,11 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
199225
item.span,
200226
NonLocalDefinitionsDiag::MacroRules {
201227
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())
228+
body_kind_descr: "?", /*cx.tcx.def_kind_descr(parent_def_kind(), parent())*/
229+
body_name: parent_owner()
230+
.1
231+
.ident()
232+
.map(|s| s.name.to_ident_string())
205233
.unwrap_or_else(|| "<unnameable>".to_string()),
206234
cargo_update: cargo_update(),
207235
},
@@ -221,16 +249,26 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
221249
/// std::convert::PartialEq<Foo<Bar>>
222250
/// ^^^^^^^^^^^^^^^^^^^^^^^
223251
/// ```
224-
fn path_has_local_parent(
252+
fn path_has_local_parent<'tcx>(
225253
path: &Path<'_>,
226-
cx: &LateContext<'_>,
227-
parent: impl Fn() -> DefId,
228-
extra_local_parent: impl Fn() -> Option<DefId>,
254+
cx: &LateContext<'tcx>,
255+
local_parent: impl Fn() -> (OwnerId, OwnerNode<'tcx>),
256+
extra_local_parent: impl Fn() -> Option<LocalDefId>,
229257
) -> 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-
})
258+
let Some(res_did) = path.res.opt_def_id() else {
259+
return true;
260+
};
261+
let Some(did) = res_did.as_local() else {
262+
return false;
263+
};
264+
265+
let res_parent = {
266+
let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(did) else {
267+
return true;
268+
};
269+
let owner_id = cx.tcx.hir().get_parent_item(hir_id);
270+
owner_id.def_id
271+
};
272+
273+
res_parent == local_parent().0.def_id || Some(res_parent) == extra_local_parent()
236274
}

0 commit comments

Comments
 (0)