-
-
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
Compiler may not assume correct integer literal type from enclosing context #6558
Comments
There is 10.unsafe_as(UInt32) # => 10_u32 Also, your case would be better handled with struct Slice(T)
def zero!
map! { T.zero }
end
end |
@Sija unsafe is the last resort. In fact, I'd like to say it's never a solution. In fact, it won't work well, I think, when trying to covert between types of different bit size. In this case there's a |
Thanks @Sija, though that brings up another question - does there exist manual type hinting? |
@RomanHargrave a couple of extra notes: Casting in Crystal is using Hope that helps! |
Tested with Crystal 0.25.1 (the currently available version from the official debian repository)
There exist situations where the compiler will not correctly determine the appropriate integer type to use for ambiguously specified integer literals (e.g. lacking the integer type suffix).
Take, for example, the following extension to
Slice
Because the compiler appears to assume ambiguous integers to be
Int32
when the type is unspecified (or in this case when it gets confused),zero!
will compile (and therefore run) as expected when called onSlice[1, 2, 3]
(sinceInt32
is the default type); however, attempting to do the same withSlice[1_u8, 2_u8, 3_u8]
will result in some rather misleading compiler errors regarding argument type compatibility forPointer#[]=
called withinSlice#map!
.While this could supposedly be all good and well if there existed a means to 'blindly' convert integer types at compile time, no such manner exists. While
0.cast(T)
may appear acceptable, it prohibits nearly any conversion - presumably on the basis thatInt32
and some otherInt
have different sizes. These leads me to believe that, In order to support each possible member type forSlice(T)
one would have to specialize - by hand -zero!
for each possibleT
, which seems absurd.I assume that this misbehavior is brought about by inability to constrain the return type of a block, which would explain the compilers unwavering choice of
Int32
; however, I am not entirely privy to the existence, or lack thereof, of such an inability - and therefore may be entirely wrong in my diagnosis of the problem.As an aside, I observed that the compiler refuses to allow casts between
Int32
andUInt32
which, while I have no use for, i find amusing solely because the types should be compatible at memory level. Yes, I do realize that the sign bit would be treated as part of the value in the event that it were set, but one has to assume that if#to(T)
is being used that the developer acknowledges it is now their responsibility to ensure the integrity of the resulting outcome.The text was updated successfully, but these errors were encountered: