Odin icon indicating copy to clipboard operation
Odin copied to clipboard

Compiler crash when indexing an improperly defined enumerated array

Open chuga-git opened this issue 10 months ago • 1 comments
trafficstars

Context

Odin:    dev-2024-12-nightly:cf53404
OS:      Windows 10 Professional (version: 22H2), build 19045.5247   
CPU:     Intel(R) Core(TM) i9-7900X CPU @ 3.30GHz
RAM:     32440 MiB
Backend: LLVM 18.1.8

Expected Behavior

I expect my confused butchering of the language to not literally butcher the compiler.

Expected warning (see snippet below):

Unhandled enumerated array cases:
	North
	East
	South
	West(checker)

and

Expected a constant enum of type 'Direction' as an array field(checker)

Current Behavior

Improperly defining an enumerated array and then indexing it in the same file will cause an assertion failure before the compiler manages to warn the user of their error.

D:\a\Odin\Odin\src\check_expr.cpp(4946): Assertion Failure: `index_tav.mode == Addressing_Constant`

https://github.com/odin-lang/Odin/blob/ad99d20d292ab4708996c935315c36aef58796a8/src/check_expr.cpp#L4945-L4947

Steps to Reproduce

Here is a snippet that triggers the failure:

package main

Direction :: enum { North, East, South, West }

// incorrect
DirVecs :: [Direction][2]int {
    North = [2]int{-1, 0},
    East  = [2]int{0, +1},
    South = [2]int{+1, 0},
    West  = [2]int{-1, 0},
}

// correct (for reference)
DirVecs :: [Direction][2]int {
    .North = [2]int{-1, 0},
    .East  = [2]int{0, +1},
    .South = [2]int{+1, 0},
    .West  = [2]int{-1, 0},
}

some_func :: proc(number: int) {
    vec = [2]int{}

    // commenting this out will warn of the mistake above instead of crashing
    if number == 0 {
        vec += DirVecs[.North]
    }
}

chuga-git avatar Dec 26 '24 00:12 chuga-git

This is still occurring as of the latest commit.

Feoramund avatar Jun 09 '25 18:06 Feoramund

Still occurring as of the latest commit, and I found that it occurs even if you don't omit the expected . before the enumeration name.

Reproduction

Consider the code:

package main

import "core:fmt"

Races :: enum {
    Dwarf,
    Elf,
}

PARTY :: [Races]string {
    .DWARF = "Gimli", // Bad. Should've been ".Dwarf".
    .ELF   = "Legolas", // Bad. Should've been ".Elf".
}

main :: proc() {
    name_of_dwarf := PARTY[.Dwarf]
    fmt.println(name_of_dwarf)
}

which when compiled with odin build compiler_bug_repro.odin -file outputs:

D:\app\Odin\src\check_expr.cpp(5158): Assertion Failure: `index_tav.mode == Addressing_Constant`

However, if you instead write the first enum correctly (.Dwarf) as in:

PARTY :: [Races]string {
    .Dwarf = "Gimli", // Correct.
    .ELF   = "Legolas", // Bad. Should've been ".Elf".
}

you get a compiler error as expected:

D:/temp/compiler_bug_repro.odin(10:10) Error: Unhandled enumerated array case: Elf
        Suggestion: Was '#partial [Races]string{...}' wanted?
D:/temp/compiler_bug_repro.odin(12:6) Error: Undeclared name 'ELF' for type 'Races'
        .ELF   = "Legolas",
         ^~^
        Suggestion: Did you mean?
                Elf

Changing only the second (but not the first) enumeration name as in:

PARTY :: [Races]string {
    .DWARF = "Gimli", // Bad. Should've been ".Dwarf".
    .Elf   = "Legolas", // Correct.
}

also generates the exact same compiler error as the first wrong version.

Expected behaviour

Although a user error, it is expected for the compiler to generate the same analogous error as shown in the second version above for all of the given examples.

luizmugnaini avatar Aug 23 '25 19:08 luizmugnaini