-
-
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
[RFC] Support autocasting of tuple literals instead of Tuple
covariance
#10036
Comments
Also continuing from #2576: class Foo; end
class Bar < Foo; end
ary = [] of {Foo}
ary << {Bar.new} # should not work
ary << {Bar.new.as(Foo)} # okay Because class Foo; end
class Bar < Foo; end
ary = [] of Array(Foo)
ary << [Bar.new] # should not work
ary << [Bar.new.as(Foo)] # okay |
I don't think this is okay, a Bar is a Foo and so it should be allowed. If UInt8 is allowed to be passed into Int32 inside a tuple, that's a bug. |
It might be possible to extend the rules here so that autocasting a tuple literal consisders both covariant and compatible expressions. I am unsure if anything bad could happen that way. Also array literals could technically autocast in the same manner, but they have an
It isn't any more special than passing a |
The same arguments apply to both
Tuple
andNamedTuple
, but here only examples for the former are shown. The following code seems like it should work:But if
T
andU
areTuple
s of the same size, then due to #2576 the code will fail to compile, and if the call is replaced byas?
, the conversion will fail at runtime. The following will also not work:The difference here is that due to #6342 the type restriction never coalesces to
{Int32 | String}
.I propose we should remove
Tuple
's variance behaviour and apply automatic casts for tuple literals instead, in the same way number literals autocast to other numbers, or symbol literals autocast to enum values. Consider the original example from #2576 again:Here the deduced type of the
{1, 'a'}
literal isTuple(Int32, Char)
, whileArray#<<
expects aTuple(Int32 | String, Char)
. If the tuple literal has the same size as the tuple in the type restriction, and every element expression is compatible with the corresponding expected type, then an automatic cast is performed, so that the above will still work even withoutTuple
's covariance. On the other hand, we will now reject code like below, as compatibility does not imply covariance:Allowing compatible types instead of subtypes has further consequences, even when variance isn't involved, because compatibility checks will then be applied recursively: (both examples already work when the 1-tuples are removed)
The text was updated successfully, but these errors were encountered: