@@ -219,11 +219,15 @@ rustc_index::newtype_index! {
219219#[ derive( Default ) ]
220220struct VirtualFileMapping {
221221 local_to_global : IndexVec < LocalFileId , u32 > ,
222+ global_to_local : FxIndexMap < u32 , LocalFileId > ,
222223}
223224
224225impl VirtualFileMapping {
225- fn push_global_id ( & mut self , global_file_id : u32 ) -> LocalFileId {
226- self . local_to_global . push ( global_file_id)
226+ fn local_id_for_global ( & mut self , global_file_id : u32 ) -> LocalFileId {
227+ * self
228+ . global_to_local
229+ . entry ( global_file_id)
230+ . or_insert_with ( || self . local_to_global . push ( global_file_id) )
227231 }
228232
229233 fn into_vec ( self ) -> Vec < u32 > {
@@ -240,7 +244,7 @@ fn encode_mappings_for_function(
240244 global_file_table : & GlobalFileTable ,
241245 function_coverage : & FunctionCoverage < ' _ > ,
242246) -> Vec < u8 > {
243- let mut counter_regions = function_coverage. counter_regions ( ) . collect :: < Vec < _ > > ( ) ;
247+ let counter_regions = function_coverage. counter_regions ( ) ;
244248 if counter_regions. is_empty ( ) {
245249 return Vec :: new ( ) ;
246250 }
@@ -250,25 +254,23 @@ fn encode_mappings_for_function(
250254 let mut virtual_file_mapping = VirtualFileMapping :: default ( ) ;
251255 let mut mapping_regions = Vec :: with_capacity ( counter_regions. len ( ) ) ;
252256
253- // Sort and group the list of (counter, region) mapping pairs by filename.
254- // (Preserve any further ordering imposed by `FunctionCoverage`.)
257+ // Group mappings into runs with the same filename, preserving the order
258+ // yielded by `FunctionCoverage`.
255259 // Prepare file IDs for each filename, and prepare the mapping data so that
256260 // we can pass it through FFI to LLVM.
257- counter_regions. sort_by_key ( |( _counter, region) | region. file_name ) ;
258- for counter_regions_for_file in
259- counter_regions. group_by ( |( _, a) , ( _, b) | a. file_name == b. file_name )
261+ for ( file_name, counter_regions_for_file) in
262+ & counter_regions. group_by ( |( _counter, region) | region. file_name )
260263 {
261264 // Look up the global file ID for this filename.
262- let file_name = counter_regions_for_file[ 0 ] . 1 . file_name ;
263265 let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
264266
265267 // Associate that global file ID with a local file ID for this function.
266- let local_file_id = virtual_file_mapping. push_global_id ( global_file_id) ;
268+ let local_file_id = virtual_file_mapping. local_id_for_global ( global_file_id) ;
267269 debug ! ( " file id: {local_file_id:?} => global {global_file_id} = '{file_name:?}'" ) ;
268270
269271 // For each counter/region pair in this function+file, convert it to a
270272 // form suitable for FFI.
271- for & ( counter, region) in counter_regions_for_file {
273+ for ( counter, region) in counter_regions_for_file {
272274 let CodeRegion { file_name : _, start_line, start_col, end_line, end_col } = * region;
273275
274276 debug ! ( "Adding counter {counter:?} to map for {region:?}" ) ;
0 commit comments