parse_float("abc") fails with an empty message:
fn main() -> Int:
r := parse_float("abc")
if r.is_err:
print("err=[" + r.err + "] len=" + r.err.len().to_string())
n := parse_int("zz")
if n.is_err:
print("int err=[" + n.err + "]")
return 0
prints err=[] len=0 and int err=[invalid integer] on main at e22c5a6.
Mechanism: ir_emit_wrapped_legacy_result (self-host/ir_emitter_core.pith) builds the error box with ir_emit_result_error_message(callee_name) (self-host/ir_result_abi.pith), which calls ir_str(callee_name + " failed") while the function body is being emitted. The string table has already been written by then, so the literal is appended to a table nobody emits again and the strref names an index the table does not define (strref 22 m8s411 where module 8's table ends at m8s410). The ir consumer resolves an undefined string reference to a null string (cranelift/codegen/src/ir_consumer.rs, the strref arm, "a strref may name a string defined in another compilation unit"), so the message reads as empty. Every std.json importer carries these dangling references, in std_json_json_float_of_text among others; only parse_float is affected among the builtins because parse_int has its own retkind and message.
ir_str_interned exists for this situation. The fix shape is to intern <callee> failed for every legacy-wrapped builtin in the string prepass, or to route the message through a runtime call that needs no literal. tooling/ir_normalize.py folds an undefined reference to str(<undefined>) so an ir_compare run reads through it; the dangling references themselves are unchanged by that.
Found while classifying an ir_compare run for the json collection decode work; not fixed there.
parse_float("abc")fails with an empty message:prints
err=[] len=0andint err=[invalid integer]on main at e22c5a6.Mechanism:
ir_emit_wrapped_legacy_result(self-host/ir_emitter_core.pith) builds the error box withir_emit_result_error_message(callee_name)(self-host/ir_result_abi.pith), which callsir_str(callee_name + " failed")while the function body is being emitted. The string table has already been written by then, so the literal is appended to a table nobody emits again and thestrrefnames an index the table does not define (strref 22 m8s411where module 8's table ends atm8s410). The ir consumer resolves an undefined string reference to a null string (cranelift/codegen/src/ir_consumer.rs, thestrrefarm, "a strref may name a string defined in another compilation unit"), so the message reads as empty. Every std.json importer carries these dangling references, instd_json_json_float_of_textamong others; onlyparse_floatis affected among the builtins becauseparse_inthas its own retkind and message.ir_str_internedexists for this situation. The fix shape is to intern<callee> failedfor every legacy-wrapped builtin in the string prepass, or to route the message through a runtime call that needs no literal. tooling/ir_normalize.py folds an undefined reference tostr(<undefined>)so an ir_compare run reads through it; the dangling references themselves are unchanged by that.Found while classifying an ir_compare run for the json collection decode work; not fixed there.