@@ -124,13 +124,17 @@ impl StableFilemapId {
124124// CodeMap
125125//
126126
127+ pub ( super ) struct CodeMapFiles {
128+ pub ( super ) file_maps : Vec < Lrc < FileMap > > ,
129+ stable_id_to_filemap : FxHashMap < StableFilemapId , Lrc < FileMap > >
130+ }
131+
127132pub struct CodeMap {
128- pub ( super ) files : Lock < Vec < Lrc < FileMap > > > ,
133+ pub ( super ) files : Lock < CodeMapFiles > ,
129134 file_loader : Box < FileLoader + Sync + Send > ,
130135 // This is used to apply the file path remapping as specified via
131136 // --remap-path-prefix to all FileMaps allocated within this CodeMap.
132137 path_mapping : FilePathMapping ,
133- stable_id_to_filemap : Lock < FxHashMap < StableFilemapId , Lrc < FileMap > > > ,
134138 /// In case we are in a doctest, replace all file names with the PathBuf,
135139 /// and add the given offsets to the line info
136140 doctest_offset : Option < ( FileName , isize ) > ,
@@ -139,10 +143,12 @@ pub struct CodeMap {
139143impl CodeMap {
140144 pub fn new ( path_mapping : FilePathMapping ) -> CodeMap {
141145 CodeMap {
142- files : Lock :: new ( Vec :: new ( ) ) ,
146+ files : Lock :: new ( CodeMapFiles {
147+ file_maps : Vec :: new ( ) ,
148+ stable_id_to_filemap : FxHashMap ( ) ,
149+ } ) ,
143150 file_loader : Box :: new ( RealFileLoader ) ,
144151 path_mapping,
145- stable_id_to_filemap : Lock :: new ( FxHashMap ( ) ) ,
146152 doctest_offset : None ,
147153 }
148154 }
@@ -160,10 +166,12 @@ impl CodeMap {
160166 path_mapping : FilePathMapping )
161167 -> CodeMap {
162168 CodeMap {
163- files : Lock :: new ( Vec :: new ( ) ) ,
169+ files : Lock :: new ( CodeMapFiles {
170+ file_maps : Vec :: new ( ) ,
171+ stable_id_to_filemap : FxHashMap ( ) ,
172+ } ) ,
164173 file_loader : file_loader,
165174 path_mapping,
166- stable_id_to_filemap : Lock :: new ( FxHashMap ( ) ) ,
167175 doctest_offset : None ,
168176 }
169177 }
@@ -187,16 +195,15 @@ impl CodeMap {
187195 }
188196
189197 pub fn files ( & self ) -> LockGuard < Vec < Lrc < FileMap > > > {
190- self . files . borrow ( )
198+ LockGuard :: map ( self . files . borrow ( ) , |files| & mut files . file_maps )
191199 }
192200
193201 pub fn filemap_by_stable_id ( & self , stable_id : StableFilemapId ) -> Option < Lrc < FileMap > > {
194- 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 ( ) )
195203 }
196204
197205 fn next_start_pos ( & self ) -> usize {
198- let files = self . files . borrow ( ) ;
199- match files. last ( ) {
206+ match self . files . borrow ( ) . file_maps . last ( ) {
200207 None => 0 ,
201208 // Add one so there is some space between files. This lets us distinguish
202209 // positions in the codemap, even in the presence of zero-length files.
@@ -206,6 +213,7 @@ impl CodeMap {
206213
207214 /// Creates a new filemap without setting its line information. If you don't
208215 /// 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.
209217 pub fn new_filemap ( & self , filename : FileName , src : String ) -> Lrc < FileMap > {
210218 let start_pos = self . next_start_pos ( ) ;
211219
@@ -231,16 +239,16 @@ impl CodeMap {
231239 Pos :: from_usize ( start_pos) ,
232240 ) ) ;
233241
234- self . files . borrow_mut ( ) . push ( filemap . clone ( ) ) ;
242+ let mut files = self . files . borrow_mut ( ) ;
235243
236- self . stable_id_to_filemap
237- . borrow_mut ( )
238- . 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 ( ) ) ;
239246
240247 filemap
241248 }
242249
243250 /// Creates a new filemap and sets its line information.
251+ /// This does not ensure that only one FileMap exists per file name.
244252 pub fn new_filemap_and_lines ( & self , filename : & Path , src : & str ) -> Lrc < FileMap > {
245253 let fm = self . new_filemap ( filename. to_owned ( ) . into ( ) , src. to_owned ( ) ) ;
246254 let mut byte_pos: u32 = fm. start_pos . 0 ;
@@ -303,11 +311,10 @@ impl CodeMap {
303311 name_hash,
304312 } ) ;
305313
306- self . files . borrow_mut ( ) . push ( filemap . clone ( ) ) ;
314+ let mut files = self . files . borrow_mut ( ) ;
307315
308- self . stable_id_to_filemap
309- . borrow_mut ( )
310- . 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 ( ) ) ;
311318
312319 filemap
313320 }
@@ -398,7 +405,7 @@ impl CodeMap {
398405 pub fn lookup_line ( & self , pos : BytePos ) -> Result < FileMapAndLine , Lrc < FileMap > > {
399406 let idx = self . lookup_filemap_idx ( pos) ;
400407
401- let f = ( * self . files . borrow ( ) ) [ idx] . clone ( ) ;
408+ let f = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
402409
403410 match f. lookup_line ( pos) {
404411 Some ( line) => Ok ( FileMapAndLine { fm : f, line : line } ) ,
@@ -452,7 +459,7 @@ impl CodeMap {
452459 }
453460
454461 pub fn span_to_string ( & self , sp : Span ) -> String {
455- 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 ) {
456463 return "no-location" . to_string ( ) ;
457464 }
458465
@@ -787,7 +794,7 @@ impl CodeMap {
787794 }
788795
789796 pub fn get_filemap ( & self , filename : & FileName ) -> Option < Lrc < FileMap > > {
790- for fm in self . files . borrow ( ) . iter ( ) {
797+ for fm in self . files . borrow ( ) . file_maps . iter ( ) {
791798 if * filename == fm. name {
792799 return Some ( fm. clone ( ) ) ;
793800 }
@@ -798,15 +805,15 @@ impl CodeMap {
798805 /// For a global BytePos compute the local offset within the containing FileMap
799806 pub fn lookup_byte_offset ( & self , bpos : BytePos ) -> FileMapAndBytePos {
800807 let idx = self . lookup_filemap_idx ( bpos) ;
801- let fm = ( * self . files . borrow ( ) ) [ idx] . clone ( ) ;
808+ let fm = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
802809 let offset = bpos - fm. start_pos ;
803810 FileMapAndBytePos { fm : fm, pos : offset}
804811 }
805812
806813 /// Converts an absolute BytePos to a CharPos relative to the filemap.
807814 pub fn bytepos_to_file_charpos ( & self , bpos : BytePos ) -> CharPos {
808815 let idx = self . lookup_filemap_idx ( bpos) ;
809- let map = & ( * self . files . borrow ( ) ) [ idx] ;
816+ let map = & ( * self . files . borrow ( ) . file_maps ) [ idx] ;
810817
811818 // The number of extra bytes due to multibyte chars in the FileMap
812819 let mut total_extra_bytes = 0 ;
@@ -832,7 +839,7 @@ impl CodeMap {
832839 // Return the index of the filemap (in self.files) which contains pos.
833840 pub fn lookup_filemap_idx ( & self , pos : BytePos ) -> usize {
834841 let files = self . files . borrow ( ) ;
835- let files = & * files;
842+ let files = & files. file_maps ;
836843 let count = files. len ( ) ;
837844
838845 // Binary search for the filemap.
0 commit comments