@@ -1912,3 +1912,44 @@ fn test_hidden_file_truncation() {
19121912 let metadata = file. metadata ( ) . unwrap ( ) ;
19131913 assert_eq ! ( metadata. len( ) , 0 ) ;
19141914}
1915+
1916+ #[ cfg( windows) ]
1917+ #[ test]
1918+ fn test_rename_file_over_open_file ( ) {
1919+ // Make sure that std::fs::rename works if the target file is already opened with FILE_SHARE_DELETE. See #123985.
1920+ let tmpdir = tmpdir ( ) ;
1921+
1922+ // Create source with test data to read.
1923+ let source_path = tmpdir. join ( "source_file.txt" ) ;
1924+ fs:: write ( & source_path, b"source hello world" ) . unwrap ( ) ;
1925+
1926+ // Create target file with test data to read;
1927+ let target_path = tmpdir. join ( "target_file.txt" ) ;
1928+ fs:: write ( & target_path, b"target hello world" ) . unwrap ( ) ;
1929+
1930+ // Open target file
1931+ let target_file = fs:: File :: open ( & target_path) . unwrap ( ) ;
1932+
1933+ // Rename source
1934+ fs:: rename ( source_path, & target_path) . unwrap ( ) ;
1935+
1936+ core:: mem:: drop ( target_file) ;
1937+ assert_eq ! ( fs:: read( target_path) . unwrap( ) , b"source hello world" ) ;
1938+ }
1939+
1940+ #[ test]
1941+ #[ cfg( windows) ]
1942+ fn test_rename_directory_to_non_empty_directory ( ) {
1943+ // Renaming a directory over a non-empty existing directory should fail on Windows.
1944+ let tmpdir: TempDir = tmpdir ( ) ;
1945+
1946+ let source_path = tmpdir. join ( "source_directory" ) ;
1947+ let target_path = tmpdir. join ( "target_directory" ) ;
1948+
1949+ fs:: create_dir ( & source_path) . unwrap ( ) ;
1950+ fs:: create_dir ( & target_path) . unwrap ( ) ;
1951+
1952+ fs:: write ( target_path. join ( "target_file.txt" ) , b"target hello world" ) . unwrap ( ) ;
1953+
1954+ error ! ( fs:: rename( source_path, target_path) , 145 ) ; // ERROR_DIR_NOT_EMPTY
1955+ }
0 commit comments