@@ -111,7 +111,7 @@ use rustc_fs_util::{link_or_copy, LinkOrCopy};
111
111
use rustc_session:: { Session , StableCrateId } ;
112
112
113
113
use std:: fs as std_fs;
114
- use std:: io;
114
+ use std:: io:: { self , ErrorKind } ;
115
115
use std:: mem;
116
116
use std:: path:: { Path , PathBuf } ;
117
117
use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
@@ -371,7 +371,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
371
371
let new_path = incr_comp_session_dir. parent ( ) . unwrap ( ) . join ( new_sub_dir_name) ;
372
372
debug ! ( "finalize_session_directory() - new path: {}" , new_path. display( ) ) ;
373
373
374
- match std_fs :: rename ( & * incr_comp_session_dir, & new_path) {
374
+ match rename_path_with_retry ( & * incr_comp_session_dir, & new_path, 3 ) {
375
375
Ok ( _) => {
376
376
debug ! ( "finalize_session_directory() - directory renamed successfully" ) ;
377
377
@@ -961,3 +961,24 @@ fn safe_remove_file(p: &Path) -> io::Result<()> {
961
961
result => result,
962
962
}
963
963
}
964
+
965
+ // On Windows the compiler would sometimes fail to rename the session directory because
966
+ // the OS thought something was still being accessed in it. So we retry a few times to give
967
+ // the OS time to catch up.
968
+ // See https://github.com/rust-lang/rust/issues/86929.
969
+ fn rename_path_with_retry ( from : & Path , to : & Path , mut retries_left : usize ) -> std:: io:: Result < ( ) > {
970
+ loop {
971
+ match std_fs:: rename ( from, to) {
972
+ Ok ( ( ) ) => return Ok ( ( ) ) ,
973
+ Err ( e) => {
974
+ if retries_left > 0 && e. kind ( ) == ErrorKind :: PermissionDenied {
975
+ // Try again after a short waiting period.
976
+ std:: thread:: sleep ( Duration :: from_millis ( 50 ) ) ;
977
+ retries_left -= 1 ;
978
+ } else {
979
+ return Err ( e) ;
980
+ }
981
+ }
982
+ }
983
+ }
984
+ }
0 commit comments