Skip to content

Commit

Permalink
gen: output bit32 ops even for invalid variables
Browse files Browse the repository at this point in the history
Do not short-circuit the 5.1 adaptation of the output code
when an invalid type is detected. (That patching of the AST
shouldn't really be at the type checking stage...)

Fixes #673.
  • Loading branch information
hishamhm committed Jul 19, 2023
1 parent dd7f845 commit bd41ad4
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
20 changes: 20 additions & 0 deletions spec/cli/gen_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,26 @@ describe("tl gen", function()
local y = bit32.lshift(2, 3)
]], util.read_file(lua_name))
end)

it("generates bit32 operations even for invalid variables (regression test for #673)", function()
local name = util.write_tmp_file(finally, [[
local foo = require("nonexisting")
local y = 2 | (foo.wat << 9)
local x = ~y
]])
local pd = io.popen(util.tl_cmd("gen", "--gen-target=5.1", name), "r")
local output = pd:read("*a")
util.assert_popen_close(0, pd:close())
local lua_name = tl_to_lua(name)
assert.match("Wrote: " .. lua_name, output, 1, true)
util.assert_line_by_line([[
local bit32 = bit32; if not bit32 then local p, m = pcall(require, 'bit32'); if p then bit32 = m end end
local foo = require("nonexisting")
local y = bit32.bor(2, (bit32.lshift(foo.wat, 9)))
local x = bit32.bnot(y)
]], util.read_file(lua_name))
end)
end)

describe("with --gen-target=5.3", function()
Expand Down
6 changes: 3 additions & 3 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9986,14 +9986,14 @@ tl.type_check = function(ast, opts)
if not node.type then
node.type, meta_on_operator = check_metamethod(node, node.op.op, a)
if not node.type then
return node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' on type %s", resolve_tuple(orig_a))
node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' on type %s", resolve_tuple(orig_a))
end
end
if a.typename == "map" then
if a.keys.typename == "number" or a.keys.typename == "integer" then
node_warning("hint", node, "using the '#' operator on a map with numeric key type may produce unexpected results")
else
return node_error(node, "using the '#' operator on this map will always return 0")
node_error(node, "using the '#' operator on this map will always return 0")
end
end

Expand Down Expand Up @@ -10032,7 +10032,7 @@ tl.type_check = function(ast, opts)
if not node.type then
node.type, meta_on_operator = check_metamethod(node, node.op.op, a, b)
if not node.type then
return node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' for types %s and %s", resolve_tuple(orig_a), resolve_tuple(orig_b))
node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' for types %s and %s", resolve_tuple(orig_a), resolve_tuple(orig_b))
end
end

Expand Down
6 changes: 3 additions & 3 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -9986,14 +9986,14 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
if not node.type then
node.type, meta_on_operator = check_metamethod(node, node.op.op, a)
if not node.type then
return node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' on type %s", resolve_tuple(orig_a))
node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' on type %s", resolve_tuple(orig_a))
end
end
if a.typename == "map" then
if a.keys.typename == "number" or a.keys.typename == "integer" then
node_warning("hint", node, "using the '#' operator on a map with numeric key type may produce unexpected results")
else
return node_error(node, "using the '#' operator on this map will always return 0")
node_error(node, "using the '#' operator on this map will always return 0")
end
end

Expand Down Expand Up @@ -10032,7 +10032,7 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
if not node.type then
node.type, meta_on_operator = check_metamethod(node, node.op.op, a, b)
if not node.type then
return node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' for types %s and %s", resolve_tuple(orig_a), resolve_tuple(orig_b))
node_error(node, "cannot use operator '" .. node.op.op:gsub("%%", "%%%%") .. "' for types %s and %s", resolve_tuple(orig_a), resolve_tuple(orig_b))
end
end

Expand Down

0 comments on commit bd41ad4

Please sign in to comment.