Windows: building a V project located directly under a drive root hangs forever (infinite loop in find_module_path) #3
Describe the bug
On Windows, compiling a V project that is located directly under a drive root (e.g. S:\vlang2) hangs forever (100% CPU on one core, memory slowly growing, no output). The same sources compile fine when the project is nested one level deeper (e.g. S:\repo\vlang).
This also makes make/makev.bat hang at the Compiling "./v_stage.exe" with "./v_win_bootstrap.exe" step when the checkout is at a drive root.
Reproduce
- Put a V checkout directly under a drive root, e.g.
S:\v. - From that directory, build the compiler:
Observed: hangs indefinitely. Building the same sources from a nested path (e.g.v -o vnew cmd/vS:\some\dir\v) completes normally.Minimal trigger: the hang occurs while resolving the first cross-module import ofcmd/v(import hashfromcmd/v/v.v). A trivial single-file program (v run examples/hello_world.v) does not hang, because it has no such import.
Root cause
The infinite loop is in find_module_path() in vlib/v/builder/builder.v — the loop that anchors an importer to the outermost enclosing v.mod:
importer_vmod_folder = vmod_file_location.vmod_folder // e.g. "S:\v"
for {
parent := os.dir(importer_vmod_folder) // os.dir("S:\v") -> "S:"
if parent == importer_vmod_folder {
break
}
parent_loc := mcache.get_by_folder(parent) // get_by_folder("S:")
if parent_loc.vmod_file == '' {
break
}
importer_vmod_folder = parent_loc.vmod_folder // -> back to "S:\v"
}
When the project sits at a drive root:
os.dir("S:\v")returns the bare drive"S:".- inside
get_by_folder("S:"),os.real_path("S:")resolves a bare drive letter to that drive's current directory ("S:\v"), not the drive root.Soimporter_vmod_foldernever advances past"S:\v", while the loop's progress guard compares the unresolved"S:"against"S:\v"— they differ textually, so it never breaks. The loop spins forever.At a nested path the parent (S:\repo) has nov.mod, soparent_loc.vmod_file == ''and the loop exits — which is why nesting the project avoids the bug.Confirmation of the OS-level behavior (run fromS:\v):os.dir("S:\v") => "S:" os.real_path("S:") => "S:\v" # bare drive letter -> drive's current dir os.real_path("S:\") => "S:\"
Suggested fix
Break the loop when resolving parent makes no upward progress:
parent_loc := mcache.get_by_folder(parent)
if parent_loc.vmod_file == '' {
break
}
if parent_loc.vmod_folder == importer_vmod_folder {
// no upward progress (e.g. a bare drive letter like `S:` resolves back
// to the same folder on Windows); stop to avoid an infinite loop
break
}
importer_vmod_folder = parent_loc.vmod_folder
With this guard, building cmd/v from a drive-root checkout completes normally (~27s in my test, vs. never), and the resulting compiler self-rebuilds at the drive root in ~6s.
Note: because make/makev.bat bootstrap the first stage from the pre-generated vc/v_win.c, the bootstrap step will keep hanging at a drive-root checkout until vlang/vc is regenerated with this fix.
Expected behavior
Building a V project located at a drive root on Windows should work the same as building it from a nested directory.
V version / Environment
- V 0.5.1
- OS: Windows 11 (x64)
[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.