diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index 15785cfd8a69a04cf7682110dc84754424a7b306..de003734cf58d31e333ed76fb46b782e9835928a 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1124,9 +1124,6 @@ pub const RenamePreserveError = error{ /// /// If `new_sub_path` already exists, `error.PathAlreadyExists` will be returned. /// -/// Renaming a file over an existing directory or a directory over an existing -/// file will fail with `error.IsDir` or `error.NotDir` -/// /// * On Windows, both paths should be encoded as [WTF-8](https://wtf-8.codeberg.page/). /// * On WASI, both paths should be encoded as valid UTF-8. /// * On other platforms, both paths are an opaque sequence of bytes with no particular encoding. diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 580804e1029bb4d4704ec1c56c928e89331956d2..1fbd02ea4535697f7e51fa3c441834f61bc361f9 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1074,6 +1074,45 @@ test "Dir.rename file <-> dir" { }.impl); } +test "Dir.renamePreserve onto existing" { + try testWithAllSupportedPathTypes(struct { + fn impl(ctx: *TestContext) !void { + const io = ctx.io; + + const test_file_path = try ctx.transformPath("test_file"); + const target_file_path = try ctx.transformPath("target_file"); + const test_dir_path = try ctx.transformPath("test_dir"); + const target_dir_path = try ctx.transformPath("target_dir"); + + try ctx.dir.writeFile(io, .{ .sub_path = test_file_path, .data = "" }); + try ctx.dir.writeFile(io, .{ .sub_path = target_file_path, .data = "" }); + try ctx.dir.createDir(io, test_dir_path, .default_dir); + try ctx.dir.createDir(io, target_dir_path, .default_dir); + + // file -> file + try expectError(error.PathAlreadyExists, ctx.dir.renamePreserve(test_file_path, ctx.dir, target_file_path, io)); + // file -> dir + try expectError(error.PathAlreadyExists, ctx.dir.renamePreserve(test_file_path, ctx.dir, target_dir_path, io)); + + // TODO: fix dir renaming on non-Linux, non-Windows systems, see https://codeberg.org/ziglang/zig/issues/35340 + if (native_os != .windows and native_os != .linux) return; + + // dir -> file + try expectError(error.PathAlreadyExists, ctx.dir.renamePreserve(test_dir_path, ctx.dir, target_file_path, io)); + // dir -> dir + try expectError(error.PathAlreadyExists, ctx.dir.renamePreserve(test_dir_path, ctx.dir, target_dir_path, io)); + + // dir -> non-empty dir + { + const target_dir = try ctx.dir.openDir(io, target_dir_path, .{}); + defer target_dir.close(io); + try target_dir.writeFile(io, .{ .sub_path = "test_file", .data = "" }); + } + try expectError(error.PathAlreadyExists, ctx.dir.renamePreserve(test_dir_path, ctx.dir, target_dir_path, io)); + } + }.impl); +} + test "rename" { const io = testing.io;