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 ;
3
6
use rustc_span:: { sym, symbol:: kw, ExpnKind , MacroKind } ;
4
7
5
8
use crate :: lints:: { NonLocalDefinitionsCargoUpdateNote , NonLocalDefinitionsDiag } ;
@@ -72,9 +75,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
72
75
} ;
73
76
}
74
77
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
+ ) ;
78
85
79
86
let cargo_update = || {
80
87
let oexpn = item. span . ctxt ( ) . outer_expn_data ( ) ;
@@ -110,22 +117,37 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
110
117
// is using local items and so we don't lint on it.
111
118
112
119
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
+ )
115
128
) ;
116
129
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( )
118
140
) ;
119
141
120
142
let self_ty_has_local_parent = match impl_. self_ty . kind {
121
143
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)
123
145
}
124
146
TyKind :: TraitObject ( [ principle_poly_trait_ref, ..] , _, _) => {
125
147
path_has_local_parent (
126
148
principle_poly_trait_ref. trait_ref . path ,
127
149
cx,
128
- & parent ,
150
+ & parent_owner ,
129
151
& extra_local_parent,
130
152
)
131
153
}
@@ -150,7 +172,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
150
172
|| impl_
151
173
. of_trait
152
174
. 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
+ )
154
181
} )
155
182
. unwrap_or ( false ) ;
156
183
@@ -159,15 +186,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
159
186
if !( self_ty_has_local_parent || of_trait_has_local_parent) {
160
187
// Per RFC we (currently) ignore anon-const (`const _: Ty = ...`) in
161
188
// top-level module.
162
- if self . body_depth == 1 && parent_is_anon_const ( ) {
189
+ if self . body_depth == 1 && parent_owner_is_anon_const ( ) {
163
190
return ;
164
191
}
165
192
166
193
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
171
196
&& let ItemKind :: Const ( ty, _, _) = item. kind
172
197
&& let TyKind :: Tup ( & [ ] ) = ty. kind
173
198
{
@@ -181,9 +206,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
181
206
item. span ,
182
207
NonLocalDefinitionsDiag :: Impl {
183
208
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 ( ) )
187
213
. unwrap_or_else ( || "<unnameable>" . to_string ( ) ) ,
188
214
cargo_update : cargo_update ( ) ,
189
215
const_anon,
@@ -199,9 +225,11 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
199
225
item. span ,
200
226
NonLocalDefinitionsDiag :: MacroRules {
201
227
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 ( ) )
205
233
. unwrap_or_else ( || "<unnameable>" . to_string ( ) ) ,
206
234
cargo_update : cargo_update ( ) ,
207
235
} ,
@@ -221,16 +249,26 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
221
249
/// std::convert::PartialEq<Foo<Bar>>
222
250
/// ^^^^^^^^^^^^^^^^^^^^^^^
223
251
/// ```
224
- fn path_has_local_parent (
252
+ fn path_has_local_parent < ' tcx > (
225
253
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 > ,
229
257
) -> 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 ( )
236
274
}
0 commit comments