@@ -250,7 +250,7 @@ pub fn prepare_session_directory(tcx: TyCtxt) -> Result<bool, ()> {
250
250
251
251
// Try to remove the session directory we just allocated. We don't
252
252
// 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) {
254
254
tcx. sess . warn ( & format ! ( "Failed to delete partly initialized \
255
255
session dir `{}`: {}",
256
256
session_dir. display( ) ,
@@ -282,7 +282,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
282
282
debug ! ( "finalize_session_directory() - invalidating session directory: {}" ,
283
283
incr_comp_session_dir. display( ) ) ;
284
284
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) {
286
286
sess. warn ( & format ! ( "Error deleting incremental compilation \
287
287
session directory `{}`: {}",
288
288
incr_comp_session_dir. display( ) ,
@@ -460,7 +460,7 @@ fn lock_directory(sess: &Session,
460
460
461
461
fn delete_session_dir_lock_file ( sess : & Session ,
462
462
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) {
464
464
sess. warn ( & format ! ( "Error deleting lock file for incremental \
465
465
compilation session directory `{}`: {}",
466
466
lock_file_path. display( ) ,
@@ -841,7 +841,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
841
841
debug ! ( "garbage_collect_session_directories() - deleting `{}`" ,
842
842
path. display( ) ) ;
843
843
844
- if let Err ( err) = std_fs :: remove_dir_all ( & path) {
844
+ if let Err ( err) = safe_remove_dir_all ( & path) {
845
845
sess. warn ( & format ! ( "Failed to garbage collect finalized incremental \
846
846
compilation session directory `{}`: {}",
847
847
path. display( ) ,
@@ -860,7 +860,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
860
860
debug ! ( "garbage_collect_session_directories() - deleting `{}`" ,
861
861
path. display( ) ) ;
862
862
863
- if let Err ( err) = std_fs :: remove_dir_all ( & path) {
863
+ if let Err ( err) = safe_remove_dir_all ( & path) {
864
864
sess. warn ( & format ! ( "Failed to garbage collect incremental \
865
865
compilation session directory `{}`: {}",
866
866
path. display( ) ,
@@ -893,6 +893,30 @@ fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option<
893
893
}
894
894
}
895
895
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
+
896
920
#[ test]
897
921
fn test_all_except_most_recent ( ) {
898
922
assert_eq ! ( all_except_most_recent(
0 commit comments