How can I force the type of a nested literal from the outside in?

I want an array of Array(String | Symbol), but

icr:1> typeof([["str"], [:sym], ["str", :sym]])
 => Array(Array(String | Symbol) | Array(String) | Array(Symbol))

I can force the type of the inner arrays

icr:2> typeof([["str"] of String | Symbol, [:sym] of String | Symbol, ["str", :sym]])
 => Array(Array(String | Symbol))

but I’d rather not do that, because that’s a lot of typing. I’d rather do

icr:3> typeof([["str"], [:sym], ["str", :sym]] of Array(String | Symbol))
error in line 1
Error: instantiating 'Pointer(Array(String | Symbol))#[]=(Int32, Array(String))'


In C:\Users\carlo\scoop\apps\crystal\current\src\pointer.cr:146:29

 146 | (self + offset).value = value
                               ^----
Error: type must be Array(String | Symbol), not Array(String)

Shouldn’t the compiler propagate the type specification, not only from the inside out, but also from the outside in?

How can I do that?

Unfortunately, the compiler ain’t smart enough for that (yet). You have to be explicit about it.

There’s a feature request in Autocasting of array literals · Issue #10188 · crystal-lang/crystal · GitHub but it’s not high priority.

Bummer :(