@@ -24,8 +24,7 @@ pub use self::ExpnFormat::*;
24
24
25
25
use rustc_data_structures:: fx:: FxHashMap ;
26
26
use rustc_data_structures:: stable_hasher:: StableHasher ;
27
- use rustc_data_structures:: sync:: Lrc ;
28
- use std:: cell:: { RefCell , Ref } ;
27
+ use rustc_data_structures:: sync:: { Lrc , Lock , LockGuard } ;
29
28
use std:: cmp;
30
29
use std:: hash:: Hash ;
31
30
use std:: path:: { Path , PathBuf } ;
@@ -125,13 +124,17 @@ impl StableFilemapId {
125
124
// CodeMap
126
125
//
127
126
127
+ pub ( super ) struct CodeMapFiles {
128
+ pub ( super ) file_maps : Vec < Lrc < FileMap > > ,
129
+ stable_id_to_filemap : FxHashMap < StableFilemapId , Lrc < FileMap > >
130
+ }
131
+
128
132
pub struct CodeMap {
129
- pub ( super ) files : RefCell < Vec < Lrc < FileMap > > > ,
130
- file_loader : Box < FileLoader > ,
133
+ pub ( super ) files : Lock < CodeMapFiles > ,
134
+ file_loader : Box < FileLoader + Sync + Send > ,
131
135
// This is used to apply the file path remapping as specified via
132
136
// --remap-path-prefix to all FileMaps allocated within this CodeMap.
133
137
path_mapping : FilePathMapping ,
134
- stable_id_to_filemap : RefCell < FxHashMap < StableFilemapId , Lrc < FileMap > > > ,
135
138
/// In case we are in a doctest, replace all file names with the PathBuf,
136
139
/// and add the given offsets to the line info
137
140
doctest_offset : Option < ( FileName , isize ) > ,
@@ -140,10 +143,12 @@ pub struct CodeMap {
140
143
impl CodeMap {
141
144
pub fn new ( path_mapping : FilePathMapping ) -> CodeMap {
142
145
CodeMap {
143
- files : RefCell :: new ( Vec :: new ( ) ) ,
146
+ files : Lock :: new ( CodeMapFiles {
147
+ file_maps : Vec :: new ( ) ,
148
+ stable_id_to_filemap : FxHashMap ( ) ,
149
+ } ) ,
144
150
file_loader : Box :: new ( RealFileLoader ) ,
145
151
path_mapping,
146
- stable_id_to_filemap : RefCell :: new ( FxHashMap ( ) ) ,
147
152
doctest_offset : None ,
148
153
}
149
154
}
@@ -157,14 +162,16 @@ impl CodeMap {
157
162
158
163
}
159
164
160
- pub fn with_file_loader ( file_loader : Box < FileLoader > ,
165
+ pub fn with_file_loader ( file_loader : Box < FileLoader + Sync + Send > ,
161
166
path_mapping : FilePathMapping )
162
167
-> CodeMap {
163
168
CodeMap {
164
- files : RefCell :: new ( Vec :: new ( ) ) ,
165
- file_loader,
169
+ files : Lock :: new ( CodeMapFiles {
170
+ file_maps : Vec :: new ( ) ,
171
+ stable_id_to_filemap : FxHashMap ( ) ,
172
+ } ) ,
173
+ file_loader : file_loader,
166
174
path_mapping,
167
- stable_id_to_filemap : RefCell :: new ( FxHashMap ( ) ) ,
168
175
doctest_offset : None ,
169
176
}
170
177
}
@@ -187,17 +194,16 @@ impl CodeMap {
187
194
Ok ( self . new_filemap ( filename, src) )
188
195
}
189
196
190
- pub fn files ( & self ) -> Ref < Vec < Lrc < FileMap > > > {
191
- self . files . borrow ( )
197
+ pub fn files ( & self ) -> LockGuard < Vec < Lrc < FileMap > > > {
198
+ LockGuard :: map ( self . files . borrow ( ) , |files| & mut files . file_maps )
192
199
}
193
200
194
201
pub fn filemap_by_stable_id ( & self , stable_id : StableFilemapId ) -> Option < Lrc < FileMap > > {
195
- self . stable_id_to_filemap . borrow ( ) . get ( & stable_id) . map ( |fm| fm. clone ( ) )
202
+ self . files . borrow ( ) . stable_id_to_filemap . get ( & stable_id) . map ( |fm| fm. clone ( ) )
196
203
}
197
204
198
205
fn next_start_pos ( & self ) -> usize {
199
- let files = self . files . borrow ( ) ;
200
- match files. last ( ) {
206
+ match self . files . borrow ( ) . file_maps . last ( ) {
201
207
None => 0 ,
202
208
// Add one so there is some space between files. This lets us distinguish
203
209
// positions in the codemap, even in the presence of zero-length files.
@@ -207,9 +213,9 @@ impl CodeMap {
207
213
208
214
/// Creates a new filemap without setting its line information. If you don't
209
215
/// intend to set the line information yourself, you should use new_filemap_and_lines.
216
+ /// This does not ensure that only one FileMap exists per file name.
210
217
pub fn new_filemap ( & self , filename : FileName , src : String ) -> Lrc < FileMap > {
211
218
let start_pos = self . next_start_pos ( ) ;
212
- let mut files = self . files . borrow_mut ( ) ;
213
219
214
220
// The path is used to determine the directory for loading submodules and
215
221
// include files, so it must be before remapping.
@@ -233,16 +239,16 @@ impl CodeMap {
233
239
Pos :: from_usize ( start_pos) ,
234
240
) ) ;
235
241
236
- files. push ( filemap . clone ( ) ) ;
242
+ let mut files = self . files . borrow_mut ( ) ;
237
243
238
- self . stable_id_to_filemap
239
- . borrow_mut ( )
240
- . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
244
+ files. file_maps . push ( filemap. clone ( ) ) ;
245
+ files. stable_id_to_filemap . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
241
246
242
247
filemap
243
248
}
244
249
245
250
/// Creates a new filemap and sets its line information.
251
+ /// This does not ensure that only one FileMap exists per file name.
246
252
pub fn new_filemap_and_lines ( & self , filename : & Path , src : & str ) -> Lrc < FileMap > {
247
253
let fm = self . new_filemap ( filename. to_owned ( ) . into ( ) , src. to_owned ( ) ) ;
248
254
let mut byte_pos: u32 = fm. start_pos . 0 ;
@@ -273,7 +279,6 @@ impl CodeMap {
273
279
mut file_local_non_narrow_chars : Vec < NonNarrowChar > )
274
280
-> Lrc < FileMap > {
275
281
let start_pos = self . next_start_pos ( ) ;
276
- let mut files = self . files . borrow_mut ( ) ;
277
282
278
283
let end_pos = Pos :: from_usize ( start_pos + source_len) ;
279
284
let start_pos = Pos :: from_usize ( start_pos) ;
@@ -297,20 +302,19 @@ impl CodeMap {
297
302
crate_of_origin,
298
303
src : None ,
299
304
src_hash,
300
- external_src : RefCell :: new ( ExternalSource :: AbsentOk ) ,
305
+ external_src : Lock :: new ( ExternalSource :: AbsentOk ) ,
301
306
start_pos,
302
307
end_pos,
303
- lines : RefCell :: new ( file_local_lines) ,
304
- multibyte_chars : RefCell :: new ( file_local_multibyte_chars) ,
305
- non_narrow_chars : RefCell :: new ( file_local_non_narrow_chars) ,
308
+ lines : Lock :: new ( file_local_lines) ,
309
+ multibyte_chars : Lock :: new ( file_local_multibyte_chars) ,
310
+ non_narrow_chars : Lock :: new ( file_local_non_narrow_chars) ,
306
311
name_hash,
307
312
} ) ;
308
313
309
- files. push ( filemap . clone ( ) ) ;
314
+ let mut files = self . files . borrow_mut ( ) ;
310
315
311
- self . stable_id_to_filemap
312
- . borrow_mut ( )
313
- . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
316
+ files. file_maps . push ( filemap. clone ( ) ) ;
317
+ files. stable_id_to_filemap . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
314
318
315
319
filemap
316
320
}
@@ -401,8 +405,7 @@ impl CodeMap {
401
405
pub fn lookup_line ( & self , pos : BytePos ) -> Result < FileMapAndLine , Lrc < FileMap > > {
402
406
let idx = self . lookup_filemap_idx ( pos) ;
403
407
404
- let files = self . files . borrow ( ) ;
405
- let f = ( * files) [ idx] . clone ( ) ;
408
+ let f = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
406
409
407
410
match f. lookup_line ( pos) {
408
411
Some ( line) => Ok ( FileMapAndLine { fm : f, line : line } ) ,
@@ -456,7 +459,7 @@ impl CodeMap {
456
459
}
457
460
458
461
pub fn span_to_string ( & self , sp : Span ) -> String {
459
- if self . files . borrow ( ) . is_empty ( ) && sp. source_equal ( & DUMMY_SP ) {
462
+ if self . files . borrow ( ) . file_maps . is_empty ( ) && sp. source_equal ( & DUMMY_SP ) {
460
463
return "no-location" . to_string ( ) ;
461
464
}
462
465
@@ -799,7 +802,7 @@ impl CodeMap {
799
802
}
800
803
801
804
pub fn get_filemap ( & self , filename : & FileName ) -> Option < Lrc < FileMap > > {
802
- for fm in self . files . borrow ( ) . iter ( ) {
805
+ for fm in self . files . borrow ( ) . file_maps . iter ( ) {
803
806
if * filename == fm. name {
804
807
return Some ( fm. clone ( ) ) ;
805
808
}
@@ -810,16 +813,15 @@ impl CodeMap {
810
813
/// For a global BytePos compute the local offset within the containing FileMap
811
814
pub fn lookup_byte_offset ( & self , bpos : BytePos ) -> FileMapAndBytePos {
812
815
let idx = self . lookup_filemap_idx ( bpos) ;
813
- let fm = ( * self . files . borrow ( ) ) [ idx] . clone ( ) ;
816
+ let fm = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
814
817
let offset = bpos - fm. start_pos ;
815
818
FileMapAndBytePos { fm : fm, pos : offset}
816
819
}
817
820
818
821
/// Converts an absolute BytePos to a CharPos relative to the filemap.
819
822
pub fn bytepos_to_file_charpos ( & self , bpos : BytePos ) -> CharPos {
820
823
let idx = self . lookup_filemap_idx ( bpos) ;
821
- let files = self . files . borrow ( ) ;
822
- let map = & ( * files) [ idx] ;
824
+ let map = & ( * self . files . borrow ( ) . file_maps ) [ idx] ;
823
825
824
826
// The number of extra bytes due to multibyte chars in the FileMap
825
827
let mut total_extra_bytes = 0 ;
@@ -845,7 +847,7 @@ impl CodeMap {
845
847
// Return the index of the filemap (in self.files) which contains pos.
846
848
pub fn lookup_filemap_idx ( & self , pos : BytePos ) -> usize {
847
849
let files = self . files . borrow ( ) ;
848
- let files = & * files;
850
+ let files = & files. file_maps ;
849
851
let count = files. len ( ) ;
850
852
851
853
// Binary search for the filemap.
0 commit comments