Search code examples
lualabelsyntax-error

Why a label after a return cause syntax error?


With Lua 5.4:

function f()
  return 1
  ::LABEL::
end
print(f())

I got error:

lua: _.lua:3: 'end' expected (to close 'function' at line 1) near '::'

while

function f()
  if true then return 1 end
  ::LABEL::
end
print(f())

works fine.

I don't understand that error.


Solution

  • Labels syntactically are statements. This can be seen from the grammar in the reference manual:

    stat ::= label | ...
    

    A return statement is syntactically required to be the last statement in a block:

    block ::= {stat} [retstat]
    

    The following Lua code would throw a similar syntax error:

    function f()
        return
        x = 1
    end
    

    simply because the assignment x = 1, a statement just like labels, comes after the return. Simply put, return ... must be followed by end. The rationale for this presumably is that Lua doesn't want to allow "dead code" (although this isn't really valid for labels); IIRC it also resolves a syntactical ambiguity.

    If you wrap the return in a block, the syntax error is fixed - the return now is the last statement in the block, there are no "dead statements" after it:

    function f()
        if 1 then return end -- return is followed by end - all is well (syntactically)!
        x = 1 -- this is still dead code (semantically)
    end
    

    Lua can't and won't semantically analyze your code to determine that the assignment to x is still dead code.

    This is used for quick'n'dirty insertion of early returns during debugging: You can simply wrap them in do ... end:

    function f()
        do return end -- syntactically valid, equivalent to commenting out the rest of the function
        x = 1
    end