@@ -250,7 +250,7 @@ pub fn prepare_session_directory(tcx: TyCtxt) -> Result<bool, ()> {
250250
251251 // Try to remove the session directory we just allocated. We don't
252252 // know if there's any garbage in it from the failed copy action.
253- if let Err ( err) = std_fs :: remove_dir_all ( & session_dir) {
253+ if let Err ( err) = safe_remove_dir_all ( & session_dir) {
254254 tcx. sess . warn ( & format ! ( "Failed to delete partly initialized \
255255 session dir `{}`: {}",
256256 session_dir. display( ) ,
@@ -282,7 +282,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
282282 debug ! ( "finalize_session_directory() - invalidating session directory: {}" ,
283283 incr_comp_session_dir. display( ) ) ;
284284
285- if let Err ( err) = std_fs :: remove_dir_all ( & * incr_comp_session_dir) {
285+ if let Err ( err) = safe_remove_dir_all ( & * incr_comp_session_dir) {
286286 sess. warn ( & format ! ( "Error deleting incremental compilation \
287287 session directory `{}`: {}",
288288 incr_comp_session_dir. display( ) ,
@@ -460,7 +460,7 @@ fn lock_directory(sess: &Session,
460460
461461fn delete_session_dir_lock_file ( sess : & Session ,
462462 lock_file_path : & Path ) {
463- if let Err ( err) = std_fs :: remove_file ( & lock_file_path) {
463+ if let Err ( err) = safe_remove_file ( & lock_file_path) {
464464 sess. warn ( & format ! ( "Error deleting lock file for incremental \
465465 compilation session directory `{}`: {}",
466466 lock_file_path. display( ) ,
@@ -841,7 +841,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
841841 debug ! ( "garbage_collect_session_directories() - deleting `{}`" ,
842842 path. display( ) ) ;
843843
844- if let Err ( err) = std_fs :: remove_dir_all ( & path) {
844+ if let Err ( err) = safe_remove_dir_all ( & path) {
845845 sess. warn ( & format ! ( "Failed to garbage collect finalized incremental \
846846 compilation session directory `{}`: {}",
847847 path. display( ) ,
@@ -860,7 +860,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
860860 debug ! ( "garbage_collect_session_directories() - deleting `{}`" ,
861861 path. display( ) ) ;
862862
863- if let Err ( err) = std_fs :: remove_dir_all ( & path) {
863+ if let Err ( err) = safe_remove_dir_all ( & path) {
864864 sess. warn ( & format ! ( "Failed to garbage collect incremental \
865865 compilation session directory `{}`: {}",
866866 path. display( ) ,
@@ -893,6 +893,30 @@ fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option<
893893 }
894894}
895895
896+ /// Since paths of artifacts within session directories can get quite long, we
897+ /// need to support deleting files with very long paths. The regular
898+ /// WinApi functions only support paths up to 260 characters, however. In order
899+ /// to circumvent this limitation, we canonicalize the path of the directory
900+ /// before passing it to std::fs::remove_dir_all(). This will convert the path
901+ /// into the '\\?\' format, which supports much longer paths.
902+ fn safe_remove_dir_all ( p : & Path ) -> io:: Result < ( ) > {
903+ if p. exists ( ) {
904+ let canonicalized = try!( p. canonicalize ( ) ) ;
905+ std_fs:: remove_dir_all ( canonicalized)
906+ } else {
907+ Ok ( ( ) )
908+ }
909+ }
910+
911+ fn safe_remove_file ( p : & Path ) -> io:: Result < ( ) > {
912+ if p. exists ( ) {
913+ let canonicalized = try!( p. canonicalize ( ) ) ;
914+ std_fs:: remove_file ( canonicalized)
915+ } else {
916+ Ok ( ( ) )
917+ }
918+ }
919+
896920#[ test]
897921fn test_all_except_most_recent ( ) {
898922 assert_eq ! ( all_except_most_recent(
0 commit comments