diff --git a/lib/std/io/path.c3 b/lib/std/io/path.c3 index e729b018a..d98251018 100644 --- a/lib/std/io/path.c3 +++ b/lib/std/io/path.c3 @@ -399,6 +399,19 @@ fn Path? Path.parent(self) { if (is_separator(c, self.env)) { + if (i == 0) return { self.path_string[..0], self.env, null }; + if (self.env == WIN32 && i > 1) + { + if (try volume_len = volume_name_len(self.path_string, WIN32)) + { + // Handle C:\foo + if (volume_len == i) + { + if (i + 1 == self.path_string.len) return NO_PARENT?; + return { self.path_string[:i + 1], WIN32, null }; + } + } + } return { self.path_string[:i], self.env, null }; } } diff --git a/releasenotes.md b/releasenotes.md index 066900143..48d25ab1a 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -18,6 +18,7 @@ - Error message with hashmap shows "mangled" name instead of original #2562. - Passing a compile time type implicitly converted to a typeid would crash instead of producing an error. #2568 - Compiler assert with const enum based on vector #2566 +- Fix to `Path` handling `c:\foo` and `\home` parent. #2569 ### Stdlib changes diff --git a/test/unit/stdlib/io/path.c3 b/test/unit/stdlib/io/path.c3 index d5c7503b3..e77d2b5ec 100644 --- a/test/unit/stdlib/io/path.c3 +++ b/test/unit/stdlib/io/path.c3 @@ -34,6 +34,13 @@ fn void test_parent() p = path::new(mem, "/a/b/c", path_env: PathEnv.WIN32)!!; assert(p.parent().str_view()!! == `\a\b`); p.free(); + p = path::new(mem, "/a/", path_env: PathEnv.POSIX)!!; + assert(p.parent().str_view()!! == "/"); + p.free(); + p = path::new(mem, `C:\foo`, path_env: WIN32)!!; + assert(p.parent().str_view()!! == `C:\`); + assert(@catch(p.parent().parent())); + p.free(); } fn void test_path_normalized() => mem::@scoped(tmem)