You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# The result of this block is never Nil
result =case str ="string".as(String|Nil)
whenStringputs"str.class = #{str.class}"puts"typeof(str) = #{typeof(str)}"
str
whenNil"(Nil)"endputs"result.class = #{result.class}"puts"typeof(result) = #{typeof(result)}"
For a block that never returns String (never Nil), the type of the block is still String | Nil,
which I suspect is because it is returning str which is String | Nil even though it can only ever be
returned when it is String (notice that the output shows the compiler implicity changing the type to String within the match clause).
If it is only possible for the block to return String, the type should not be a union of String and another.
The text was updated successfully, but these errors were encountered:
NOTE: Adding a default branch (else) causes the compiler to compute the correct type, but the problem I have with that is that the two preexisting branches cover the entire domain of potential types, and the compiler should not expect a default branch in order to determine the type (because the default branch will never be followed...).
# The result of this block is never Nil
result =case str ="string".as(String|Nil)
whenStringputs"str.class = #{str.class}"puts"typeof(str) = #{typeof(str)}"
str
whenNil"(Nil)"elseraise""endputs"result.class = #{result.class}"puts"typeof(result) = #{typeof(result)}"
It's because case will return nil if it matches nothing by default.
I don't think the compiler can work out whether a case's branches is exhaustive (at the moment) because it compares using Object#=== which can be overridden. You could make str === Nil be true, and it would segfault. Not sure if this is something @asterite would want to change.
RomanHargrave
changed the title
Type computer for block by compiler may not match the actual type.
Type computed for block by compiler may not match the actual type.
Apr 7, 2017
Illustrated on the crystal playground
Code from the example:
Output of above:
For a block that never returns
String
(neverNil
), the type of the block is stillString | Nil
,which I suspect is because it is returning
str
which isString | Nil
even though it can only ever bereturned when it is
String
(notice that the output shows the compiler implicity changing the type toString
within the match clause).If it is only possible for the block to return
String
, the type should not be a union ofString
and another.The text was updated successfully, but these errors were encountered: