@@ -8,8 +8,9 @@ use std::convert::From;
8
8
use std:: fmt;
9
9
10
10
use rustc_ast:: ast;
11
- use rustc_hir:: { def:: CtorKind , def_id:: DefId } ;
11
+ use rustc_hir:: { def:: CtorKind , def :: DefKind , def_id:: DefId } ;
12
12
use rustc_middle:: ty:: { self , TyCtxt } ;
13
+ use rustc_span:: symbol:: sym;
13
14
use rustc_span:: { Pos , Symbol } ;
14
15
use rustc_target:: spec:: abi:: Abi as RustcAbi ;
15
16
@@ -217,13 +218,27 @@ pub(crate) fn from_item_id_with_name(item_id: ItemId, tcx: TyCtxt<'_>, name: Opt
217
218
218
219
impl < ' a > fmt:: Display for DisplayDefId < ' a > {
219
220
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 {
221
223
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
+ }
227
242
} ;
228
243
write ! ( f, "{}:{}{}" , self . 0 . krate. as_u32( ) , u32 :: from( self . 0 . index) , name)
229
244
}
0 commit comments