@@ -14,12 +14,38 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX};
14
14
use ty:: { self , Ty , TyCtxt } ;
15
15
use syntax:: ast;
16
16
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
+
17
36
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
18
37
/// Returns a string identifying this def-id. This string is
19
38
/// suitable for user output. It is relative to the current crate
20
- /// root.
39
+ /// root, unless with_forced_absolute_paths was used .
21
40
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) ;
23
49
self . push_item_path ( & mut buffer, def_id) ;
24
50
buffer. into_string ( )
25
51
}
@@ -75,7 +101,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
75
101
RootMode :: Absolute => {
76
102
// In absolute mode, just write the crate name
77
103
// 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
+ }
79
109
}
80
110
}
81
111
}
0 commit comments