@@ -8,6 +8,7 @@ use rustc_codegen_ssa::traits::ConstMethods;
88use rustc_data_structures:: fx:: FxIndexSet ;
99use rustc_hir:: def:: DefKind ;
1010use rustc_hir:: def_id:: DefId ;
11+ use rustc_index:: IndexVec ;
1112use rustc_middle:: bug;
1213use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
1314use rustc_middle:: mir:: coverage:: CodeRegion ;
@@ -163,34 +164,33 @@ fn encode_mappings_for_function(
163164 return Vec :: new ( ) ;
164165 }
165166
166- let mut virtual_file_mapping = Vec :: new ( ) ;
167+ let mut virtual_file_mapping = IndexVec :: < u32 , u32 > :: new ( ) ;
167168 let mut mapping_regions = Vec :: with_capacity ( counter_regions. len ( ) ) ;
168- let mut current_file_name = None ;
169- let mut current_file_id = 0 ;
170-
171- // Convert the list of (Counter, CodeRegion) pairs to an array of `CounterMappingRegion`, sorted
172- // by filename and position. Capture any new files to compute the `CounterMappingRegion`s
173- // `file_id` (indexing files referenced by the current function), and construct the
174- // function-specific `virtual_file_mapping` from `file_id` to its index in the module's
175- // `filenames` array.
169+
170+ // Sort the list of (counter, region) mapping pairs by region, so that they
171+ // can be grouped by filename. Prepare file IDs for each filename, and
172+ // prepare the mapping data so that we can pass it through FFI to LLVM.
176173 counter_regions. sort_by_key ( |( _counter, region) | * region) ;
177- for ( counter, region) in counter_regions {
178- let CodeRegion { file_name, start_line, start_col, end_line, end_col } = * region;
179- let same_file = current_file_name. is_some_and ( |p| p == file_name) ;
180- if !same_file {
181- if current_file_name. is_some ( ) {
182- current_file_id += 1 ;
183- }
184- current_file_name = Some ( file_name) ;
185- debug ! ( " file_id: {} = '{:?}'" , current_file_id, file_name) ;
186- let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
187- virtual_file_mapping. push ( global_file_id) ;
188- }
189- {
190- debug ! ( "Adding counter {:?} to map for {:?}" , counter, region) ;
174+ for counter_regions_for_file in
175+ counter_regions. group_by ( |( _, a) , ( _, b) | a. file_name == b. file_name )
176+ {
177+ // Look up (or allocate) the global file ID for this filename.
178+ let file_name = counter_regions_for_file[ 0 ] . 1 . file_name ;
179+ let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
180+
181+ // Associate that global file ID with a local file ID for this function.
182+ let local_file_id: u32 = virtual_file_mapping. push ( global_file_id) ;
183+ debug ! ( " file id: local {local_file_id} => global {global_file_id} = '{file_name:?}'" ) ;
184+
185+ // For each counter/region pair in this function+file, convert it to a
186+ // form suitable for FFI.
187+ for & ( counter, region) in counter_regions_for_file {
188+ let CodeRegion { file_name : _, start_line, start_col, end_line, end_col } = * region;
189+
190+ debug ! ( "Adding counter {counter:?} to map for {region:?}" ) ;
191191 mapping_regions. push ( CounterMappingRegion :: code_region (
192192 counter,
193- current_file_id ,
193+ local_file_id ,
194194 start_line,
195195 start_col,
196196 end_line,
@@ -202,7 +202,7 @@ fn encode_mappings_for_function(
202202 // Encode the function's coverage mappings into a buffer.
203203 llvm:: build_byte_buffer ( |buffer| {
204204 coverageinfo:: write_mapping_to_buffer (
205- virtual_file_mapping,
205+ virtual_file_mapping. raw ,
206206 expressions,
207207 mapping_regions,
208208 buffer,
0 commit comments