Skip to content

Commit c934749

Browse files
authored
allow __len to override # (#1034)
Fixes #1031.
1 parent 118df78 commit c934749

3 files changed

Lines changed: 40 additions & 16 deletions

File tree

spec/lang/code_gen/macroexp_spec.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,5 +222,27 @@ describe("macroexp code generation", function()
222222
223223
print('arg1', 'arg2', nil)
224224
]]))
225+
226+
it("overrides array __len", util.gen([[
227+
local interface Foo is {integer}
228+
sz: integer
229+
metamethod __len: function(self) = macroexp(self: Foo)
230+
return self.sz
231+
end
232+
end
233+
234+
local f: Foo = {sz = 10}
235+
print(#f)
236+
]], [[
237+
238+
239+
240+
241+
242+
243+
244+
local f = {sz = 10}
245+
print(f.sz)
246+
]]))
225247
end)
226248

tl.lua

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14109,6 +14109,15 @@ self:expand_type(node, values, elements) })
1410914109
local tn = types_op[ra.typename]
1411014110
local t = tn and a_type(node, tn, {})
1411114111

14112+
14113+
local meta_on_operator
14114+
if not t then
14115+
local mt_name = unop_to_metamethod[node.op.op]
14116+
if mt_name then
14117+
t, meta_on_operator = self:check_metamethod(node, mt_name, ra, nil, ua, nil)
14118+
end
14119+
end
14120+
1411214121
if not t and ra.fields then
1411314122
if ra.interface_list then
1411414123
for _, iface in ipairs(ra.interface_list) do
@@ -14120,14 +14129,6 @@ self:expand_type(node, values, elements) })
1412014129
end
1412114130
end
1412214131

14123-
local meta_on_operator
14124-
if not t then
14125-
local mt_name = unop_to_metamethod[node.op.op]
14126-
if mt_name then
14127-
t, meta_on_operator = self:check_metamethod(node, mt_name, ra, nil, ua, nil)
14128-
end
14129-
end
14130-
1413114132
if ra.typename == "map" then
1413214133
if ra.keys.typename == "number" or ra.keys.typename == "integer" then
1413314134
self.errs:add_warning("hint", node, "using the '#' operator on a map with numeric key type may produce unexpected results")

tl.tl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14109,6 +14109,15 @@ do
1410914109
local tn = types_op[ra.typename]
1411014110
local t = tn and a_type(node, tn, {})
1411114111

14112+
-- we need to check if we have a macroexp that overrides any interfaces first
14113+
local meta_on_operator: integer
14114+
if not t then
14115+
local mt_name = unop_to_metamethod[node.op.op]
14116+
if mt_name then
14117+
t, meta_on_operator = self:check_metamethod(node, mt_name, ra, nil, ua, nil)
14118+
end
14119+
end
14120+
1411214121
if not t and ra is RecordLikeType then
1411314122
if ra.interface_list then
1411414123
for _, iface in ipairs(ra.interface_list) do
@@ -14120,14 +14129,6 @@ do
1412014129
end
1412114130
end
1412214131

14123-
local meta_on_operator: integer
14124-
if not t then
14125-
local mt_name = unop_to_metamethod[node.op.op]
14126-
if mt_name then
14127-
t, meta_on_operator = self:check_metamethod(node, mt_name, ra, nil, ua, nil)
14128-
end
14129-
end
14130-
1413114132
if ra is MapType then
1413214133
if ra.keys.typename == "number" or ra.keys.typename == "integer" then
1413314134
self.errs:add_warning("hint", node, "using the '#' operator on a map with numeric key type may produce unexpected results")

0 commit comments

Comments
 (0)