Given:
var x as Array<String> = [42, 42] as Array<String>; // Fails, despite explicit cast var y as [Number, Number] = [42, 42]; // Works, tuple type is inferred var z as Array<String> = y as Array<String>; // Works var w as Array<String> = 42 as Array<String>; // Works var v as String = 42 as String; // Works
The first assignment fails, even though we cast the tuple to the correct type. In earlier sdks, casts are always honored, even if they're obviously wrong (as this one is). So in a way, this could be seen as an improvement. On the other hand it reports the assignment as the error, rather than the cast. Also it only seems to do this for tuple literals. If we create a tuple variable y with the same type ([Number, Number]) and cast that to Array<String>, the type checker is happy. So this behavior is both inconsistent wrt to old sdks, and inconsistent wrt itself.
And just to confirm the inconsistency, the type checker is still quite happy to cast 42 to Array<String> (assignment to w), or to String (assignment to v).
Also, the error message is really confusing:
ERROR: fr235: bug.mc:1,4: Cannot assign '[$.Toybox.Lang.Number] = $.Toybox.Lang.Number' to '$.Toybox.Lang.Array<$.Toybox.Lang.String>'.
What does
[$.Toybox.Lang.Number] = $.Toybox.Lang.Number
mean here? The tuple is actually [Number, Number]
, it's being cast to Array<String>
, and assigned to Array<String>
. I don't see what the error message is referring to...
If this seems too abstract (who would want to cast a tuple of Number to an Array of String?), this actually came up in my code. I currently have something like this, which works (and is type-correct) in sdk-6:
var ids as Array<Symbol> = [Rez.Strings.S1, Rez.Strings.S2, ...] as Array<Symbol>;
As described here, Rez.Strings.x is now typed as ResourceId, rather than as Symbol, and this assignment now fails, despite the previously correct cast. As described in the bug report, if you work around that, things still don't work, because when you try to pass ids[i] to loadResource, the type is wrong.