@@ -14,12 +14,38 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX};
1414use ty:: { self , Ty , TyCtxt } ;
1515use syntax:: ast;
1616
17+ use std:: cell:: Cell ;
18+
19+ thread_local ! {
20+ static FORCE_ABSOLUTE : Cell <bool > = Cell :: new( false )
21+ }
22+
23+ /// Enforces that item_path_str always returns an absolute path.
24+ /// This is useful when building symbols that contain types,
25+ /// where we want the crate name to be part of the symbol.
26+ pub fn with_forced_absolute_paths < F : FnOnce ( ) -> R , R > ( f : F ) -> R {
27+ FORCE_ABSOLUTE . with ( |force| {
28+ let old = force. get ( ) ;
29+ force. set ( true ) ;
30+ let result = f ( ) ;
31+ force. set ( old) ;
32+ result
33+ } )
34+ }
35+
1736impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
1837 /// Returns a string identifying this def-id. This string is
1938 /// suitable for user output. It is relative to the current crate
20- /// root.
39+ /// root, unless with_forced_absolute_paths was used .
2140 pub fn item_path_str ( self , def_id : DefId ) -> String {
22- let mut buffer = LocalPathBuffer :: new ( RootMode :: Local ) ;
41+ let mode = FORCE_ABSOLUTE . with ( |force| {
42+ if force. get ( ) {
43+ RootMode :: Absolute
44+ } else {
45+ RootMode :: Local
46+ }
47+ } ) ;
48+ let mut buffer = LocalPathBuffer :: new ( mode) ;
2349 self . push_item_path ( & mut buffer, def_id) ;
2450 buffer. into_string ( )
2551 }
@@ -75,7 +101,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
75101 RootMode :: Absolute => {
76102 // In absolute mode, just write the crate name
77103 // unconditionally.
78- buffer. push ( & self . crate_name ( cnum) ) ;
104+ if cnum == LOCAL_CRATE {
105+ buffer. push ( & self . crate_name ( cnum) ) ;
106+ } else {
107+ buffer. push ( & self . sess . cstore . original_crate_name ( cnum) ) ;
108+ }
79109 }
80110 }
81111 }
0 commit comments