Skip to content

Commit 88918b2

Browse files
committed
accept 'or' as a boolean in if/while/repeat expressions
1 parent bce8845 commit 88918b2

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

spec/statement/if_spec.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ describe("if", function()
1616
end
1717
]]))
1818

19+
it("if expression propagates a boolean context", util.check([[
20+
local n = 123
21+
local s = "hello"
22+
if n or s then
23+
local ns: number | string = n or s
24+
print(ns)
25+
end
26+
]]))
27+
1928
it("accepts boolean expressions", util.check([[
2029
local s = "Hallo, Welt"
2130
if string.match(s, "world") or s == "Hallo, Welt" then

spec/statement/repeat_spec.lua

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
local util = require("spec.util")
22

33
describe("repeat", function()
4+
it("accepts a boolean", util.check([[
5+
local b = true
6+
repeat
7+
print(b)
8+
until b
9+
]]))
10+
11+
it("accepts a non-boolean", util.check([[
12+
local n = 123
13+
repeat
14+
print(n)
15+
until n
16+
]]))
17+
18+
it("until expression propagates a boolean context", util.check([[
19+
local n = 123
20+
local s = "hello"
21+
repeat
22+
local ns: number | string = n or s
23+
print(ns)
24+
until n or s
25+
]]))
26+
427
it("only closes scope after until", util.check([[
528
repeat
629
local type R = record

spec/statement/while_spec.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
local util = require("spec.util")
2+
3+
describe("while", function()
4+
it("accepts a boolean", util.check([[
5+
local b = true
6+
while b do
7+
print(b)
8+
end
9+
]]))
10+
11+
it("accepts a non-boolean", util.check([[
12+
local n = 123
13+
while n do
14+
print(n)
15+
end
16+
]]))
17+
18+
it("while expression propagates a boolean context", util.check([[
19+
local n = 123
20+
local s = "hello"
21+
while n or s do
22+
local ns: number | string = n or s
23+
print(ns)
24+
end
25+
]]))
26+
end)

tl.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10764,6 +10764,9 @@ self:expand_type(node, values, elements) })
1076410764
if node.if_block_n > 1 then
1076510765
self:infer_negation_of_if_blocks(node, node.if_parent, node.if_block_n - 1)
1076610766
end
10767+
if node.exp then
10768+
node.exp.expected = a_type(node, "boolean", {})
10769+
end
1076710770
end,
1076810771
before_statements = function(self, node)
1076910772
if node.exp then
@@ -10784,6 +10787,7 @@ self:expand_type(node, values, elements) })
1078410787
before = function(self, node)
1078510788

1078610789
self:widen_all_unions(node)
10790+
node.exp.expected = a_type(node, "boolean", {})
1078710791
end,
1078810792
before_statements = function(self, node)
1078910793
self:begin_scope(node)
@@ -10847,6 +10851,7 @@ self:expand_type(node, values, elements) })
1084710851
before = function(self, node)
1084810852

1084910853
self:widen_all_unions(node)
10854+
node.exp.expected = a_type(node, "boolean", {})
1085010855
end,
1085110856

1085210857
after = end_scope_and_none_type,
@@ -11707,6 +11712,10 @@ self:expand_type(node, values, elements) })
1170711712
end
1170811713
t = drop_constant_value(t)
1170911714
end
11715+
11716+
if expected and expected.typename == "boolean" then
11717+
t = a_type(node, "boolean", {})
11718+
end
1171011719
end
1171111720

1171211721
if t then

tl.tl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10764,6 +10764,9 @@ do
1076410764
if node.if_block_n > 1 then
1076510765
self:infer_negation_of_if_blocks(node, node.if_parent, node.if_block_n - 1)
1076610766
end
10767+
if node.exp then
10768+
node.exp.expected = a_type(node, "boolean", {})
10769+
end
1076710770
end,
1076810771
before_statements = function(self: TypeChecker, node: Node)
1076910772
if node.exp then
@@ -10784,6 +10787,7 @@ do
1078410787
before = function(self: TypeChecker, node: Node)
1078510788
-- widen all narrowed variables because we don't calculate a fixpoint yet
1078610789
self:widen_all_unions(node)
10790+
node.exp.expected = a_type(node, "boolean", {})
1078710791
end,
1078810792
before_statements = function(self: TypeChecker, node: Node)
1078910793
self:begin_scope(node)
@@ -10847,6 +10851,7 @@ do
1084710851
before = function(self: TypeChecker, node: Node)
1084810852
-- widen all narrowed variables because we don't calculate a fixpoint yet
1084910853
self:widen_all_unions(node)
10854+
node.exp.expected = a_type(node, "boolean", {})
1085010855
end,
1085110856
-- only end scope after checking `until`, `statements` in repeat body has is_repeat == true
1085210857
after = end_scope_and_none_type,
@@ -11707,6 +11712,10 @@ do
1170711712
end
1170811713
t = drop_constant_value(t)
1170911714
end
11715+
11716+
if expected and expected is BooleanType then
11717+
t = a_type(node, "boolean", {})
11718+
end
1171011719
end
1171111720

1171211721
if t then

0 commit comments

Comments
 (0)