Summary
A module-qualified call whose function name already starts with the module name is mangled correctly inside an assignment, but gets the module prefix applied twice inside a struct literal in return position. intarr.intarr_new_raw(4) becomes intarr_intarr_new_raw(4), which does not exist.
The generated C then fails with call to undeclared function, so this surfaces as a C compiler error rather than an Aether diagnostic.
Reproduction
import std.intarr
struct Box { a: ptr }
fn make_assign() -> Box {
b = Box { a: intarr.intarr_new_raw(4) } // emits intarr_new_raw correct
return b
}
fn make_return() -> Box {
return Box { a: intarr.intarr_new_raw(4) } // emits intarr_intarr_new_raw wrong
}
main() {
x = make_assign()
y = make_return()
println("ok")
}
mangle_repro.ae:11:23: error: call to undeclared function 'intarr_intarr_new_raw';
return (Box){.a = intarr_intarr_new_raw(4)};
^
note: did you mean 'intarr_new_raw'?
The assignment form at line 6 and the return form at line 11 are the same call. Only the return form is mangled wrongly.
Notes
This only bites when the exported function name already begins with its module name, which is why bytes.new inside a return W { buf: bytes.new(cap), off: 0 } is fine (bytes_new is correct either way) while intarr.intarr_new_raw is not. Any module following the <module>_<verb> export convention is exposed: std.intarr, and by inspection std.fs (fs_read_binary_tuple), std.zlib (zlib_try_inflate) and std.bytes (aether_bytes_*) have the same shape.
Workaround
Assign to a local first, then return it:
fn make_return() -> Box {
b = Box { a: intarr.intarr_new_raw(4) }
return b
}
Environment
Summary
A module-qualified call whose function name already starts with the module name is mangled correctly inside an assignment, but gets the module prefix applied twice inside a struct literal in
returnposition.intarr.intarr_new_raw(4)becomesintarr_intarr_new_raw(4), which does not exist.The generated C then fails with
call to undeclared function, so this surfaces as a C compiler error rather than an Aether diagnostic.Reproduction
The assignment form at line 6 and the return form at line 11 are the same call. Only the return form is mangled wrongly.
Notes
This only bites when the exported function name already begins with its module name, which is why
bytes.newinside areturn W { buf: bytes.new(cap), off: 0 }is fine (bytes_newis correct either way) whileintarr.intarr_new_rawis not. Any module following the<module>_<verb>export convention is exposed:std.intarr, and by inspectionstd.fs(fs_read_binary_tuple),std.zlib(zlib_try_inflate) andstd.bytes(aether_bytes_*) have the same shape.Workaround
Assign to a local first, then return it:
Environment