Ticket Created
over 2 years ago

CIQQA-1133

Inconsistent type checker errors

With strict type checking:

import Toybox.Application;
enum Foo {
    Zero,
    One,
    Two,
    Three,
}
function foo(x as Foo) as Void {}
function bar() as Void {
    foo(0);           // Fails, as expected
    foo(Zero);        // Works, as expected
    foo(Zero as Foo); // Works, as expected
    foo(0 as Foo);    // Works, as expected
    Storage.setValue("foo", Zero);          // Works
    Storage.setValue("foo", 0);             // Works
    Storage.setValue("bar", Zero as Foo);   // Fails (why?)
    Storage.setValue("baz", 0 as Foo);      // Fails (why?)
}

The error from Storage.setValue is "Invalid '$.Foo' passed as parameter 2 of type 'PolyType<Null or $.Toybox.Application.PropertyKeyType or $.Toybox.Lang.Array<$.Toybox.Application.PropertyValueType> or $.Toybox.Lang.Dictionary<$.Toybox.Application.PropertyKeyType,$.Toybox.Application.PropertyValueType> or $.Toybox.WatchUi.BitmapResource>'."

The first four lines of bar show that "Foo" is its own type, and that both Numbers and Foos can be passed when cast to Foo. Storage.setValue is happy to accept a Zero, so it seems like it accepts type Foo. But it *won't* accept 'Zero as Foo', or '0 as Foo'. Whats going on? It should either reject Zero (and require "Zero as Number" instead), or accept Zero, "Zero as Foo" and "0 as Foo".

Parents
  • One more comment

    the type of Zero is actually Number

    No, it isn't. If it was, the call foo(Zero) would fail in the same way that foo(0) does (taking the foo from my example). It's clearly its own type. And the only sensible type for it to be is the same type as (0 as Foo). But thats not what the type checker does.

    You're arguing that the type checker differentiates numeric Foos from non-numeric Foos based on their actual values, which is ok (if a little weird); but (0 as Foo) is just as good a "numeric Foo" as Zero is.

Comment
  • One more comment

    the type of Zero is actually Number

    No, it isn't. If it was, the call foo(Zero) would fail in the same way that foo(0) does (taking the foo from my example). It's clearly its own type. And the only sensible type for it to be is the same type as (0 as Foo). But thats not what the type checker does.

    You're arguing that the type checker differentiates numeric Foos from non-numeric Foos based on their actual values, which is ok (if a little weird); but (0 as Foo) is just as good a "numeric Foo" as Zero is.

Children
No Data