Skip to content

parse_float's error message is empty: the legacy result wrap interns its literal after the string table is emitted #1147

Description

@kacy

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions