@@ -8,8 +8,10 @@ use crate::util::interning::InternedString;
88use crate :: util:: { human_readable_bytes, GlobalContext , Progress , ProgressStyle } ;
99use anyhow:: bail;
1010use cargo_util:: paths;
11+ use std:: collections:: HashMap ;
1112use std:: fs;
1213use std:: path:: { Path , PathBuf } ;
14+ use std:: rc:: Rc ;
1315
1416pub struct CleanOptions < ' gctx > {
1517 pub gctx : & ' gctx GlobalContext ,
@@ -168,7 +170,7 @@ fn clean_specs(
168170 let packages = pkg_set. get_many ( pkg_ids) ?;
169171
170172 clean_ctx. progress = Box :: new ( CleaningPackagesBar :: new ( clean_ctx. gctx , packages. len ( ) ) ) ;
171-
173+ let mut dirs_to_clean : HashMap < _ , HashSet < _ > > = HashMap :: new ( ) ;
172174 for pkg in packages {
173175 let pkg_dir = format ! ( "{}-*" , pkg. name( ) ) ;
174176 clean_ctx. progress . on_cleaning_package ( & pkg. name ( ) ) ?;
@@ -193,8 +195,9 @@ fn clean_specs(
193195 continue ;
194196 }
195197 let crate_name = target. crate_name ( ) ;
196- let path_dot = format ! ( "{crate_name}." ) ;
197- let path_dash = format ! ( "{crate_name}-" ) ;
198+ let path_dot: Rc < str > = format ! ( "{crate_name}." ) . into ( ) ;
199+ let path_dash: Rc < str > = format ! ( "{crate_name}-" ) . into ( ) ;
200+
198201 for & mode in & [
199202 CompileMode :: Build ,
200203 CompileMode :: Test ,
@@ -240,16 +243,16 @@ fn clean_specs(
240243 // Remove split-debuginfo files generated by rustc.
241244
242245 let paths = [
243- ( path_dash. as_str ( ) , ".d" ) ,
244- ( path_dot. as_str ( ) , ".o" ) ,
245- ( path_dot. as_str ( ) , ".dwo" ) ,
246- ( path_dot. as_str ( ) , ".dwp" ) ,
246+ ( path_dash. clone ( ) , ".d" ) ,
247+ ( path_dot. clone ( ) , ".o" ) ,
248+ ( path_dot. clone ( ) , ".dwo" ) ,
249+ ( path_dot. clone ( ) , ".dwp" ) ,
247250 ] ;
248251 if !dir_glob_str. ends_with ( std:: path:: MAIN_SEPARATOR ) {
249252 dir_glob_str. push ( std:: path:: MAIN_SEPARATOR ) ;
250253 }
251254 dir_glob_str. push ( '*' ) ;
252- clean_ctx . rm_rf_prefix_list ( & dir_glob_str. as_str ( ) , & paths) ? ;
255+ dirs_to_clean . entry ( dir_glob_str) . or_default ( ) . extend ( paths) ;
253256
254257 // TODO: what to do about build_script_build?
255258 let dir = escape_glob_path ( layout. incremental ( ) ) ?;
@@ -260,6 +263,9 @@ fn clean_specs(
260263 }
261264 }
262265
266+ for ( dir, paths) in dirs_to_clean {
267+ clean_ctx. rm_rf_prefix_list ( & dir, & paths) ?;
268+ }
263269 Ok ( ( ) )
264270}
265271
@@ -332,17 +338,16 @@ impl<'gctx> CleanContext<'gctx> {
332338 fn rm_rf_prefix_list (
333339 & mut self ,
334340 pattern : & str ,
335- path_matchers : & [ ( & str , & str ) ] ,
341+ path_matchers : & HashSet < ( Rc < str > , & str ) > ,
336342 ) -> CargoResult < ( ) > {
337343 // TODO: Display utf8 warning to user? Or switch to globset?
338344
339345 for path in glob:: glob ( pattern) ? {
340346 let path = path?;
341347 let filename = path. file_name ( ) . and_then ( |name| name. to_str ( ) ) . unwrap ( ) ;
342- if path_matchers
343- . iter ( )
344- . any ( |( prefix, suffix) | filename. starts_with ( prefix) && filename. ends_with ( suffix) )
345- {
348+ if path_matchers. iter ( ) . any ( |( prefix, suffix) | {
349+ filename. starts_with ( & * * prefix) && filename. ends_with ( suffix)
350+ } ) {
346351 self . rm_rf ( & path) ?;
347352 }
348353 }
0 commit comments