@@ -27,6 +27,7 @@ use rustc_middle::thir;
2727use rustc_middle:: traits:: specialization_graph;
2828use rustc_middle:: ty:: codec:: TyEncoder ;
2929use rustc_middle:: ty:: fast_reject:: { self , SimplifyParams , StripReferences } ;
30+ use rustc_middle:: ty:: query:: Providers ;
3031use rustc_middle:: ty:: { self , SymbolName , Ty , TyCtxt } ;
3132use rustc_serialize:: { opaque, Encodable , Encoder } ;
3233use rustc_session:: config:: CrateType ;
@@ -612,10 +613,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
612613 self . encode_def_path_table ( ) ;
613614 let def_path_table_bytes = self . position ( ) - i;
614615
616+ // Encode the def IDs of traits, for rustdoc and diagnostics.
617+ i = self . position ( ) ;
618+ let traits = self . encode_traits ( ) ;
619+ let traits_bytes = self . position ( ) - i;
620+
615621 // Encode the def IDs of impls, for coherence checking.
616622 i = self . position ( ) ;
617- let ( traits , impls) = self . encode_traits_and_impls ( ) ;
618- let traits_and_impls_bytes = self . position ( ) - i;
623+ let impls = self . encode_impls ( ) ;
624+ let impls_bytes = self . position ( ) - i;
619625
620626 let tcx = self . tcx ;
621627
@@ -726,8 +732,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
726732 native_libraries,
727733 foreign_modules,
728734 source_map,
729- impls,
730735 traits,
736+ impls,
731737 exported_symbols,
732738 interpret_alloc_index,
733739 tables,
@@ -754,7 +760,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
754760 eprintln ! ( " diagnostic item bytes: {}" , diagnostic_item_bytes) ;
755761 eprintln ! ( " native bytes: {}" , native_lib_bytes) ;
756762 eprintln ! ( " source_map bytes: {}" , source_map_bytes) ;
757- eprintln ! ( "traits and impls bytes: {}" , traits_and_impls_bytes) ;
763+ eprintln ! ( " traits bytes: {}" , traits_bytes) ;
764+ eprintln ! ( " impls bytes: {}" , impls_bytes) ;
758765 eprintln ! ( " exp. symbols bytes: {}" , exported_symbols_bytes) ;
759766 eprintln ! ( " def-path table bytes: {}" , def_path_table_bytes) ;
760767 eprintln ! ( " def-path hashes bytes: {}" , def_path_hash_map_bytes) ;
@@ -1791,24 +1798,22 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
17911798 self . lazy ( & tcx. lang_items ( ) . missing )
17921799 }
17931800
1801+ fn encode_traits ( & mut self ) -> Lazy < [ DefIndex ] > {
1802+ empty_proc_macro ! ( self ) ;
1803+ self . lazy ( self . tcx . traits_in_crate ( LOCAL_CRATE ) . iter ( ) . map ( |def_id| def_id. index ) )
1804+ }
1805+
17941806 /// Encodes an index, mapping each trait to its (local) implementations.
1795- fn encode_traits_and_impls ( & mut self ) -> ( Lazy < [ DefIndex ] > , Lazy < [ TraitImpls ] > ) {
1796- if self . is_proc_macro {
1797- return ( Lazy :: empty ( ) , Lazy :: empty ( ) ) ;
1798- }
1807+ fn encode_impls ( & mut self ) -> Lazy < [ TraitImpls ] > {
17991808 debug ! ( "EncodeContext::encode_traits_and_impls()" ) ;
1809+ empty_proc_macro ! ( self ) ;
18001810 let tcx = self . tcx ;
1801- let mut visitor =
1802- TraitsAndImplsVisitor { tcx, impls : FxHashMap :: default ( ) , traits : Default :: default ( ) } ;
1811+ let mut visitor = ImplsVisitor { tcx, impls : FxHashMap :: default ( ) } ;
18031812 tcx. hir ( ) . visit_all_item_likes ( & mut visitor) ;
18041813
1805- let mut all_traits = visitor. traits ;
18061814 let mut all_impls: Vec < _ > = visitor. impls . into_iter ( ) . collect ( ) ;
18071815
18081816 // Bring everything into deterministic order for hashing
1809- all_traits. sort_by_cached_key ( |& local_def_index| {
1810- tcx. hir ( ) . def_path_hash ( LocalDefId { local_def_index } )
1811- } ) ;
18121817 all_impls. sort_by_cached_key ( |& ( trait_def_id, _) | tcx. def_path_hash ( trait_def_id) ) ;
18131818
18141819 let all_impls: Vec < _ > = all_impls
@@ -1826,7 +1831,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18261831 } )
18271832 . collect ( ) ;
18281833
1829- ( self . lazy ( & all_traits ) , self . lazy ( & all_impls) )
1834+ self . lazy ( & all_impls)
18301835 }
18311836
18321837 // Encodes all symbols exported from this crate into the metadata.
@@ -2048,18 +2053,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
20482053 }
20492054}
20502055
2051- struct TraitsAndImplsVisitor < ' tcx > {
2056+ struct ImplsVisitor < ' tcx > {
20522057 tcx : TyCtxt < ' tcx > ,
2053- traits : Vec < DefIndex > ,
20542058 impls : FxHashMap < DefId , Vec < ( DefIndex , Option < fast_reject:: SimplifiedType > ) > > ,
20552059}
20562060
2057- impl < ' tcx , ' v > ItemLikeVisitor < ' v > for TraitsAndImplsVisitor < ' tcx > {
2061+ impl < ' tcx , ' v > ItemLikeVisitor < ' v > for ImplsVisitor < ' tcx > {
20582062 fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
20592063 match item. kind {
2060- hir:: ItemKind :: Trait ( ..) | hir:: ItemKind :: TraitAlias ( ..) => {
2061- self . traits . push ( item. def_id . local_def_index ) ;
2062- }
20632064 hir:: ItemKind :: Impl ( ..) => {
20642065 if let Some ( trait_ref) = self . tcx . impl_trait_ref ( item. def_id . to_def_id ( ) ) {
20652066 let simplified_self_ty = fast_reject:: simplify_type (
@@ -2224,3 +2225,34 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
22242225
22252226 EncodedMetadata { raw_data : result }
22262227}
2228+
2229+ pub fn provide ( providers : & mut Providers ) {
2230+ * providers = Providers {
2231+ traits_in_crate : |tcx, cnum| {
2232+ assert_eq ! ( cnum, LOCAL_CRATE ) ;
2233+
2234+ #[ derive( Default ) ]
2235+ struct TraitsVisitor {
2236+ traits : Vec < DefId > ,
2237+ }
2238+ impl ItemLikeVisitor < ' _ > for TraitsVisitor {
2239+ fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
2240+ if let hir:: ItemKind :: Trait ( ..) | hir:: ItemKind :: TraitAlias ( ..) = item. kind {
2241+ self . traits . push ( item. def_id . to_def_id ( ) ) ;
2242+ }
2243+ }
2244+ fn visit_trait_item ( & mut self , _trait_item : & hir:: TraitItem < ' _ > ) { }
2245+ fn visit_impl_item ( & mut self , _impl_item : & hir:: ImplItem < ' _ > ) { }
2246+ fn visit_foreign_item ( & mut self , _foreign_item : & hir:: ForeignItem < ' _ > ) { }
2247+ }
2248+
2249+ let mut visitor = TraitsVisitor :: default ( ) ;
2250+ tcx. hir ( ) . visit_all_item_likes ( & mut visitor) ;
2251+ // Bring everything into deterministic order.
2252+ visitor. traits . sort_by_cached_key ( |& def_id| tcx. def_path_hash ( def_id) ) ;
2253+ tcx. arena . alloc_slice ( & visitor. traits )
2254+ } ,
2255+
2256+ ..* providers
2257+ } ;
2258+ }
0 commit comments