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
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 toint64_t. Any downstream field access on the result fails to compile.Reproduction
Expected
Prints
42.Actual
C compilation error surfaced to the user:
Working cases (for contrast)
These adjacent patterns all work correctly:
mut f func = ()Vec.create; mut v = f(42)— direct func var (was bug: function reference to struct-namespaced function returns wrong type #1438, fixed by 1a3e7c6)mut v = Vec.create(42)— direct struct-namespaced callmut ops [func] = {()add, ()sub}; ops[0](10, 3)—[func]array with plain (non-struct) return types (fixed by bug: array of function references fails at C codegen #1439 in 7be1a1a / 1a3e7c6)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 genericfunctype (the[func]storage is type-erased tovoid *) 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 throughSymbol::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
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[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
[func]array codegen base work. Closed, but this bug sits in the same neighborhood.