Skip to content

bug: [func] array holding struct-namespaced function refs loses struct return type at codegen #1458

@SchoolyB

Description

@SchoolyB

Severity

Medium — compile-time failure, not a silent miscompile. User-facing error is a raw C compiler error rather than a clean EZ error, which is confusing.

Summary

When a struct-namespaced function reference (e.g. ()Vec.create) is stored in a [func] array and then invoked via index-call, the codegen forgets that the function's return type is the struct type and falls through to int64_t. Any downstream field access on the result fails to compile.

Reproduction

const Vec struct {
    x int

    do create(val int) -> Vec {
        return Vec{x: val}
    }
}

do main() {
    mut ctors [func] = {()Vec.create}
    mut v = ctors[0](42)
    println(v.x)
}

Expected

Prints 42.

Actual

C compilation error surfaced to the user:

error: member reference base type 'int64_t' (aka 'long long') is not a structure or union
 45 |     ez_builtin_println_int(v.x);
    |                            ~^~

Working cases (for contrast)

These adjacent patterns all work correctly:

Only the intersection — [func] array + struct-namespaced ref + struct field access on the result — is broken.

Root cause (best guess)

When inferring the type of ctors[0](42), the codegen/typechecker treats the element type as the generic func type (the [func] storage is type-erased to void *) and has no way to recover the specific referenced function's return type. The direct-func-var path (mut f func = ()Vec.create) works because the fix in 1a3e7c6 threads the referenced function through Symbol::func_ref_name — but that metadata only lives on the symbol, not on an array element. Once a struct-namespaced ref is put in a [func] array, its return-type identity is lost.

Suggested scope for fix

  • Either extend Symbol::func_ref_name / equivalent bookkeeping to array element positions, so index-call through a [func] array can look up the original referenced function's return type, or
  • Accept that [func] elements are type-erased and require an explicit cast / type annotation at the call site when the return type is a struct, with a clean EZ error ("cannot infer struct return type from [func] element; annotate or call directly") instead of a raw C error.

Design call needed — the first option is more ergonomic but adds parallel bookkeeping; the second is simpler but degrades UX.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcodegenRelated to C code generationezcEZC compiler tool (EZ → C → native binary)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions