Skip to content

Commit 8df3e4e

Browse files
committed
Move completely away from cx.tcx.parent and only use the HIR
1 parent 2fc98d7 commit 8df3e4e

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

compiler/rustc_lint/src/non_local_def.rs

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use rustc_hir::{Body, Item, ItemKind, OwnerNode, 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, OwnerId, OwnerNode, Path, QPath, TyKind};
3+
use rustc_span::def_id::LOCAL_CRATE;
34
use rustc_span::{sym, symbol::kw, symbol::Ident, ExpnKind, MacroKind};
45

56
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
@@ -65,11 +66,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
6566
return;
6667
}
6768

68-
let mut parent_node = {
69-
let mut parent_node_cache = None;
69+
let mut parent_owner = {
70+
let mut parent_owner_cache = None;
7071
move || {
71-
*parent_node_cache.get_or_insert_with(|| {
72-
cx.tcx.hir().parent_owner_iter(item.hir_id()).next().unwrap().1
72+
*parent_owner_cache.get_or_insert_with(|| {
73+
// Unwrap safety: can only panic when reaching the crate root
74+
// but we made sure above that we are not at crate root.
75+
cx.tcx.hir().parent_owner_iter(item.hir_id()).next().unwrap()
7376
})
7477
}
7578
};
@@ -107,12 +110,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
107110
// If that's the case this means that this impl block declaration
108111
// is using local items and so we don't lint on it.
109112

110-
let mut parent_node_is_anon_const = {
111-
let mut parent_node_is_anon_const = None;
113+
let mut parent_owner_is_anon_const = {
114+
let mut parent_owner_is_anon_const = None;
112115
move || {
113-
*parent_node_is_anon_const.get_or_insert_with(|| {
116+
*parent_owner_is_anon_const.get_or_insert_with(|| {
114117
matches!(
115-
parent_node(),
118+
parent_owner().1,
116119
OwnerNode::Item(Item {
117120
ident: Ident { name: kw::Underscore, .. },
118121
kind: ItemKind::Const(..),
@@ -122,18 +125,20 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
122125
})
123126
}
124127
};
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-
};
132128
let mut extra_local_parent = {
133129
let mut extra_parent_cache = None;
134-
move |did| {
130+
move || {
135131
*extra_parent_cache.get_or_insert_with(|| {
136-
parent_node_is_anon_const().then(|| cx.tcx.parent(did))
132+
parent_owner_is_anon_const()
133+
.then(|| {
134+
cx.tcx
135+
.hir()
136+
.parent_owner_iter(item.hir_id())
137+
.skip(1)
138+
.next()
139+
.map(|(owner_id, _owner_node)| owner_id.def_id)
140+
})
141+
.flatten()
137142
})
138143
}
139144
};
@@ -142,14 +147,14 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
142147
TyKind::Path(QPath::Resolved(_, ty_path)) => path_has_local_parent(
143148
ty_path,
144149
cx,
145-
&mut local_parent,
150+
&mut parent_owner,
146151
&mut extra_local_parent,
147152
),
148153
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
149154
path_has_local_parent(
150155
principle_poly_trait_ref.trait_ref.path,
151156
cx,
152-
&mut local_parent,
157+
&mut parent_owner,
153158
&mut extra_local_parent,
154159
)
155160
}
@@ -176,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
176181
path_has_local_parent(
177182
of_trait.path,
178183
cx,
179-
&mut local_parent,
184+
&mut parent_owner,
180185
&mut extra_local_parent,
181186
)
182187
})
@@ -186,12 +191,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
186191
// this impl definition is a non-local definition and so we lint on it.
187192
if !(self_ty_has_local_parent || of_trait_has_local_parent) {
188193
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in top-level module.
189-
if parent_node_is_anon_const() && self.body_depth == 1 {
194+
if parent_owner_is_anon_const() && self.body_depth == 1 {
190195
return;
191196
}
192197

193198
let const_anon = if self.body_depth == 1
194-
&& let OwnerNode::Item(item) = parent_node()
199+
&& let OwnerNode::Item(item) = parent_owner().1
195200
&& let ItemKind::Const(ty, _, _) = item.kind
196201
&& let TyKind::Tup(&[]) = ty.kind
197202
{
@@ -200,13 +205,15 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
200205
None
201206
};
202207

208+
let parent_owner = parent_owner().1;
209+
203210
cx.emit_span_lint(
204211
NON_LOCAL_DEFINITIONS,
205212
item.span,
206213
NonLocalDefinitionsDiag::Impl {
207214
depth: self.body_depth,
208215
body_kind_descr: "?" /* FIXME: cx.tcx.def_kind_descr(parent_def_kind, parent) */,
209-
body_name: parent_node()
216+
body_name: parent_owner
210217
.ident()
211218
.map(|s| s.name.to_ident_string())
212219
.unwrap_or_else(|| "<unnameable>".to_string()),
@@ -219,13 +226,15 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
219226
ItemKind::Macro(_macro, MacroKind::Bang)
220227
if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
221228
{
229+
let parent_owner = parent_owner().1;
230+
222231
cx.emit_span_lint(
223232
NON_LOCAL_DEFINITIONS,
224233
item.span,
225234
NonLocalDefinitionsDiag::MacroRules {
226235
depth: self.body_depth,
227236
body_kind_descr: "?" /* FIXME: cx.tcx.def_kind_descr(parent_def_kind, parent) */,
228-
body_name: parent_node()
237+
body_name: parent_owner
229238
.ident()
230239
.map(|s| s.name.to_ident_string())
231240
.unwrap_or_else(|| "<unnameable>".to_string()),
@@ -247,20 +256,22 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
247256
/// std::convert::PartialEq<Foo<Bar>>
248257
/// ^^^^^^^^^^^^^^^^^^^^^^^
249258
/// ```
250-
fn path_has_local_parent(
259+
fn path_has_local_parent<'tcx>(
251260
path: &Path<'_>,
252-
cx: &LateContext<'_>,
253-
local_parent: &mut impl FnMut() -> DefId,
254-
extra_local_parent: &mut impl FnMut(DefId) -> Option<DefId>,
261+
cx: &LateContext<'tcx>,
262+
local_parent: &mut impl FnMut() -> (OwnerId, OwnerNode<'tcx>),
263+
extra_local_parent: &mut impl FnMut() -> Option<LocalDefId>,
255264
) -> bool {
256-
if let Some(did) = path.res.opt_def_id() {
257-
if !did.is_local() {
258-
false
259-
} else {
260-
let res_parent = cx.tcx.parent(did);
261-
res_parent == local_parent() || Some(res_parent) == extra_local_parent(local_parent())
262-
}
263-
} else {
264-
true
265-
}
265+
let Some(res_did) = path.res.opt_def_id() else {
266+
return true;
267+
};
268+
let Some(did) = res_did.as_local() else {
269+
return false;
270+
};
271+
let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(did) else {
272+
return true;
273+
};
274+
let owner_id = cx.tcx.hir().get_parent_item(hir_id);
275+
let res_parent = owner_id.def_id;
276+
res_parent == local_parent().0.def_id || Some(res_parent) == extra_local_parent()
266277
}

0 commit comments

Comments
 (0)