[VERSE] Wrong error and warning message about "return" following "or"

Summary

In verse, the compiler complains about the following code:

DoStuff():void = {
    Result := AnyFailableExpression[] or return # Error: Precedence doesn't allow "return" following "or"

    Print("Result is: {Result}")
}

But, I believe this error is a mistake and not true, since it can be easily bypassed by writting the same logic in other ways, such as the following examples:

DoStuff():void = {
    Result := AnyFailableExpression[] or (return) # No error, compiles and work fine.

    Print("Result is: {Result}")
}
DoStuff():void = {
    Result := AnyFailableExpression[] or block{return} # No error, compiles and work fine.

    Print("Result is: {Result}")
}
DoStuff():void = {
    Result := AnyFailableExpression[] or (Print("Failed :("); return) # No error, compiles and work fine.

    Print("Result is: {Result}")
}
DoStuff():int = { # <- Function that returns a value
    Result := AnyFailableExpression[] or (return 76) # No error, compiles and work fine.

    Print("Result is: {Result}")
    Result
}
DoStuff():string = {
    Result := AnyFailableExpression[] or block{
        Print("Failed :(")
        DoSomething()
        return "Oh, no!"
    } # No error, compiles and work fine.

    Print("Result is: {Result}")
    "Yayyy!"
}

All the examples above works as intended: If the failable expression succeeds, it continue and prints the result. If it fails, it does an early return (executing all the right side of the “or” statement).

Due to this, I am confident that the original Error (Precedence doesn’t allow “return” following “or”) is a mistake.

Additionally, when doing any of the workaround examples I mentioned above, while it does not throw any error, it still shows a warning that is also incorrect: “Unreachable code - previous expression is guaranteed to exit early”.
This warning does not prevent compiling or usage of the code, but, the statement said on the warning is wrong, because the code still works fine as intended (the code IS reachable).

Both the Error and Warnings should be removed.

Please select what you are reporting on:

Verse

What Type of Bug are you experiencing?

Verse

Steps to Reproduce

Try to use any expression with a return on the right side of a “or” statement. (Does not matter if the function returns void or a specific value)

Expected Result

No errors and no warnings about functionality and/or usage should appear, since the code is already properly working fine as expected.

Observed Result

  • If using return directly, an Error will be thrown, preventing from compiling and using the code;
  • If the return is enclosed (on a tuple or a code block for example), it will not show the Error, but now it will show a Warning about functionality.

Both the Error and Warnings messages are incorrect, and should be removed since the code behavior works correctly without problems, as described on the examples provided above…

Platform(s)

All (Verse VM)

Upload an image




Additional Notes

This syntax is currently being used to provide “early returns” like guard statements, such as discussed here: Verse lacks `guard` statement

Update: After some tests, I discovered that the same problem occurs with other keywords too, such as “break” (inside loops)

DoStuff():void = {
    loop {
        Result := GetRandomInt(0, 1) = 1 or break # Error: Precedence doesn't allow "break" following "or"
    }
}

and workarounds:

DoStuff():void = {
    loop {
        Result := GetRandomInt(0, 1) = 1 or (break) # No error, compiles and work fine (but shows false unreachable code warning).
    }
}
DoStuff():void = {
    loop {
        Result := GetRandomInt(0, 1) = 1 or block{
            Print("CoinFlip Failed :(")
            break
        } # No error, compiles and work fine (but shows false unreachable code warning).
    }
}

Same behavior on the examples above: It compiles works, but shows the error and warning messages as if it did not worked at all…


And, even other unreleased/unimplemented features/keywords are also affected by this (such as “continue” keyword example bellow):

DoStuff():void = {
    for (X := 0..10 ){
        Result := GetRandomInt(0, 1) = 1 or continue # Error: Precedence doesn't allow "continue" following "or"
    }
}
DoStuff():void = {
    for (X := 0..10 ){
        Result := GetRandomInt(0, 1) = 1 or (continue) # No precedence Error, and also no code unreachable Warning this time.
    }
}

(On the last example above, It shows “continue is reserved reserved for future use” error, but that’s expected on this case)

FORT-972607 has been added to our ‘To Do’ list. Someone’s been assigned this task.