@@ -3,14 +3,17 @@ use std::hash::Hash;
33
44use rustdoc_json_types:: {
55 Constant , Crate , DynTrait , Enum , FnDecl , Function , FunctionPointer , GenericArg , GenericArgs ,
6- GenericBound , GenericParamDef , Generics , Id , Impl , Import , ItemEnum , Module , OpaqueTy , Path ,
7- Primitive , ProcMacro , Static , Struct , StructKind , Term , Trait , TraitAlias , Type , TypeBinding ,
8- TypeBindingKind , Typedef , Union , Variant , VariantKind , WherePredicate ,
6+ GenericBound , GenericParamDef , Generics , Id , Impl , Import , ItemEnum , ItemSummary , Module ,
7+ OpaqueTy , Path , Primitive , ProcMacro , Static , Struct , StructKind , Term , Trait , TraitAlias ,
8+ Type , TypeBinding , TypeBindingKind , Typedef , Union , Variant , VariantKind , WherePredicate ,
99} ;
1010use serde_json:: Value ;
1111
1212use crate :: { item_kind:: Kind , json_find, Error , ErrorKind } ;
1313
14+ // This is a rustc implementation detail that we rely on here
15+ const LOCAL_CRATE_ID : u32 = 0 ;
16+
1417/// The Validator walks over the JSON tree, and ensures it is well formed.
1518/// It is made of several parts.
1619///
@@ -53,12 +56,19 @@ impl<'a> Validator<'a> {
5356 }
5457
5558 pub fn check_crate ( & mut self ) {
59+ // Graph traverse the index
5660 let root = & self . krate . root ;
5761 self . add_mod_id ( root) ;
5862 while let Some ( id) = set_remove ( & mut self . todo ) {
5963 self . seen_ids . insert ( id) ;
6064 self . check_item ( id) ;
6165 }
66+
67+ let root_crate_id = self . krate . index [ root] . crate_id ;
68+ assert_eq ! ( root_crate_id, LOCAL_CRATE_ID , "LOCAL_CRATE_ID is wrong" ) ;
69+ for ( id, item_info) in & self . krate . paths {
70+ self . check_item_info ( id, item_info) ;
71+ }
6272 }
6373
6474 fn check_item ( & mut self , id : & ' a Id ) {
@@ -364,6 +374,19 @@ impl<'a> Validator<'a> {
364374 fp. generic_params . iter ( ) . for_each ( |gpd| self . check_generic_param_def ( gpd) ) ;
365375 }
366376
377+ fn check_item_info ( & mut self , id : & Id , item_info : & ItemSummary ) {
378+ // FIXME: Their should be a better way to determine if an item is local, rather than relying on `LOCAL_CRATE_ID`,
379+ // which encodes rustc implementation details.
380+ if item_info. crate_id == LOCAL_CRATE_ID && !self . krate . index . contains_key ( id) {
381+ self . errs . push ( Error {
382+ id : id. clone ( ) ,
383+ kind : ErrorKind :: Custom (
384+ "Id for local item in `paths` but not in `index`" . to_owned ( ) ,
385+ ) ,
386+ } )
387+ }
388+ }
389+
367390 fn add_id_checked ( & mut self , id : & ' a Id , valid : fn ( Kind ) -> bool , expected : & str ) {
368391 if let Some ( kind) = self . kind_of ( id) {
369392 if valid ( kind) {
0 commit comments