-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong type of value of union type after assignment in if
clause with cast
#12661
Comments
Oh, and I discovered this in Crystal 1.0 and confirmed at https://play.crystal-lang.org/#/r/dy5j that it's still present in 1.6.1, so it appears to be deeply entrenched. |
Sorry, I should also add that if I remove the Hash{"stuff" => "bla", "more" => false, "level" => 33}.select{|k, v| k == "level"}.each do |key, param_value|
puts "BEFORE class for #{key}: #{param_value.class.name}"
if as_i = param_value.as?(Int32)
puts "YES #{as_i} was truthy"
end
if as_i = param_value.as?(Int32)
puts "Made it int #{as_i}.. what should happen"
elsif as_b = param_value.as?(Bool)
puts "Made it bool #{as_b}... what the heck?!"
else
puts "No dice"
end
puts "AFTER class for #{key}: #{param_value.class.name}"
end Then everything works properly. So something about the |
Reduced: val = 33 || false || "foo"
if as_s = val.as?(String)
puts "Made it string #{as_s}.. never happens"
elsif as_i = val.as?(Int32)
puts "Made it int #{as_i}.. what should happen"
elsif as_b = val.as?(Bool)
puts "Made it bool #{as_b}... what the heck?!"
else
puts "No dice"
end Printing @atlantis This does seem quite strange, tho I'm not sure if param_value.is_a?(String)
puts "Made it string #{param_value}.. never happens"
elsif param_value.is_a?(Int32)
puts "Made it int #{param_value}.. what should happen"
elsif param_value.is_a?(Bool)
puts "Made it bool #{param_value}... what the heck?!"
else
puts "No dice"
end Ref: https://crystal-lang.org/reference/1.6/syntax_and_semantics/is_a.html |
Yes fortunately it's easy to work around (i used a |
Reduced further: val = 33.as(Bool | Int32 | String)
if a = val.as?(String)
else
typeof(val) # => Bool
end The problem seems to be caused by the assignment in the val = 33.as(Bool | Int32 | String)
a = val.as?(String)
if a
else
typeof(val) # => (Bool | Int32 | String)
end |
What happens if you do this?
|
Same. Parentheses don't change anything. |
if
clause with cast
First of all, thanks for a great language! I'm having issues with some sort of dark compiler type magic when using Hashes in a parameter parsing library:
produces
However, if I change the Hash to only
Hash{"level" => 33}
it works as expected. What's odd is that at the beginning of the loop I confirm thatparam_value.as?(Int32)
is truthy, and at the very end of the loop the value is still Int32, yet somehowparam_value.as?(Int32)
fails to pick it up?Let me know if there's anything else I can do to help (other than hacking the compiler, for which I'm unfortunately not qualified :)
The text was updated successfully, but these errors were encountered: