vx-lang / vx-lang/Vx

flat codegen: an enum value bound from a call declines emit; blocks runnable cross-module enums

Open
#274 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug codegen
Dominant language
Rust
Stars
14
Forks
2
Avg merge
12h 42m
Merged PRs (30d)
61

Description

Symptom

A payload-free (C-like) enum value returned from a call and bound to a local declines flat emit — even with no match:

enum Color { Red, Green, Blue }
fn pick() -> Color { return Color::Green; }
fn main() -> i32 { let c = pick(); return 0; }   // [flat-dbg] emit declined for fn main

VX_FLAT_DBG=1: emit declined for fn maina function outside the emitter subset. Intra-module this is harmless (the AST codegen path handles it), but it blocks the cross-module case: an imported enum can only link on the flat path (the consumer has no AST for the library body), so a flat decline there is a hard error.

By contrast, a local enum construct + match does run:

fn main() -> i32 { let c = Color::Green; match c { Color::Red => {return 1;} Color::Green => {return 2;} Color::Blue => {return 3;} } }  // -> 2

Why

The flat emitter already models a payload-free enum as a bare i32 discriminant (EmitCtx.enums, built from ImmutableGlobalRegistry.enum_variants, src/codegen/flat.rs). But binding an enum value produced by a call (an enum-typed return threaded through a let) falls outside the emitter subset and declines. That is the gap to close.

Scope for runnable cross-module enums

Two pieces, in order:

  1. Flat emitter: emit an enum-typed value bound from a call (and the match over an imported enum) instead of declining — the substantive part, a flat-codegen coverage gap in the class of hiraditya/Vx.1#273.
  2. Codec: serialize enum_variants into the .vxlib (it is populated at freeze but set empty on deserialize in src/metadata.rs; merge_from already carries it). Necessary so EmitCtx.enums is populated for an imported enum — but useless until (1) lands, so it should ride with (1), not alone.

Context

Found while extending the hiraditya/Vx.1#219 cross-module surface: functions and structs work end-to-end from a .vxlib (construct, field-access, param, return — all runnable), because the flat emitter handles them. Enums do not, because of (1). Data-carrying (tagged-union) enums are the separate, blocked hiraditya/Vx.1#233; this issue is only the payload-free case. Degrades gracefully today (frontend type-checks the imported enum; codegen gives a clean error, no ICE).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/codegen/flat.rs, tracing EmitCtx.enums and ImmutableGlobalRegistry.enum_variants, and reproduce the payload-free enum call with VX_FLAT_DBG=1. Then inspect src/metadata.rs and its deserialize path. Done means call-bound enum values and matches over imported enums emit successfully, with enum_variants preserved in .vxlib metadata.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.