Repository navigation
fix(std): correct loadstring annotations for LuaJIT - #1298
Conversation
In LuaJIT loadstring() is an alias for load() and accepts an optional mode and env, so extend the loadstring signature accordingly. Also add @NODISCARD to loadfile for consistency with load/loadstring. Add a redundant-parameter regression test for the LuaJIT case. Fixes EmmyLuaLs#1274
Add redundant-parameter coverage for load() and loadfile() so all three LuaJIT load functions are exercised, mirroring the loadstring regression test. Follows up EmmyLuaLs#1274
There was a problem hiding this comment.
Code Review
1. global.lua — loadstring signature change
Issue: mode parameter type may be incorrect for Lua 5.1
The loadstring function is annotated with @version 5.1, JIT. In standard Lua 5.1, loadstring only accepts (text, chunkname) — it does not accept mode or env. Only LuaJIT extends loadstring to accept mode/env (as an alias for load).
By adding mode/env unconditionally, the stdlib now advertises these parameters for plain Lua 5.1 as well, which will suppress legitimate RedundantParameter diagnostics for 5.1 users. Consider splitting the annotation or gating the extra params to JIT only (e.g., a separate @version JIT overload), rather than widening the shared signature.
Issue: mode type is std.loadmode, but load above uses the same — verify consistency
The new @param mode? std.loadmode matches load's annotation, which is good. However, note that LuaJIT's loadstring actually accepts the same mode strings as load ("b", "t", "bt"), so this is fine — just flagging that the type must be defined and exported.
Issue: @nodiscard added to loadfile — behavior change
Adding @nodiscard to loadfile is a semantic change unrelated to the stated issue (#1274). It will now flag every ignored loadfile(...) call. This may be intentional, but it's worth confirming:
- It is inconsistent with
load/loadstring, which already had@nodiscard— so this actually fixes an inconsistency. Good. - But it is a breaking change for users who intentionally ignore the result. Ensure this is called out in release notes.
2. Test file — redundant_parameter_test.rs
Issue: Repeated boilerplate across three tests
All three tests duplicate the same setup:
let mut ws = VirtualWorkspace::new();
let mut config = Emmyrc::default();
config.runtime.version = EmmyrcLuaVersion::LuaJIT;
ws.update_emmyrc(config);
ws.analysis.init_std_lib(None);Consider extracting a helper (e.g., fn luajit_ws() -> VirtualWorkspace) to reduce duplication and make future version-specific tests easier to add.
Issue: use statements inside each test function
use crate::{Emmyrc, EmmyrcLuaVersion}; is repeated in all three test functions. Move these to the module level (or the enclosing mod test) to avoid repetition.
Issue: Guard tests use assert!(!ws.has_no_diagnostic(...)) — weak assertion
The negative guard only asserts that some diagnostic exists, not that it is specifically RedundantParameter. If an unrelated diagnostic (e.g., a type error from passing {} where table is expected, or a different check) fires, the test still passes vacuously. Prefer asserting the specific diagnostic code, e.g.:
assert!(ws.has_diagnostic(
DiagnosticCode::RedundantParameter,
r#"loadstring("return 42", nil, nil, {}, {})"#
));(assuming such an API exists; otherwise check the diagnostic list explicitly).
Issue: Test naming / scope
The tests are named test_issue_1274_luajit_*, which is fine, but the load test (test_issue_1274_luajit_load) tests behavior that was presumably already working (since load already had mode/env). Confirm this test is actually exercising the new code path; if load was unchanged, this test may be redundant with existing coverage.
Minor: local _ = loadstring(...)
Using local _ = to suppress @nodiscard is a reasonable pattern, but note that _ is a real variable here. If the linter has an "unused local" check, this could itself trigger a diagnostic and interfere with the has_no_diagnostic assertion. Verify that _ is treated as a discard name by the analyzer.
3. General
- Missing changelog / doc update: The stdlib change affects user-visible diagnostics. Ensure the release notes mention both the
loadstringsignature widening and the new@nodiscardonloadfile. - Version gating: The core concern is that
loadstring's new params are only valid for JIT, but the annotation applies to5.1, JIT. This is the most likely source of false negatives for 5.1 users.
Summary
| Severity | Issue |
|---|---|
| High | loadstring mode/env params apply to Lua 5.1, but only JIT supports them → suppresses valid diagnostics |
| Medium | Guard tests assert only "some diagnostic", not specifically RedundantParameter |
| Low | Duplicated setup/use across three tests |
| Low | @nodiscard on loadfile is a behavior change; needs release-note mention |
| Info | local _ = discard pattern may interact with unused-local checks |
In LuaJIT
loadstring()is an alias forload()and accepts an optionalmodeandenv, so extend theloadstring()signature accordingly. Also add @NODISCARD toloadfile()for consistency withload()/loadstring().Add a redundant-parameter regression test for the LuaJIT case.
Fixes #1274