@@ -6,6 +6,8 @@ use rustc_hir::{self as hir, ItemKind};
66use rustc_middle:: query:: Providers ;
77use rustc_middle:: ty:: { self , ImplTraitInTraitData , TyCtxt } ;
88use rustc_middle:: { bug, span_bug} ;
9+ use rustc_span:: Ident ;
10+ use rustc_span:: symbol:: kw;
911
1012pub ( crate ) fn provide ( providers : & mut Providers ) {
1113 * providers = Providers {
@@ -66,46 +68,33 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId>
6668}
6769
6870fn 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+ }
9479
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 , .. } ) , ..] )
10082}
10183
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+ }
10998 } ;
11099
111100 ty:: AssocItem {
@@ -116,19 +105,23 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
116105 }
117106}
118107
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+ }
126119 } ;
127120
128121 ty:: AssocItem {
129122 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 ,
132125 container : ty:: AssocItemContainer :: Impl ,
133126 }
134127}
@@ -196,17 +189,13 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
196189 return None ;
197190 }
198191 let did = item. id . owner_id . def_id . to_def_id ( ) ;
192+ let item = tcx. hir_impl_item ( item. id ) ;
199193 let Some ( trait_item_def_id) = item. trait_item_def_id else {
200194 return Some ( ( did, vec ! [ ] ) ) ;
201195 } ;
202196 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 ( )
210199 } ) ;
211200 Some ( ( did, iter. collect ( ) ) )
212201 } )
@@ -285,20 +274,20 @@ fn associated_type_for_impl_trait_in_trait(
285274
286275/// Given an `trait_assoc_def_id` corresponding to an associated item synthesized
287276/// 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
289278/// that the `impl Trait` comes from, synthesize an associated type for that `impl Trait`
290279/// that inherits properties that we infer from the method and the associated type.
291280fn associated_type_for_impl_trait_in_impl (
292281 tcx : TyCtxt < ' _ > ,
293282 trait_assoc_def_id : DefId ,
294- impl_fn_def_id : LocalDefId ,
283+ impl_fn : & hir :: ImplItem < ' _ > ,
295284 disambiguator : & mut DisambiguatorState ,
296285) -> 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 ) ;
298287
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 ) ,
302291 hir:: FnRetTy :: Return ( ty) => ty. span ,
303292 } ;
304293
@@ -329,7 +318,7 @@ fn associated_type_for_impl_trait_in_impl(
329318 impl_assoc_ty. associated_item ( ty:: AssocItem {
330319 kind : ty:: AssocKind :: Type {
331320 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 ( ) ,
333322 } ) ,
334323 } ,
335324 def_id,
@@ -338,10 +327,10 @@ fn associated_type_for_impl_trait_in_impl(
338327 } ) ;
339328
340329 // 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 ) ) ;
342331
343332 // 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 ) ) ;
345334
346335 // Copy generics_of the trait's associated item but the impl as the parent.
347336 // FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars
0 commit comments