16
16
use rustc:: dep_graph:: DepNode ;
17
17
use rustc:: hir:: map:: DefPath ;
18
18
use rustc:: hir:: def_id:: DefId ;
19
+ use rustc:: middle:: cstore:: LOCAL_CRATE ;
19
20
use rustc:: ty:: TyCtxt ;
20
21
use rustc:: util:: nodemap:: DefIdMap ;
21
22
use std:: fmt:: { self , Debug } ;
23
+ use std:: iter:: once;
24
+ use syntax:: ast;
22
25
23
26
/// Index into the DefIdDirectory
24
27
#[ derive( Copy , Clone , Debug , PartialOrd , Ord , Hash , PartialEq , Eq ,
@@ -31,17 +34,66 @@ pub struct DefPathIndex {
31
34
pub struct DefIdDirectory {
32
35
// N.B. don't use Removable here because these def-ids are loaded
33
36
// directly without remapping, so loading them should not fail.
34
- paths : Vec < DefPath >
37
+ paths : Vec < DefPath > ,
38
+
39
+ // For each crate, saves the crate-name/disambiguator so that
40
+ // later we can match crate-numbers up again.
41
+ krates : Vec < KrateInfo > ,
42
+ }
43
+
44
+ #[ derive( Debug , RustcEncodable , RustcDecodable ) ]
45
+ pub struct KrateInfo {
46
+ krate : ast:: CrateNum ,
47
+ name : String ,
48
+ disambiguator : String ,
35
49
}
36
50
37
51
impl DefIdDirectory {
38
- pub fn new ( ) -> DefIdDirectory {
39
- DefIdDirectory { paths : vec ! [ ] }
52
+ pub fn new ( krates : Vec < KrateInfo > ) -> DefIdDirectory {
53
+ DefIdDirectory { paths : vec ! [ ] , krates : krates }
54
+ }
55
+
56
+ pub fn krate_still_valid ( & self ,
57
+ tcx : TyCtxt ,
58
+ max_current_crate : ast:: CrateNum ,
59
+ krate : ast:: CrateNum ) -> bool {
60
+ // Check that the crate-number still matches. For now, if it
61
+ // doesn't, just return None. We could do better, such as
62
+ // finding the new number.
63
+
64
+ if krate > max_current_crate {
65
+ false
66
+ } else {
67
+ let old_info = & self . krates [ krate as usize ] ;
68
+ assert_eq ! ( old_info. krate, krate) ;
69
+ let old_name: & str = & old_info. name ;
70
+ let old_disambiguator: & str = & old_info. disambiguator ;
71
+ let new_name: & str = & tcx. crate_name ( krate) ;
72
+ let new_disambiguator: & str = & tcx. crate_disambiguator ( krate) ;
73
+ old_name == new_name && old_disambiguator == new_disambiguator
74
+ }
40
75
}
41
76
42
77
pub fn retrace ( & self , tcx : TyCtxt ) -> RetracedDefIdDirectory {
78
+ let max_current_crate =
79
+ tcx. sess . cstore . crates ( )
80
+ . into_iter ( )
81
+ . max ( )
82
+ . unwrap_or ( LOCAL_CRATE ) ;
83
+
43
84
let ids = self . paths . iter ( )
44
- . map ( |path| tcx. retrace_path ( path) )
85
+ . map ( |path| {
86
+ if self . krate_still_valid ( tcx, max_current_crate, path. krate ) {
87
+ tcx. retrace_path ( path)
88
+ } else {
89
+ debug ! ( "crate {} changed from {:?} to {:?}/{:?}" ,
90
+ path. krate,
91
+ self . krates[ path. krate as usize ] ,
92
+ tcx. crate_name( path. krate) ,
93
+ tcx. crate_disambiguator( path. krate) ) ;
94
+ None
95
+ }
96
+ } )
45
97
. collect ( ) ;
46
98
RetracedDefIdDirectory { ids : ids }
47
99
}
@@ -70,10 +122,26 @@ pub struct DefIdDirectoryBuilder<'a,'tcx:'a> {
70
122
71
123
impl < ' a , ' tcx > DefIdDirectoryBuilder < ' a , ' tcx > {
72
124
pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> DefIdDirectoryBuilder < ' a , ' tcx > {
125
+ let mut krates: Vec < _ > =
126
+ once ( LOCAL_CRATE )
127
+ . chain ( tcx. sess . cstore . crates ( ) )
128
+ . map ( |krate| {
129
+ KrateInfo {
130
+ krate : krate,
131
+ name : tcx. crate_name ( krate) . to_string ( ) ,
132
+ disambiguator : tcx. crate_disambiguator ( krate) . to_string ( )
133
+ }
134
+ } )
135
+ . collect ( ) ;
136
+
137
+ // the result of crates() is not in order, so sort list of
138
+ // crates so that we can just index it later
139
+ krates. sort_by_key ( |k| k. krate ) ;
140
+
73
141
DefIdDirectoryBuilder {
74
142
tcx : tcx,
75
143
hash : DefIdMap ( ) ,
76
- directory : DefIdDirectory :: new ( )
144
+ directory : DefIdDirectory :: new ( krates ) ,
77
145
}
78
146
}
79
147
0 commit comments