Skip to content

fix(stdlib): convert dots to path separators in require()#242

Merged
davydog187 merged 1 commit into
mainfrom
fix/require-dotted-module-name
May 27, 2026
Merged

fix(stdlib): convert dots to path separators in require()#242
davydog187 merged 1 commit into
mainfrom
fix/require-dotted-module-name

Conversation

@davydog187
Copy link
Copy Markdown
Contributor

Summary

  • require("foo.bar") was resolving to <package.path>/foo.bar.lua instead of <package.path>/foo/bar.lua. Lua 5.3 §6.3 (package.searchpath) requires that every . in the module name be replaced with the directory separator before substitution into the ? slot of each package.path template. The new VM was skipping that step, so any disk-loaded dotted require would look in the wrong place.
  • Fix is a two-line change in find_module_file/2: hoist String.replace(modname, ".", "/") above the pattern loop and substitute the result. The default package.path already hardcodes / as the separator (lib/lua/vm/stdlib.ex:597), so this introduces no new configuration surface.
  • Adds a regression test that exercises the disk-load path with a dotted module name. Existing tests in package_test.exs only used single-segment names, so the substitution path was unexercised.

Downstream impact

Caught by a downstream sidecar consumer bumping to 1.0.0-rc.0. Its bootstrap goes require("luassert")luassert/init.luarequire("luassert.assert"), which is exactly the broken path. With this fix and a 1.0.0-rc.1 release, that consumer can bump.

Out of scope (intentionally)

The investigation surfaced broader package-compliance gaps that are not part of this PR — keeping the fix minimal. Track separately if/when needed:

  • package.config (the 5-line config string) is not exposed.
  • package.searchpath/2 is not implemented (would share the same ./ logic; worth extracting a helper at that point).
  • package.cpath / C-loader semantics.
  • The official lua53_tests/attrib.lua suite remains skipped — it depends on package.searchpath and C submodules in addition to this fix.

Test plan

  • mix test test/lua/vm/stdlib/package_test.exs — new dotted-require test passes
  • mix test — full suite: 1,848 passed, 30 skipped (no new skips, no regressions)
  • Manual: point a downstream consumer at this branch ({:lua, github: "tv-labs/lua", branch: "fix/require-dotted-module-name"}) and confirm its luassert-chained requires resolve

Lua 5.3 §6.3 requires that the module-name dots be replaced with the
directory separator before substitution into each `?` slot of a
`package.path` template. The new VM was substituting `modname` verbatim,
so `require("foo.bar")` looked for `foo.bar.lua` instead of `foo/bar.lua`.

This broke downstream consumers that chain dotted requires (e.g. the
`luassert` bootstrap: `luassert/init.lua` → `require("luassert.assert")`).

The fix hoists a `String.replace(modname, ".", "/")` above the pattern
loop. The default `package.path` already hardcodes `/` as the separator,
so no new configuration surface is introduced.

Adds a regression test exercising the disk-load path with a dotted name;
prior tests only used single-segment module names.
@davydog187 davydog187 merged commit 9344c7c into main May 27, 2026
5 checks passed
@davydog187 davydog187 deleted the fix/require-dotted-module-name branch May 27, 2026 00:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant