Skip to content

Commit 9731729

Browse files
committed
Allow unifing of promise branches in some cases.
1 parent 4f381be commit 9731729

File tree

7 files changed

+113
-6
lines changed

7 files changed

+113
-6
lines changed

spec/examples/block

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,39 @@ component Main {
66
<span>"Hello"</span>
77
}
88
}
9+
10+
11+
-------------------------------------------------------------------------------
12+
type Maybe(value) {
13+
Just(value)
14+
Nothing
15+
}
16+
17+
component Main {
18+
fun render : String {
19+
{
20+
let Just = Maybe.Just("hello") or return ""
21+
22+
`` as Promise(String)
23+
}
24+
25+
""
26+
}
27+
}
28+
-------------------------------------------------statement_return_type_mismatch
29+
type Maybe(value) {
30+
Just(value)
31+
Nothing
32+
}
33+
34+
component Main {
35+
fun render : String {
36+
{
37+
let Just = Maybe.Just("hello") or return `` as Promise(String)
38+
39+
""
40+
}
41+
42+
""
43+
}
44+
}

spec/examples/case

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,18 @@ component Main {
283283
""
284284
}
285285
}
286+
-------------------------------------------------------------------------------
287+
component Main {
288+
fun render : String {
289+
case 0 {
290+
0 => `` as Promise(Void)
291+
1 => void
292+
2 => `` as Promise(Void)
293+
3 => void
294+
4=> `` as Promise(Void)
295+
=> void
296+
}
297+
298+
""
299+
}
300+
}

spec/examples/if

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,33 @@ component Main {
199199
}
200200
}
201201
}
202+
-------------------------------------------------------------------------------
203+
component Main {
204+
fun test : Promise(Void) {
205+
if true {
206+
`` as Promise(Void)
207+
} else {
208+
Void
209+
}
210+
}
211+
212+
fun render : String {
213+
test()
214+
""
215+
}
216+
}
217+
-------------------------------------------------------------------------------
218+
component Main {
219+
fun test : Promise(Void) {
220+
if true {
221+
Void
222+
} else {
223+
`` as Promise(Void)
224+
}
225+
}
226+
227+
fun render : String {
228+
test()
229+
""
230+
}
231+
}

src/type_checker/comparer.cr

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@ module Mint
77
targets.any? { |target| compare(node, target) }
88
end
99

10+
def compare_as_promises(node1, node2, *, first_only : Bool = false)
11+
promise = false
12+
13+
if node1.name != node2.name &&
14+
((node1.name == "Promise" && node1.parameters.size == 1) ||
15+
(node2.name == "Promise" && node2.parameters.size == 1 && !first_only))
16+
node1 =
17+
node1.parameters.first if node1.name == "Promise"
18+
19+
node2 =
20+
node2.parameters.first if node2.name == "Promise" && !first_only
21+
22+
promise = true
23+
end
24+
25+
compare(node1, node2).try do |resolved|
26+
if promise
27+
Type.new("Promise", [resolved] of Checkable)
28+
else
29+
resolved
30+
end
31+
end
32+
end
33+
1034
def compare(node1, node2, *, expand : Bool = false)
1135
prune(unify(fresh(prune(node1)), fresh(prune(node2)), expand: expand))
1236
rescue

src/type_checkers/block.cr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ module Mint
6565
snippet "I was expecting:", last
6666
snippet "The return call in question is here:", return_value
6767
snippet "The returned value of the block is here:", expressions.last
68-
end unless Comparer.compare(last, type)
68+
end unless Comparer.compare_as_promises(last, type, first_only: true)
6969
end
7070

7171
if fallback = node.fallback
@@ -79,7 +79,7 @@ module Mint
7979
snippet "I was expecting:", last
8080
snippet "The fallback expression in question is here:", fallback
8181
snippet "The returned value of the block is here:", expressions.last
82-
end unless Comparer.compare(last, type)
82+
end unless Comparer.compare_as_promises(last, type, first_only: true)
8383
end
8484

8585
if async.includes?(node) && last.name != "Promise"

src/type_checkers/case.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ module Mint
224224
resolve branch, condition
225225

226226
unified_branch =
227-
Comparer.compare(type, resolved)
227+
Comparer.compare_as_promises(resolved, type)
228228

229229
error! :case_branch_not_matches do
230230
block do

src/type_checkers/if.cr

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ module Mint
7878

7979
snippet "The value for the else branch is here:",
8080
error_node.as(Ast::Node)
81-
end unless Comparer.compare(truthy, falsy)
81+
end unless resolved = Comparer.compare_as_promises(truthy, falsy)
82+
83+
resolved
8284
else
8385
error! :if_expected_else do
8486
block do
@@ -94,9 +96,9 @@ module Mint
9496
snippet truthy
9597
snippet node
9698
end unless Comparer.matches_any?(truthy, VALID_IF_TYPES)
97-
end
9899

99-
truthy
100+
truthy
101+
end
100102
end
101103
end
102104
end

0 commit comments

Comments
 (0)