@@ -8,8 +8,9 @@ use std::convert::From;
88use std:: fmt;
99
1010use rustc_ast:: ast;
11- use rustc_hir:: { def:: CtorKind , def_id:: DefId } ;
11+ use rustc_hir:: { def:: CtorKind , def :: DefKind , def_id:: DefId } ;
1212use rustc_middle:: ty:: { self , TyCtxt } ;
13+ use rustc_span:: symbol:: sym;
1314use rustc_span:: { Pos , Symbol } ;
1415use rustc_target:: spec:: abi:: Abi as RustcAbi ;
1516
@@ -217,13 +218,27 @@ pub(crate) fn from_item_id_with_name(item_id: ItemId, tcx: TyCtxt<'_>, name: Opt
217218
218219 impl < ' a > fmt:: Display for DisplayDefId < ' a > {
219220 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
220- let name = match self . 2 {
221+ let DisplayDefId ( def_id, tcx, name) = self ;
222+ let name = match name {
221223 Some ( name) => format ! ( ":{}" , name. as_u32( ) ) ,
222- None => self
223- . 1
224- . opt_item_name ( self . 0 )
225- . map ( |n| format ! ( ":{}" , n. as_u32( ) ) )
226- . unwrap_or_default ( ) ,
224+ None => {
225+ // We need this workaround because primitive types' DefId actually refers to
226+ // their parent module, which isn't present in the output JSON items. So
227+ // instead, we directly get the primitive symbol and convert it to u32 to
228+ // generate the ID.
229+ if matches ! ( tcx. def_kind( def_id) , DefKind :: Mod ) &&
230+ let Some ( prim) = tcx. get_attrs ( * def_id, sym:: doc)
231+ . flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
232+ . filter ( |attr| attr. has_name ( sym:: primitive) )
233+ . find_map ( |attr| attr. value_str ( ) ) {
234+ format ! ( ":{}" , prim. as_u32( ) )
235+ } else {
236+ tcx
237+ . opt_item_name ( * def_id)
238+ . map ( |n| format ! ( ":{}" , n. as_u32( ) ) )
239+ . unwrap_or_default ( )
240+ }
241+ }
227242 } ;
228243 write ! ( f, "{}:{}{}" , self . 0 . krate. as_u32( ) , u32 :: from( self . 0 . index) , name)
229244 }
0 commit comments