-
-
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
Box(T).unbox
crashes if T
is a nilable union type
#11839
Comments
Expanding the subtyping relationship manually, we could probably write |
This can also occur with a union of a value and nil. x = nil.as(Int32?)
Box(Int32?).unbox(Box.box(x)) |
Using Box.unbox on a nil value with a union type causes: Invalid memory access (signal 11) at address 0x8 Related Crystal issue: crystal-lang/crystal#11839 Fixes: https://gitlab.com/arctic-fox/spectator/-/issues/76
@icy-arctic-fox 🤔 Box is meant for reference types... do you have a use-case for a union of int and nil? Or was it an accident? |
Ah, nevermind, maybe there's a use case, I don't know... at least there's a spec for values. |
My actual use case was a union of a struct and nil. But this issue applies to reference and values types when they are unioned with nil. An example use case of using |
Addresses issue found relating to https://gitlab.com/arctic-fox/spectator/-/issues/81 See crystal-lang/crystal#11839
|
Box(T).unbox
crashes if T
is a nilable reference typeBox(T).unbox
crashes if T
is a nilable union type
Box.box
casts its argument toVoid*
directly if it is reference-like, via theReference?
parameter restriction.Box(T).unbox
however uses the checkT <= Reference || T == Nil
, which fails ifT
is a nilable reference type, so the boxed value is treated like a box for a value type instead. The correct check isT <= Reference?
, but this is currently disallowed:Nothing actually stops us from permitting
Reference
here, as long as we ensure that unions of direct subclasses ofReference
do not merge intoReference
(the way it is now); the same goes for runtime checks, i.e.x.is_a?(Reference?)
. Without this, the workaround would be not using theVoid*
cast for nilable references.Related: #11833
The text was updated successfully, but these errors were encountered: