@@ -6,6 +6,8 @@ use rustc_hir::{self as hir, ItemKind};
6
6
use rustc_middle:: query:: Providers ;
7
7
use rustc_middle:: ty:: { self , ImplTraitInTraitData , TyCtxt } ;
8
8
use rustc_middle:: { bug, span_bug} ;
9
+ use rustc_span:: Ident ;
10
+ use rustc_span:: symbol:: kw;
9
11
10
12
pub ( crate ) fn provide ( providers : & mut Providers ) {
11
13
* providers = Providers {
@@ -66,46 +68,33 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId>
66
68
}
67
69
68
70
fn associated_item ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> ty:: AssocItem {
69
- let id = tcx. local_def_id_to_hir_id ( def_id) ;
70
- let parent_def_id = tcx. hir_get_parent_item ( id) ;
71
- let parent_item = tcx. hir_expect_item ( parent_def_id. def_id ) ;
72
- match parent_item. kind {
73
- hir:: ItemKind :: Impl ( impl_) => {
74
- if let Some ( impl_item_ref) = impl_. items . iter ( ) . find ( |i| i. id . owner_id . def_id == def_id)
75
- {
76
- let assoc_item = associated_item_from_impl_item_ref ( impl_item_ref) ;
77
- debug_assert_eq ! ( assoc_item. def_id. expect_local( ) , def_id) ;
78
- return assoc_item;
79
- }
80
- }
81
-
82
- hir:: ItemKind :: Trait ( .., trait_item_refs) => {
83
- if let Some ( trait_item_ref) =
84
- trait_item_refs. iter ( ) . find ( |i| i. id . owner_id . def_id == def_id)
85
- {
86
- let assoc_item = associated_item_from_trait_item_ref ( trait_item_ref) ;
87
- debug_assert_eq ! ( assoc_item. def_id. expect_local( ) , def_id) ;
88
- return assoc_item;
89
- }
90
- }
91
-
92
- _ => { }
93
- }
71
+ let assoc_item = match tcx. hir_node_by_def_id ( def_id) {
72
+ hir:: Node :: TraitItem ( ti) => associated_item_from_trait_item ( tcx, ti) ,
73
+ hir:: Node :: ImplItem ( ii) => associated_item_from_impl_item ( tcx, ii) ,
74
+ node => span_bug ! ( tcx. def_span( def_id) , "impl item or item not found: {:?}" , node, ) ,
75
+ } ;
76
+ debug_assert_eq ! ( assoc_item. def_id. expect_local( ) , def_id) ;
77
+ assoc_item
78
+ }
94
79
95
- span_bug ! (
96
- parent_item. span,
97
- "unexpected parent of trait or impl item or item not found: {:?}" ,
98
- parent_item. kind
99
- )
80
+ fn fn_has_self_parameter ( tcx : TyCtxt < ' _ > , owner_id : hir:: OwnerId ) -> bool {
81
+ matches ! ( tcx. fn_arg_idents( owner_id. def_id) , [ Some ( Ident { name: kw:: SelfLower , .. } ) , ..] )
100
82
}
101
83
102
- fn associated_item_from_trait_item_ref ( trait_item_ref : & hir:: TraitItemRef ) -> ty:: AssocItem {
103
- let owner_id = trait_item_ref. id . owner_id ;
104
- let name = trait_item_ref. ident . name ;
105
- let kind = match trait_item_ref. kind {
106
- hir:: AssocItemKind :: Const => ty:: AssocKind :: Const { name } ,
107
- hir:: AssocItemKind :: Fn { has_self } => ty:: AssocKind :: Fn { name, has_self } ,
108
- hir:: AssocItemKind :: Type => ty:: AssocKind :: Type { data : ty:: AssocTypeData :: Normal ( name) } ,
84
+ fn associated_item_from_trait_item (
85
+ tcx : TyCtxt < ' _ > ,
86
+ trait_item : & hir:: TraitItem < ' _ > ,
87
+ ) -> ty:: AssocItem {
88
+ let owner_id = trait_item. owner_id ;
89
+ let name = trait_item. ident . name ;
90
+ let kind = match trait_item. kind {
91
+ hir:: TraitItemKind :: Const { .. } => ty:: AssocKind :: Const { name } ,
92
+ hir:: TraitItemKind :: Fn { .. } => {
93
+ ty:: AssocKind :: Fn { name, has_self : fn_has_self_parameter ( tcx, owner_id) }
94
+ }
95
+ hir:: TraitItemKind :: Type { .. } => {
96
+ ty:: AssocKind :: Type { data : ty:: AssocTypeData :: Normal ( name) }
97
+ }
109
98
} ;
110
99
111
100
ty:: AssocItem {
@@ -116,19 +105,23 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
116
105
}
117
106
}
118
107
119
- fn associated_item_from_impl_item_ref ( impl_item_ref : & hir:: ImplItemRef ) -> ty:: AssocItem {
120
- let def_id = impl_item_ref. id . owner_id ;
121
- let name = impl_item_ref. ident . name ;
122
- let kind = match impl_item_ref. kind {
123
- hir:: AssocItemKind :: Const => ty:: AssocKind :: Const { name } ,
124
- hir:: AssocItemKind :: Fn { has_self } => ty:: AssocKind :: Fn { name, has_self } ,
125
- hir:: AssocItemKind :: Type => ty:: AssocKind :: Type { data : ty:: AssocTypeData :: Normal ( name) } ,
108
+ fn associated_item_from_impl_item ( tcx : TyCtxt < ' _ > , impl_item : & hir:: ImplItem < ' _ > ) -> ty:: AssocItem {
109
+ let owner_id = impl_item. owner_id ;
110
+ let name = impl_item. ident . name ;
111
+ let kind = match impl_item. kind {
112
+ hir:: ImplItemKind :: Const { .. } => ty:: AssocKind :: Const { name } ,
113
+ hir:: ImplItemKind :: Fn { .. } => {
114
+ ty:: AssocKind :: Fn { name, has_self : fn_has_self_parameter ( tcx, owner_id) }
115
+ }
116
+ hir:: ImplItemKind :: Type { .. } => {
117
+ ty:: AssocKind :: Type { data : ty:: AssocTypeData :: Normal ( name) }
118
+ }
126
119
} ;
127
120
128
121
ty:: AssocItem {
129
122
kind,
130
- def_id : def_id . to_def_id ( ) ,
131
- trait_item_def_id : impl_item_ref . trait_item_def_id ,
123
+ def_id : owner_id . to_def_id ( ) ,
124
+ trait_item_def_id : impl_item . trait_item_def_id ,
132
125
container : ty:: AssocItemContainer :: Impl ,
133
126
}
134
127
}
@@ -196,17 +189,13 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
196
189
return None ;
197
190
}
198
191
let did = item. id . owner_id . def_id . to_def_id ( ) ;
192
+ let item = tcx. hir_impl_item ( item. id ) ;
199
193
let Some ( trait_item_def_id) = item. trait_item_def_id else {
200
194
return Some ( ( did, vec ! [ ] ) ) ;
201
195
} ;
202
196
let iter = in_trait_def[ & trait_item_def_id] . iter ( ) . map ( |& id| {
203
- associated_type_for_impl_trait_in_impl (
204
- tcx,
205
- id,
206
- item. id . owner_id . def_id ,
207
- disambiguator,
208
- )
209
- . to_def_id ( )
197
+ associated_type_for_impl_trait_in_impl ( tcx, id, item, disambiguator)
198
+ . to_def_id ( )
210
199
} ) ;
211
200
Some ( ( did, iter. collect ( ) ) )
212
201
} )
@@ -285,20 +274,20 @@ fn associated_type_for_impl_trait_in_trait(
285
274
286
275
/// Given an `trait_assoc_def_id` corresponding to an associated item synthesized
287
276
/// from an `impl Trait` in an associated function from a trait, and an
288
- /// `impl_fn_def_id ` that represents an implementation of the associated function
277
+ /// `impl_fn ` that represents an implementation of the associated function
289
278
/// that the `impl Trait` comes from, synthesize an associated type for that `impl Trait`
290
279
/// that inherits properties that we infer from the method and the associated type.
291
280
fn associated_type_for_impl_trait_in_impl (
292
281
tcx : TyCtxt < ' _ > ,
293
282
trait_assoc_def_id : DefId ,
294
- impl_fn_def_id : LocalDefId ,
283
+ impl_fn : & hir :: ImplItem < ' _ > ,
295
284
disambiguator : & mut DisambiguatorState ,
296
285
) -> LocalDefId {
297
- let impl_local_def_id = tcx. local_parent ( impl_fn_def_id ) ;
286
+ let impl_local_def_id = tcx. local_parent ( impl_fn . owner_id . def_id ) ;
298
287
299
- let decl = tcx . hir_node_by_def_id ( impl_fn_def_id ) . fn_decl ( ) . expect ( "expected decl" ) ;
300
- let span = match decl. output {
301
- hir:: FnRetTy :: DefaultReturn ( _) => tcx. def_span ( impl_fn_def_id ) ,
288
+ let hir :: ImplItemKind :: Fn ( fn_sig , _ ) = impl_fn . kind else { bug ! ( "expected decl" ) } ;
289
+ let span = match fn_sig . decl . output {
290
+ hir:: FnRetTy :: DefaultReturn ( _) => tcx. def_span ( impl_fn . owner_id ) ,
302
291
hir:: FnRetTy :: Return ( ty) => ty. span ,
303
292
} ;
304
293
@@ -329,7 +318,7 @@ fn associated_type_for_impl_trait_in_impl(
329
318
impl_assoc_ty. associated_item ( ty:: AssocItem {
330
319
kind : ty:: AssocKind :: Type {
331
320
data : ty:: AssocTypeData :: Rpitit ( ImplTraitInTraitData :: Impl {
332
- fn_def_id : impl_fn_def_id . to_def_id ( ) ,
321
+ fn_def_id : impl_fn . owner_id . to_def_id ( ) ,
333
322
} ) ,
334
323
} ,
335
324
def_id,
@@ -338,10 +327,10 @@ fn associated_type_for_impl_trait_in_impl(
338
327
} ) ;
339
328
340
329
// Copy visility of the containing function.
341
- impl_assoc_ty. visibility ( tcx. visibility ( impl_fn_def_id ) ) ;
330
+ impl_assoc_ty. visibility ( tcx. visibility ( impl_fn . owner_id ) ) ;
342
331
343
332
// Copy defaultness of the containing function.
344
- impl_assoc_ty. defaultness ( tcx. defaultness ( impl_fn_def_id ) ) ;
333
+ impl_assoc_ty. defaultness ( tcx. defaultness ( impl_fn . owner_id ) ) ;
345
334
346
335
// Copy generics_of the trait's associated item but the impl as the parent.
347
336
// FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars
0 commit comments