Under Review
over 1 year ago

CIQTOOLS-389

CIQTOOLS-390

Resources seem to be type Number, not Symbol

The documentation says that things like Rez.Strings.name have type Symbol.

But I tried:

        if (Rez.Strings.AppName instanceof Lang.Symbol) {
            System.println("AppName is a Symbol");
        }

and nothing got printed.

So I tried

        if (Rez.Strings.AppName instanceof Lang.Symbol) {
            System.println("AppName is a Symbol");
        }
        if (Rez.Strings.AppName instanceof Lang.Number) {
            System.println("AppName is a Number");
        }

and I got:

ERROR: <device>: bug.mc:4,8: Type '$.Toybox.Lang.Symbol' is not an instance of '$.Toybox.Lang.Number'.

So the type checker definitely seems to think that Rez.Strings.AppName is a Symbol (as an aside, this would be a pretty annoying error, even if it was correct; if it knows that instanceof is false, it could just optimize it away, maybe with a warning, but making it an error seems overkill).

So I turned the type checker off, compiled and ran, and got:

AppName is a Number

making the type checker error look even sillier.

This doesn't seem to matter too much - apparently if you pass a number where a Symbol is expected (eg as the argument to menu.setTitle), it works (provided the number corresponds to an actual symbol), even though the type checker says its an error.

But I noticed it because I was trying to debug a function that took various Rez.Strings.<name> as a symbol argument, and I added some logging to print symbol.toString() - which should show me the name of the symbol in a debug build. But all I got was numbers.

  • So to restate the obvious, there's two issues here:

    - The warning/error is poorly worded (unless there's actually something special about instanceof always being false, as opposed to some other condition always being false, in which I would ask: why?)

    - The type checker thinks resources are one type when they're actually another

  • (You'll note that I already upvoted this bug report)

  • Yeah, I get all of that, I'm just saying that if the compiler really thought the condition could never be true, it should say so explicitly rather than obliquely hinting at it. The actual error (from the compiler's POV) is that it thinks you're checking for a condition that's always false; the actual details of that condition are secondary (IMO)

    Wasn't trying to argue with you or contradict anything you wrote.

  • For example, in typescript the following code would be an error

    Also note that with typescript, you can suppress any particular error, and you can even tell the compiler to generate code even when there are errors. I'll also note that there have been several (rejected) requests to make this controlled by an option (so its not universally liked, even though you can work around it).

    So thats rather different from simply refusing to compile something.

  • Not to state the obvious but I think this is an example of a class of error where the compiler won't let you write a condition that is known to be false.

    I literally wrote that in the paragraph you quoted.

    if it knows that instanceof is false, it could just optimize it away, maybe with a warning, but making it an error seems overkill

    And - also in that paragraph - it was just an aside. An incidental comment. The real point was that although it *thinks* its a condition that can't possibly be true, it is, in fact, true.