@@ -111,7 +111,7 @@ use rustc_fs_util::{link_or_copy, LinkOrCopy};
111111use rustc_session:: { Session , StableCrateId } ;
112112
113113use std:: fs as std_fs;
114- use std:: io;
114+ use std:: io:: { self , ErrorKind } ;
115115use std:: mem;
116116use std:: path:: { Path , PathBuf } ;
117117use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
@@ -371,7 +371,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
371371 let new_path = incr_comp_session_dir. parent ( ) . unwrap ( ) . join ( new_sub_dir_name) ;
372372 debug ! ( "finalize_session_directory() - new path: {}" , new_path. display( ) ) ;
373373
374- match std_fs :: rename ( & * incr_comp_session_dir, & new_path) {
374+ match rename_path_with_retry ( & * incr_comp_session_dir, & new_path, 3 ) {
375375 Ok ( _) => {
376376 debug ! ( "finalize_session_directory() - directory renamed successfully" ) ;
377377
@@ -961,3 +961,24 @@ fn safe_remove_file(p: &Path) -> io::Result<()> {
961961 result => result,
962962 }
963963}
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