@@ -27,6 +27,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2727use rustc_middle:: mir:: { self , Body , Promoted } ;
2828use rustc_middle:: thir;
2929use rustc_middle:: ty:: codec:: TyDecoder ;
30+ use rustc_middle:: ty:: fast_reject:: SimplifiedType ;
3031use rustc_middle:: ty:: { self , Ty , TyCtxt , Visibility } ;
3132use rustc_serialize:: { opaque, Decodable , Decoder } ;
3233use rustc_session:: cstore:: {
@@ -92,8 +93,7 @@ crate struct CrateMetadata {
9293 /// Trait impl data.
9394 /// FIXME: Used only from queries and can use query cache,
9495 /// so pre-decoding can probably be avoided.
95- trait_impls :
96- FxHashMap < ( u32 , DefIndex ) , Lazy < [ ( DefIndex , Option < ty:: fast_reject:: SimplifiedType > ) ] > > ,
96+ trait_impls : FxHashMap < ( u32 , DefIndex ) , Lazy < [ ( DefIndex , Option < SimplifiedType > ) ] > > ,
9797 /// Proc macro descriptions for this crate, if it's a proc macro crate.
9898 raw_proc_macros : Option < & ' static [ ProcMacro ] > ,
9999 /// Source maps for code from the crate.
@@ -722,25 +722,24 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
722722 & self . raw_proc_macros . unwrap ( ) [ pos]
723723 }
724724
725- fn try_item_ident ( & self , item_index : DefIndex , sess : & Session ) -> Result < Ident , String > {
726- let name = self
727- . def_key ( item_index)
728- . disambiguated_data
729- . data
730- . get_opt_name ( )
731- . ok_or_else ( || format ! ( "Missing opt name for {:?}" , item_index) ) ?;
732- let span = self
733- . root
734- . tables
735- . ident_span
736- . get ( self , item_index)
737- . ok_or_else ( || format ! ( "Missing ident span for {:?} ({:?})" , name, item_index) ) ?
738- . decode ( ( self , sess) ) ;
739- Ok ( Ident :: new ( name, span) )
725+ fn opt_item_ident ( & self , item_index : DefIndex , sess : & Session ) -> Option < Ident > {
726+ let name = self . def_key ( item_index) . disambiguated_data . data . get_opt_name ( ) ?;
727+ let span = match self . root . tables . ident_span . get ( self , item_index) {
728+ Some ( lazy_span) => lazy_span. decode ( ( self , sess) ) ,
729+ None => {
730+ // FIXME: this weird case of a name with no span is specific to `extern crate`
731+ // items, which are supposed to be treated like `use` items and only be encoded
732+ // to metadata as `Export`s, return `None` because that's what all the callers
733+ // expect in this case.
734+ assert_eq ! ( self . def_kind( item_index) , DefKind :: ExternCrate ) ;
735+ return None ;
736+ }
737+ } ;
738+ Some ( Ident :: new ( name, span) )
740739 }
741740
742741 fn item_ident ( & self , item_index : DefIndex , sess : & Session ) -> Ident {
743- self . try_item_ident ( item_index, sess) . unwrap ( )
742+ self . opt_item_ident ( item_index, sess) . expect ( "no encoded ident for item" )
744743 }
745744
746745 fn maybe_kind ( & self , item_id : DefIndex ) -> Option < EntryKind > {
@@ -1102,27 +1101,19 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11021101 // Iterate over all children.
11031102 if let Some ( children) = self . root . tables . children . get ( self , id) {
11041103 for child_index in children. decode ( ( self , sess) ) {
1105- // FIXME: Merge with the logic below.
1106- if let None | Some ( EntryKind :: ForeignMod | EntryKind :: Impl ( _) ) =
1107- self . maybe_kind ( child_index)
1108- {
1109- continue ;
1110- }
1111-
1112- let def_key = self . def_key ( child_index) ;
1113- if def_key. disambiguated_data . data . get_opt_name ( ) . is_some ( ) {
1114- let span = self . get_span ( child_index, sess) ;
1104+ if let Some ( ident) = self . opt_item_ident ( child_index, sess) {
11151105 let kind = self . def_kind ( child_index) ;
1116- let ident = self . item_ident ( child_index, sess) ;
1117- let vis = self . get_visibility ( child_index) ;
1106+ if matches ! ( kind, DefKind :: Macro ( ..) ) {
1107+ // FIXME: Macros are currently encoded twice, once as items and once as
1108+ // reexports. We ignore the items here and only use the reexports.
1109+ continue ;
1110+ }
11181111 let def_id = self . local_def_id ( child_index) ;
11191112 let res = Res :: Def ( kind, def_id) ;
1113+ let vis = self . get_visibility ( child_index) ;
1114+ let span = self . get_span ( child_index, sess) ;
11201115
1121- // FIXME: Macros are currently encoded twice, once as items and once as
1122- // reexports. We ignore the items here and only use the reexports.
1123- if !matches ! ( kind, DefKind :: Macro ( ..) ) {
1124- callback ( Export { res, ident, vis, span } ) ;
1125- }
1116+ callback ( Export { ident, res, vis, span } ) ;
11261117
11271118 // For non-re-export structs and variants add their constructors to children.
11281119 // Re-export lists automatically contain constructors when necessary.
@@ -1309,24 +1300,26 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13091300
13101301 fn get_item_attrs (
13111302 & ' a self ,
1312- node_id : DefIndex ,
1303+ id : DefIndex ,
13131304 sess : & ' a Session ,
13141305 ) -> impl Iterator < Item = ast:: Attribute > + ' a {
1315- // The attributes for a tuple struct/variant are attached to the definition, not the ctor;
1316- // we assume that someone passing in a tuple struct ctor is actually wanting to
1317- // look at the definition
1318- let def_key = self . def_key ( node_id) ;
1319- let item_id = if def_key. disambiguated_data . data == DefPathData :: Ctor {
1320- def_key. parent . unwrap ( )
1321- } else {
1322- node_id
1323- } ;
1324-
13251306 self . root
13261307 . tables
13271308 . attributes
1328- . get ( self , item_id)
1329- . unwrap_or_else ( Lazy :: empty)
1309+ . get ( self , id)
1310+ . unwrap_or_else ( || {
1311+ // Structure and variant constructors don't have any attributes encoded for them,
1312+ // but we assume that someone passing a constructor ID actually wants to look at
1313+ // the attributes on the corresponding struct or variant.
1314+ let def_key = self . def_key ( id) ;
1315+ assert_eq ! ( def_key. disambiguated_data. data, DefPathData :: Ctor ) ;
1316+ let parent_id = def_key. parent . expect ( "no parent for a constructor" ) ;
1317+ self . root
1318+ . tables
1319+ . attributes
1320+ . get ( self , parent_id)
1321+ . expect ( "no encoded attributes for a structure or variant" )
1322+ } )
13301323 . decode ( ( self , sess) )
13311324 }
13321325
@@ -1372,39 +1365,39 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13721365 self . root . traits . decode ( self ) . map ( |index| self . local_def_id ( index) )
13731366 }
13741367
1375- fn get_implementations_for_trait (
1368+ fn get_trait_impls ( & ' a self ) -> impl Iterator < Item = ( DefId , Option < SimplifiedType > ) > + ' a {
1369+ self . trait_impls . values ( ) . flat_map ( move |impls| {
1370+ impls
1371+ . decode ( self )
1372+ . map ( |( idx, simplified_self_ty) | ( self . local_def_id ( idx) , simplified_self_ty) )
1373+ } )
1374+ }
1375+
1376+ fn get_implementations_of_trait (
13761377 & self ,
13771378 tcx : TyCtxt < ' tcx > ,
1378- filter : Option < DefId > ,
1379- ) -> & ' tcx [ ( DefId , Option < ty :: fast_reject :: SimplifiedType > ) ] {
1379+ trait_def_id : DefId ,
1380+ ) -> & ' tcx [ ( DefId , Option < SimplifiedType > ) ] {
13801381 if self . root . is_proc_macro_crate ( ) {
13811382 // proc-macro crates export no trait impls.
13821383 return & [ ] ;
13831384 }
13841385
1385- if let Some ( def_id) = filter {
1386- // Do a reverse lookup beforehand to avoid touching the crate_num
1387- // hash map in the loop below.
1388- let filter = match self . reverse_translate_def_id ( def_id) {
1389- Some ( def_id) => ( def_id. krate . as_u32 ( ) , def_id. index ) ,
1390- None => return & [ ] ,
1391- } ;
1386+ // Do a reverse lookup beforehand to avoid touching the crate_num
1387+ // hash map in the loop below.
1388+ let key = match self . reverse_translate_def_id ( trait_def_id) {
1389+ Some ( def_id) => ( def_id. krate . as_u32 ( ) , def_id. index ) ,
1390+ None => return & [ ] ,
1391+ } ;
13921392
1393- if let Some ( impls) = self . trait_impls . get ( & filter) {
1394- tcx. arena . alloc_from_iter (
1395- impls. decode ( self ) . map ( |( idx, simplified_self_ty) | {
1396- ( self . local_def_id ( idx) , simplified_self_ty)
1397- } ) ,
1398- )
1399- } else {
1400- & [ ]
1401- }
1402- } else {
1403- tcx. arena . alloc_from_iter ( self . trait_impls . values ( ) . flat_map ( |impls| {
1393+ if let Some ( impls) = self . trait_impls . get ( & key) {
1394+ tcx. arena . alloc_from_iter (
14041395 impls
14051396 . decode ( self )
1406- . map ( |( idx, simplified_self_ty) | ( self . local_def_id ( idx) , simplified_self_ty) )
1407- } ) )
1397+ . map ( |( idx, simplified_self_ty) | ( self . local_def_id ( idx) , simplified_self_ty) ) ,
1398+ )
1399+ } else {
1400+ & [ ]
14081401 }
14091402 }
14101403
0 commit comments