From ab5d2363a7c644395f204a6d8131420862a035fc Mon Sep 17 00:00:00 2001 From: wocaocaonimadelanbi Date: Fri, 10 Jul 2026 17:58:52 +0800 Subject: [PATCH] fix #24521: propagate checkDir in static walkDir The nimvm/weirdTarget branch of walkDir forwarded to staticWalkDir without the checkDir argument, so walkDir("missing", checkDir=true) silently succeeded at compile time instead of raising OSError. Thread checkDir through staticWalkDir and its vmop so the flag is honored. --- compiler/vmops.nim | 6 +++--- lib/std/private/osdirs.nim | 4 ++-- lib/std/staticos.nim | 4 +++- tests/stdlib/tstaticos.nim | 5 +++++ tests/stdlib/twalkdir_checkdir_static.nim | 14 ++++++++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 tests/stdlib/twalkdir_checkdir_static.nim diff --git a/compiler/vmops.nim b/compiler/vmops.nim index b526916d3cb9b..6ddd6aa5006db 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -148,9 +148,9 @@ proc getCurrentExceptionWrapper(a: VmArgs) {.nimcall.} = proc raiseDefectWrapper(a: VmArgs) {.nimcall.} = discard -proc staticWalkDirImpl(path: string, relative: bool): PNode = +proc staticWalkDirImpl(path: string, relative, checkDir: bool): PNode = result = newNode(nkBracket) - for k, f in walkDir(path, relative): + for k, f in walkDir(path, relative, checkDir): result.add toLit((k, f)) from std / compilesettings import SingleValueSetting, MultipleValueSetting @@ -270,7 +270,7 @@ proc registerAdditionalOps*(c: PCtx) = systemop getCurrentException systemop raiseDefect registerCallback c, "stdlib.staticos.staticWalkDir", proc (a: VmArgs) {.nimcall.} = - setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1))) + setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1), getBool(a, 2))) registerCallback c, "stdlib.staticos.staticDirExists", proc (a: VmArgs) {.nimcall.} = setResult(a, dirExists(getString(a, 0))) registerCallback c, "stdlib.staticos.staticFileExists", proc (a: VmArgs) {.nimcall.} = diff --git a/lib/std/private/osdirs.nim b/lib/std/private/osdirs.nim index 5c8ca2f432eef..4bb60144cef4c 100644 --- a/lib/std/private/osdirs.nim +++ b/lib/std/private/osdirs.nim @@ -190,11 +190,11 @@ iterator walkDir*(dir: string; relative = false, checkDir = false, ## * `walkDirRec iterator`_ when nimvm: - for k, v in items(staticWalkDir(dir, relative)): + for k, v in items(staticWalkDir(dir, relative, checkDir)): yield (k, v) else: when weirdTarget: - for k, v in items(staticWalkDir(dir, relative)): + for k, v in items(staticWalkDir(dir, relative, checkDir)): yield (k, v) elif defined(windows): var f: WIN32_FIND_DATA diff --git a/lib/std/staticos.nim b/lib/std/staticos.nim index 423751724060b..35183459c5e95 100644 --- a/lib/std/staticos.nim +++ b/lib/std/staticos.nim @@ -26,7 +26,7 @@ type pcDir, ## path refers to a directory pcLinkToDir ## path refers to a symbolic link to a directory -proc staticWalkDir*(dir: string; relative = false): seq[ +proc staticWalkDir*(dir: string; relative = false, checkDir = false): seq[ tuple[kind: PathComponent, path: string]] {.compileTime.} = ## Walks over the directory `dir` and returns a seq with each directory or ## file in `dir`. The component type and full path for each item are returned. @@ -35,4 +35,6 @@ proc staticWalkDir*(dir: string; relative = false): seq[ ## * If `relative` is true (default: false) ## the resulting path is shortened to be relative to ``dir``, ## otherwise the full path is returned. + ## * If `checkDir` is true, `OSError` is raised when `dir` + ## doesn't exist. raiseAssert "implemented in the vmops" diff --git a/tests/stdlib/tstaticos.nim b/tests/stdlib/tstaticos.nim index 41ab995dd7eeb..fb8b29cc164fb 100644 --- a/tests/stdlib/tstaticos.nim +++ b/tests/stdlib/tstaticos.nim @@ -6,3 +6,8 @@ block: doAssert staticFileExists("MISSINGDIR") == false doAssert staticDirExists(currentSourcePath().parentDir) doAssert staticFileExists(currentSourcePath()) + + # bug #24521: checkDir=false (default) must not raise on a missing dir + var count = 0 + for k, p in walkDir("MISSINGDIR"): count.inc + doAssert count == 0 diff --git a/tests/stdlib/twalkdir_checkdir_static.nim b/tests/stdlib/twalkdir_checkdir_static.nim new file mode 100644 index 0000000000000..26c5bd246e2c1 --- /dev/null +++ b/tests/stdlib/twalkdir_checkdir_static.nim @@ -0,0 +1,14 @@ +discard """ + errormsg: "unhandled exception" + file: "" + matrix: "--mm:orc" +""" + +# bug #24521: static walkDir(checkDir=true) should raise OSError when the +# directory doesn't exist. Previously the checkDir flag was dropped by the +# nimvm/weirdTarget branch which forwards to the staticWalkDir vmop. +import std/os + +static: + for k, p in walkDir("nonexistentdirectory", checkDir = true): + discard