Fix separating of diverging procedure types from block statements

To avoid creating a procedure literal from a procedure type and a
following block statement, one can insert a semicolon or an empty line
between the two:

    // procedure literals
    p1 :: proc() {…}
    p2 :: proc()
    {…}
    // procedure type followed by a block statement
    p3 :: proc()

    {…}

The empty line as a separator did not work if the procedure type had a
diverging result:

    // all of these are procedure literals
    p4 :: proc() -> ! {…}
    p5 :: proc() -> !
    {…}
    p6 :: proc() -> !

    {…}

The least annoying fix I came up with is to insert implicit semicolon
after the "not" token. I only needed to make sure that the inserted
implicit semicolon is being skipped when the "not" token is a part of
unary expression to avoid breaking an oddly-formatted code like:

    b := get_some_bool()
    if !
       b {…}

One small side-effect of this change is that in code like below:

    Proc_Type :: proc() -> !

    // Some comment
    Some_Other_Type :: enum byte {…}

The "// Some comment" is not associated with "Proc_Type" anymore. In
Odin's standard library this only happens in one place, in
`base/runtime/core.odin`:

    Assertion_Failure_Proc :: #type proc(prefix, message: string, loc: Source_Code_Location) -> !

    // Allocation Stuff
    Allocator_Mode :: enum byte {
    	Alloc,
    	…,
    }
This commit is contained in:
Krzesimir Nowak
2026-03-01 13:38:29 +01:00
parent 5eb7442c92
commit 8bdf82ac8d
2 changed files with 4 additions and 0 deletions

View File

@@ -3490,6 +3490,9 @@ gb_internal Ast *parse_unary_expr(AstFile *f, bool lhs) {
case Token_Mul: // Used for error handling when people do C-like things
{
Token token = advance_token(f);
if (token.kind == Token_Not) {
skip_possible_newline(f);
}
Ast *expr = parse_unary_expr(f, lhs);
return ast_unary_expr(f, token, expr);
}