@@ -1737,6 +1737,9 @@ module Crystal
1737
1737
when Assign
1738
1738
target = exp.target
1739
1739
return target if target.is_a?(Var )
1740
+ when Expressions
1741
+ return unless exp = single_expression(exp)
1742
+ return get_expression_var(exp)
1740
1743
end
1741
1744
nil
1742
1745
end
@@ -1843,15 +1846,17 @@ module Crystal
1843
1846
# block is when the condition is a Var (in the else it must be
1844
1847
# nil), IsA (in the else it's not that type), RespondsTo
1845
1848
# (in the else it doesn't respond to that message) or Not.
1846
- case cond = node.cond
1849
+ case cond = single_expression(node.cond) || node.cond
1847
1850
when Var , IsA , RespondsTo , Not
1848
1851
filter_vars cond_type_filters, & .not
1849
1852
when Or
1850
1853
# Try to apply boolean logic: `!(a || b)` is `!a && !b`
1854
+ cond_left = single_expression(cond.left) || cond.left
1855
+ cond_right = single_expression(cond.right) || cond.right
1851
1856
1852
1857
# We can't deduce anything for sub && or || expressions
1853
- or_left_type_filters = nil if cond.left. is_a?(And ) || cond.left .is_a?(Or )
1854
- or_right_type_filters = nil if cond.right. is_a?(And ) || cond.right .is_a?(Or )
1858
+ or_left_type_filters = nil if cond_left. is_a?(And ) || cond_left .is_a?(Or )
1859
+ or_right_type_filters = nil if cond_right. is_a?(And ) || cond_right .is_a?(Or )
1855
1860
1856
1861
# No need to deduce anything for temp vars created by the compiler (won't be used by a user)
1857
1862
or_left_type_filters = nil if or_left_type_filters && or_left_type_filters.temp_var?
@@ -2017,8 +2022,10 @@ module Crystal
2017
2022
node.body.accept self
2018
2023
end
2019
2024
2020
- endless_while = node.cond.true_literal?
2021
- merge_while_vars node.cond, endless_while, before_cond_vars_copy, before_cond_vars, after_cond_vars, @vars , node.break_vars
2025
+ cond = single_expression(node.cond) || node.cond
2026
+
2027
+ endless_while = cond.true_literal?
2028
+ merge_while_vars cond, endless_while, before_cond_vars_copy, before_cond_vars, after_cond_vars, @vars , node.break_vars
2022
2029
2023
2030
@while_stack .pop
2024
2031
@block = old_block
@@ -2146,6 +2153,9 @@ module Crystal
2146
2153
end
2147
2154
when Call
2148
2155
return get_while_cond_assign_target(node.obj)
2156
+ when Expressions
2157
+ return unless node = single_expression(node)
2158
+ return get_while_cond_assign_target(node)
2149
2159
end
2150
2160
2151
2161
nil
@@ -2178,6 +2188,16 @@ module Crystal
2178
2188
end
2179
2189
end
2180
2190
2191
+ def single_expression (node )
2192
+ result = nil
2193
+
2194
+ while node.is_a?(Expressions ) && node.expressions.size == 1
2195
+ result = node = node[0 ]
2196
+ end
2197
+
2198
+ result
2199
+ end
2200
+
2181
2201
def end_visit (node : Break )
2182
2202
if last_block_kind == :ensure
2183
2203
node.raise " can't use break inside ensure"
0 commit comments