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.
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 targetsThe typechecker allows
string → numericcasts, but codegen only has handlers forint/i64andfloat/f64. All other numeric targets fall through to raw C casts or range-check functions that receive anEzStringstruct where they expect a scalar.Affected targets:
uint,u64,f32,i8,i16,i32,u8,u16,u32Expected: Should parse the string to a numeric value, then apply any narrowing check.
Where:
codegen.clines 1933–1948 — string-to-numeric dispatch only matches"int","i64","float","f64"by name. Aval_kind == TK_STRINGguard needs to be added before the narrowing-cast block to parse the string first.Bug 2:
cast(int/uint, EnumType)wrongly rejectedThe typechecker has explicit code to allow
int/uint → Enumcasts, but it never fires becausetype_from_name()only resolves built-in type names. User-defined enum types like"Color"resolve toNULL/TK_UNKNOWN, so the allowlist check is skipped entirely.The reverse direction (
enum → int,enum → uint) works correctly.Expected: Should allow the cast since enums are int-backed.
Where:
typechecker.cline ~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 whentype_from_name()returnsNULL.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:
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 (
Colorfrom scope) against the cast result type (NULL/unknown), producing a false mismatch even though both are nominallyColor. Fixing Bug 2 (resolving user-defined types in cast) should also fix this.Bug 4:
cast(char, string)produces ASCII value instead of charactercast('A', string)outputs65instead of"A". The codegen routeschar → stringthroughemit_to_string()which formats it as a number.Expected: Should produce a single-character string containing
"A".Where:
codegen.cline 1930–1932 — thetarget == "string"branch callsemit_to_string()for all source types. Needs a special case forTK_CHARthat emits a char-to-string conversion instead of numeric stringification.