@@ -24,8 +24,7 @@ pub use self::ExpnFormat::*;
2424
2525use rustc_data_structures:: fx:: FxHashMap ;
2626use 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 } ;
2928use std:: cmp;
3029use std:: hash:: Hash ;
3130use std:: path:: { Path , PathBuf } ;
@@ -125,13 +124,17 @@ impl StableFilemapId {
125124// CodeMap
126125//
127126
127+ pub ( super ) struct CodeMapFiles {
128+ pub ( super ) file_maps : Vec < Lrc < FileMap > > ,
129+ stable_id_to_filemap : FxHashMap < StableFilemapId , Lrc < FileMap > >
130+ }
131+
128132pub 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 > ,
131135 // This is used to apply the file path remapping as specified via
132136 // --remap-path-prefix to all FileMaps allocated within this CodeMap.
133137 path_mapping : FilePathMapping ,
134- stable_id_to_filemap : RefCell < FxHashMap < StableFilemapId , Lrc < FileMap > > > ,
135138 /// In case we are in a doctest, replace all file names with the PathBuf,
136139 /// and add the given offsets to the line info
137140 doctest_offset : Option < ( FileName , isize ) > ,
@@ -140,10 +143,12 @@ pub struct CodeMap {
140143impl CodeMap {
141144 pub fn new ( path_mapping : FilePathMapping ) -> CodeMap {
142145 CodeMap {
143- files : RefCell :: new ( Vec :: new ( ) ) ,
146+ files : Lock :: new ( CodeMapFiles {
147+ file_maps : Vec :: new ( ) ,
148+ stable_id_to_filemap : FxHashMap ( ) ,
149+ } ) ,
144150 file_loader : Box :: new ( RealFileLoader ) ,
145151 path_mapping,
146- stable_id_to_filemap : RefCell :: new ( FxHashMap ( ) ) ,
147152 doctest_offset : None ,
148153 }
149154 }
@@ -157,14 +162,16 @@ impl CodeMap {
157162
158163 }
159164
160- pub fn with_file_loader ( file_loader : Box < FileLoader > ,
165+ pub fn with_file_loader ( file_loader : Box < FileLoader + Sync + Send > ,
161166 path_mapping : FilePathMapping )
162167 -> CodeMap {
163168 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,
166174 path_mapping,
167- stable_id_to_filemap : RefCell :: new ( FxHashMap ( ) ) ,
168175 doctest_offset : None ,
169176 }
170177 }
@@ -187,17 +194,16 @@ impl CodeMap {
187194 Ok ( self . new_filemap ( filename, src) )
188195 }
189196
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 )
192199 }
193200
194201 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 ( ) )
196203 }
197204
198205 fn next_start_pos ( & self ) -> usize {
199- let files = self . files . borrow ( ) ;
200- match files. last ( ) {
206+ match self . files . borrow ( ) . file_maps . last ( ) {
201207 None => 0 ,
202208 // Add one so there is some space between files. This lets us distinguish
203209 // positions in the codemap, even in the presence of zero-length files.
@@ -207,9 +213,9 @@ impl CodeMap {
207213
208214 /// Creates a new filemap without setting its line information. If you don't
209215 /// 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.
210217 pub fn new_filemap ( & self , filename : FileName , src : String ) -> Lrc < FileMap > {
211218 let start_pos = self . next_start_pos ( ) ;
212- let mut files = self . files . borrow_mut ( ) ;
213219
214220 // The path is used to determine the directory for loading submodules and
215221 // include files, so it must be before remapping.
@@ -233,16 +239,16 @@ impl CodeMap {
233239 Pos :: from_usize ( start_pos) ,
234240 ) ) ;
235241
236- files. push ( filemap . clone ( ) ) ;
242+ let mut files = self . files . borrow_mut ( ) ;
237243
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 ( ) ) ;
241246
242247 filemap
243248 }
244249
245250 /// Creates a new filemap and sets its line information.
251+ /// This does not ensure that only one FileMap exists per file name.
246252 pub fn new_filemap_and_lines ( & self , filename : & Path , src : & str ) -> Lrc < FileMap > {
247253 let fm = self . new_filemap ( filename. to_owned ( ) . into ( ) , src. to_owned ( ) ) ;
248254 let mut byte_pos: u32 = fm. start_pos . 0 ;
@@ -273,7 +279,6 @@ impl CodeMap {
273279 mut file_local_non_narrow_chars : Vec < NonNarrowChar > )
274280 -> Lrc < FileMap > {
275281 let start_pos = self . next_start_pos ( ) ;
276- let mut files = self . files . borrow_mut ( ) ;
277282
278283 let end_pos = Pos :: from_usize ( start_pos + source_len) ;
279284 let start_pos = Pos :: from_usize ( start_pos) ;
@@ -297,20 +302,19 @@ impl CodeMap {
297302 crate_of_origin,
298303 src : None ,
299304 src_hash,
300- external_src : RefCell :: new ( ExternalSource :: AbsentOk ) ,
305+ external_src : Lock :: new ( ExternalSource :: AbsentOk ) ,
301306 start_pos,
302307 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) ,
306311 name_hash,
307312 } ) ;
308313
309- files. push ( filemap . clone ( ) ) ;
314+ let mut files = self . files . borrow_mut ( ) ;
310315
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 ( ) ) ;
314318
315319 filemap
316320 }
@@ -401,8 +405,7 @@ impl CodeMap {
401405 pub fn lookup_line ( & self , pos : BytePos ) -> Result < FileMapAndLine , Lrc < FileMap > > {
402406 let idx = self . lookup_filemap_idx ( pos) ;
403407
404- let files = self . files . borrow ( ) ;
405- let f = ( * files) [ idx] . clone ( ) ;
408+ let f = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
406409
407410 match f. lookup_line ( pos) {
408411 Some ( line) => Ok ( FileMapAndLine { fm : f, line : line } ) ,
@@ -456,7 +459,7 @@ impl CodeMap {
456459 }
457460
458461 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 ) {
460463 return "no-location" . to_string ( ) ;
461464 }
462465
@@ -799,7 +802,7 @@ impl CodeMap {
799802 }
800803
801804 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 ( ) {
803806 if * filename == fm. name {
804807 return Some ( fm. clone ( ) ) ;
805808 }
@@ -810,16 +813,15 @@ impl CodeMap {
810813 /// For a global BytePos compute the local offset within the containing FileMap
811814 pub fn lookup_byte_offset ( & self , bpos : BytePos ) -> FileMapAndBytePos {
812815 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 ( ) ;
814817 let offset = bpos - fm. start_pos ;
815818 FileMapAndBytePos { fm : fm, pos : offset}
816819 }
817820
818821 /// Converts an absolute BytePos to a CharPos relative to the filemap.
819822 pub fn bytepos_to_file_charpos ( & self , bpos : BytePos ) -> CharPos {
820823 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] ;
823825
824826 // The number of extra bytes due to multibyte chars in the FileMap
825827 let mut total_extra_bytes = 0 ;
@@ -845,7 +847,7 @@ impl CodeMap {
845847 // Return the index of the filemap (in self.files) which contains pos.
846848 pub fn lookup_filemap_idx ( & self , pos : BytePos ) -> usize {
847849 let files = self . files . borrow ( ) ;
848- let files = & * files;
850+ let files = & files. file_maps ;
849851 let count = files. len ( ) ;
850852
851853 // Binary search for the filemap.
0 commit comments