@@ -1328,6 +1328,22 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
1328
1328
}
1329
1329
}
1330
1330
1331
+ // Translate a DefId from the current compilation environment to a DefId
1332
+ // for an external crate.
1333
+ fn reverse_translate_def_id ( cdata : Cmd , did : ast:: DefId ) -> Option < ast:: DefId > {
1334
+ if did. krate == cdata. cnum {
1335
+ return Some ( ast:: DefId { krate : ast:: LOCAL_CRATE , node : did. node } ) ;
1336
+ }
1337
+
1338
+ for ( & local, & global) in & cdata. cnum_map {
1339
+ if global == did. krate {
1340
+ return Some ( ast:: DefId { krate : local, node : did. node } ) ;
1341
+ }
1342
+ }
1343
+
1344
+ None
1345
+ }
1346
+
1331
1347
pub fn each_impl < F > ( cdata : Cmd , mut callback : F ) where
1332
1348
F : FnMut ( ast:: DefId ) ,
1333
1349
{
@@ -1355,19 +1371,35 @@ pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
1355
1371
}
1356
1372
1357
1373
pub fn each_implementation_for_trait < F > ( cdata : Cmd ,
1358
- id : ast:: NodeId ,
1374
+ def_id : ast:: DefId ,
1359
1375
mut callback : F ) where
1360
1376
F : FnMut ( ast:: DefId ) ,
1361
1377
{
1362
- let item_doc = lookup_item ( id, cdata. data ( ) ) ;
1378
+ if cdata. cnum == def_id. krate {
1379
+ let item_doc = lookup_item ( def_id. node , cdata. data ( ) ) ;
1380
+ let _ = reader:: tagged_docs ( item_doc,
1381
+ tag_items_data_item_extension_impl,
1382
+ |impl_doc| {
1383
+ callback ( item_def_id ( impl_doc, cdata) ) ;
1384
+ true
1385
+ } ) ;
1386
+ return ;
1387
+ }
1363
1388
1364
- let _ = reader:: tagged_docs ( item_doc,
1365
- tag_items_data_item_extension_impl,
1366
- |impl_doc| {
1367
- let implementation_def_id = item_def_id ( impl_doc, cdata) ;
1368
- callback ( implementation_def_id) ;
1369
- true
1370
- } ) ;
1389
+ // Do a reverse lookup beforehand to avoid touching the crate_num
1390
+ // hash map in the loop below.
1391
+ if let Some ( crate_local_did) = reverse_translate_def_id ( cdata, def_id) {
1392
+ let def_id_u64 = def_to_u64 ( crate_local_did) ;
1393
+
1394
+ let impls_doc = reader:: get_doc ( rbml:: Doc :: new ( cdata. data ( ) ) , tag_impls) ;
1395
+ let _ = reader:: tagged_docs ( impls_doc, tag_impls_impl, |impl_doc| {
1396
+ let impl_trait = reader:: get_doc ( impl_doc, tag_impls_impl_trait_def_id) ;
1397
+ if reader:: doc_as_u64 ( impl_trait) == def_id_u64 {
1398
+ callback ( item_def_id ( impl_doc, cdata) ) ;
1399
+ }
1400
+ true
1401
+ } ) ;
1402
+ }
1371
1403
}
1372
1404
1373
1405
pub fn get_trait_of_item ( cdata : Cmd , id : ast:: NodeId , tcx : & ty:: ctxt )
0 commit comments