Skip to content

bug: cast() system has multiple validation and codegen gaps #1598

@SchoolyB

Description

@SchoolyB

Description

The cast() system has four distinct bugs spanning the typechecker and codegen.

Bug 1: cast(string, <numeric>) crashes at C compilation for 9 numeric targets

The typechecker allows string → numeric casts, but codegen only has handlers for int/i64 and float/f64. All other numeric targets fall through to raw C casts or range-check functions that receive an EzString struct where they expect a scalar.

Affected targets: uint, u64, f32, i8, i16, i32, u8, u16, u32

do main() {
    mut s string = "42"
    mut n uint = cast(s, uint)   // C compiler error: operand of type 'EzString'
}

Expected: Should parse the string to a numeric value, then apply any narrowing check.

Where: codegen.c lines 1933–1948 — string-to-numeric dispatch only matches "int", "i64", "float", "f64" by name. A val_kind == TK_STRING guard needs to be added before the narrowing-cast block to parse the string first.

Bug 2: cast(int/uint, EnumType) wrongly rejected

The typechecker has explicit code to allow int/uint → Enum casts, but it never fires because type_from_name() only resolves built-in type names. User-defined enum types like "Color" resolve to NULL/TK_UNKNOWN, so the allowlist check is skipped entirely.

The reverse direction (enum → int, enum → uint) works correctly.

const Color enum { RED GREEN BLUE }

do main() {
    mut n int = 1
    mut c Color = cast(n, Color)   // E3043: cannot cast 'int' to 'Color'
}

Expected: Should allow the cast since enums are int-backed.

Where: typechecker.c line ~4232 — type_from_name(node->data.cast.target_type) can't resolve user-defined types. The cast validation needs to look up user-defined types from scope when type_from_name() returns NULL.

Bug 3: Spurious E3001 on rejected cast-to-enum

Whenever a cast targeting a user-defined enum is rejected with E3043, a second nonsensical error also fires:

error[E3001]: type mismatch: cannot assign Color to Color

Expected: Only the E3043 error should appear.

Where: The cast expression resolves to an unknown type when the target is a user-defined enum. The assignment checker then compares the declared variable type (Color from scope) against the cast result type (NULL/unknown), producing a false mismatch even though both are nominally Color. Fixing Bug 2 (resolving user-defined types in cast) should also fix this.

Bug 4: cast(char, string) produces ASCII value instead of character

cast('A', string) outputs 65 instead of "A". The codegen routes char → string through emit_to_string() which formats it as a number.

do main() {
    mut c char = 'A'
    mut s string = cast(c, string)
    println(s)   // Prints: 65   (expected: A)
}

Expected: Should produce a single-character string containing "A".

Where: codegen.c line 1930–1932 — the target == "string" branch calls emit_to_string() for all source types. Needs a special case for TK_CHAR that emits a char-to-string conversion instead of numeric stringification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcodegenRelated to C code generationtypecheckerRelated to type checking and validation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions