@@ -2113,69 +2113,111 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2113
2113
. expect ( "missing AssociatedItem in metadata" ) ;
2114
2114
}
2115
2115
2116
+ // When the user asks for a given associated item, we
2117
+ // always go ahead and convert all the associated items in
2118
+ // the container. Note that we are also careful only to
2119
+ // ever register a read on the *container* of the assoc
2120
+ // item, not the assoc item itself. This prevents changes
2121
+ // in the details of an item (for example, the type to
2122
+ // which an associated type is bound) from contaminating
2123
+ // those tasks that just need to scan the names of items
2124
+ // and so forth.
2125
+
2116
2126
let id = self . map . as_local_node_id ( def_id) . unwrap ( ) ;
2117
2127
let parent_id = self . map . get_parent ( id) ;
2118
2128
let parent_def_id = self . map . local_def_id ( parent_id) ;
2119
- match self . map . get ( id) {
2120
- ast_map:: NodeTraitItem ( trait_item) => {
2121
- let ( kind, has_self, has_value) = match trait_item. node {
2122
- hir:: MethodTraitItem ( ref sig, ref body) => {
2123
- ( AssociatedKind :: Method , sig. decl . get_self ( ) . is_some ( ) ,
2124
- body. is_some ( ) )
2125
- }
2126
- hir:: ConstTraitItem ( _, ref value) => {
2127
- ( AssociatedKind :: Const , false , value. is_some ( ) )
2128
- }
2129
- hir:: TypeTraitItem ( _, ref ty) => {
2130
- ( AssociatedKind :: Type , false , ty. is_some ( ) )
2131
- }
2132
- } ;
2133
-
2134
- AssociatedItem {
2135
- name : trait_item. name ,
2136
- kind : kind,
2137
- vis : Visibility :: from_hir ( & hir:: Inherited , id, self ) ,
2138
- defaultness : hir:: Defaultness :: Default ,
2139
- has_value : has_value,
2140
- def_id : def_id,
2141
- container : TraitContainer ( parent_def_id) ,
2142
- method_has_self_argument : has_self
2129
+ let parent_item = self . map . expect_item ( parent_id) ;
2130
+ match parent_item. node {
2131
+ hir:: ItemImpl ( .., ref impl_trait_ref, _, ref impl_item_refs) => {
2132
+ for impl_item_ref in impl_item_refs {
2133
+ let assoc_item =
2134
+ self . associated_item_from_impl_item_ref ( parent_def_id,
2135
+ impl_trait_ref. is_some ( ) ,
2136
+ impl_item_ref) ;
2137
+ self . associated_items . borrow_mut ( ) . insert ( assoc_item. def_id , assoc_item) ;
2143
2138
}
2144
2139
}
2145
- ast_map:: NodeImplItem ( impl_item) => {
2146
- let ( kind, has_self) = match impl_item. node {
2147
- hir:: ImplItemKind :: Method ( ref sig, _) => {
2148
- ( AssociatedKind :: Method , sig. decl . get_self ( ) . is_some ( ) )
2149
- }
2150
- hir:: ImplItemKind :: Const ( ..) => ( AssociatedKind :: Const , false ) ,
2151
- hir:: ImplItemKind :: Type ( ..) => ( AssociatedKind :: Type , false )
2152
- } ;
2153
-
2154
- // Trait impl items are always public.
2155
- let public = hir:: Public ;
2156
- let parent_item = self . map . expect_item ( parent_id) ;
2157
- let vis = if let hir:: ItemImpl ( .., Some ( _) , _, _) = parent_item. node {
2158
- & public
2159
- } else {
2160
- & impl_item. vis
2161
- } ;
2162
-
2163
- AssociatedItem {
2164
- name : impl_item. name ,
2165
- kind : kind,
2166
- vis : Visibility :: from_hir ( vis, id, self ) ,
2167
- defaultness : impl_item. defaultness ,
2168
- has_value : true ,
2169
- def_id : def_id,
2170
- container : ImplContainer ( parent_def_id) ,
2171
- method_has_self_argument : has_self
2140
+
2141
+ hir:: ItemTrait ( .., ref trait_items) => {
2142
+ for trait_item in trait_items {
2143
+ let assoc_item =
2144
+ self . associated_item_from_trait_item_ref ( parent_def_id, trait_item) ;
2145
+ self . associated_items . borrow_mut ( ) . insert ( assoc_item. def_id , assoc_item) ;
2172
2146
}
2173
2147
}
2174
- item => bug ! ( "associated_item: {:?} not an associated item" , item)
2148
+
2149
+ ref r => {
2150
+ panic ! ( "unexpected container of associated items: {:?}" , r)
2151
+ }
2175
2152
}
2153
+
2154
+ // memoize wants us to return something, so return
2155
+ // the one we generated for this def-id
2156
+ * self . associated_items . borrow ( ) . get ( & def_id) . unwrap ( )
2176
2157
} )
2177
2158
}
2178
2159
2160
+ fn associated_item_from_trait_item_ref ( self ,
2161
+ parent_def_id : DefId ,
2162
+ trait_item : & hir:: TraitItem )
2163
+ -> AssociatedItem {
2164
+ let def_id = self . map . local_def_id ( trait_item. id ) ;
2165
+
2166
+ let ( kind, has_self, has_value) = match trait_item. node {
2167
+ hir:: MethodTraitItem ( ref sig, ref body) => {
2168
+ ( AssociatedKind :: Method , sig. decl . get_self ( ) . is_some ( ) ,
2169
+ body. is_some ( ) )
2170
+ }
2171
+ hir:: ConstTraitItem ( _, ref value) => {
2172
+ ( AssociatedKind :: Const , false , value. is_some ( ) )
2173
+ }
2174
+ hir:: TypeTraitItem ( _, ref ty) => {
2175
+ ( AssociatedKind :: Type , false , ty. is_some ( ) )
2176
+ }
2177
+ } ;
2178
+
2179
+ AssociatedItem {
2180
+ name : trait_item. name ,
2181
+ kind : kind,
2182
+ vis : Visibility :: from_hir ( & hir:: Inherited , trait_item. id , self ) ,
2183
+ defaultness : hir:: Defaultness :: Default ,
2184
+ has_value : has_value,
2185
+ def_id : def_id,
2186
+ container : TraitContainer ( parent_def_id) ,
2187
+ method_has_self_argument : has_self
2188
+ }
2189
+ }
2190
+
2191
+ fn associated_item_from_impl_item_ref ( self ,
2192
+ parent_def_id : DefId ,
2193
+ from_trait_impl : bool ,
2194
+ impl_item_ref : & hir:: ImplItemRef )
2195
+ -> AssociatedItem {
2196
+ let def_id = self . map . local_def_id ( impl_item_ref. id . node_id ) ;
2197
+ let ( kind, has_self) = match impl_item_ref. kind {
2198
+ hir:: AssociatedItemKind :: Const => ( ty:: AssociatedKind :: Const , false ) ,
2199
+ hir:: AssociatedItemKind :: Method { has_self } => {
2200
+ ( ty:: AssociatedKind :: Method , has_self)
2201
+ }
2202
+ hir:: AssociatedItemKind :: Type => ( ty:: AssociatedKind :: Type , false ) ,
2203
+ } ;
2204
+
2205
+ // Trait impl items are always public.
2206
+ let public = hir:: Public ;
2207
+ let vis = if from_trait_impl { & public } else { & impl_item_ref. vis } ;
2208
+
2209
+ ty:: AssociatedItem {
2210
+ name : impl_item_ref. name ,
2211
+ kind : kind,
2212
+ vis : ty:: Visibility :: from_hir ( vis, impl_item_ref. id . node_id , self ) ,
2213
+ defaultness : impl_item_ref. defaultness ,
2214
+ has_value : true ,
2215
+ def_id : def_id,
2216
+ container : ImplContainer ( parent_def_id) ,
2217
+ method_has_self_argument : has_self
2218
+ }
2219
+ }
2220
+
2179
2221
pub fn associated_item_def_ids ( self , def_id : DefId ) -> Rc < Vec < DefId > > {
2180
2222
self . associated_item_def_ids . memoize ( def_id, || {
2181
2223
if !def_id. is_local ( ) {
@@ -2184,19 +2226,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
2184
2226
2185
2227
let id = self . map . as_local_node_id ( def_id) . unwrap ( ) ;
2186
2228
let item = self . map . expect_item ( id) ;
2187
- match item. node {
2229
+ let vec : Vec < _ > = match item. node {
2188
2230
hir:: ItemTrait ( .., ref trait_items) => {
2189
- Rc :: new ( trait_items. iter ( ) . map ( |trait_item| {
2190
- self . map . local_def_id ( trait_item. id )
2191
- } ) . collect ( ) )
2231
+ trait_items. iter ( )
2232
+ . map ( |trait_item| trait_item. id )
2233
+ . map ( |id| self . map . local_def_id ( id) )
2234
+ . collect ( )
2192
2235
}
2193
2236
hir:: ItemImpl ( .., ref impl_item_refs) => {
2194
- Rc :: new ( impl_item_refs. iter ( ) . map ( |impl_item_ref| {
2195
- self . map . local_def_id ( impl_item_ref. id . node_id )
2196
- } ) . collect ( ) )
2237
+ impl_item_refs. iter ( )
2238
+ . map ( |impl_item_ref| impl_item_ref. id )
2239
+ . map ( |id| self . map . local_def_id ( id. node_id ) )
2240
+ . collect ( )
2197
2241
}
2198
2242
_ => span_bug ! ( item. span, "associated_item_def_ids: not impl or trait" )
2199
- }
2243
+ } ;
2244
+ Rc :: new ( vec)
2200
2245
} )
2201
2246
}
2202
2247
0 commit comments