Skip to content

An inline # comment on a struct field deletes the next field, in every backend, and both stages accept it #3243

Description

@gHashTag

An inline # comment on a struct field consumes the rest of the line and the
declaration that follows it
. The following field is deleted from every backend, and
both parse and typecheck accept the spec.

Five lines, and a field disappears

module probe {
    pub const Thing = struct {
        a : Float  # note,
        b : String,
    };
}
stage verdict
t27c parse ACCEPTS
t27c typecheck ACCEPTS
gen-rust pub a: Floatb:String, — one field
gen (Zig) a: Floatb:String, — one field
gen-c Floatb:String a; — one field

All three backends agree, and all three are wrong the same way. Field b is gone.

A 2×2 that killed my first hypothesis

I first thought this needed a non-primitive type. It does not:

type fields out
u8 2 ✓
u8 # note 1 ✗
Float 2 ✓
Float # note 1 ✗

My earlier probe looked healthy only because the commented field was the last one,
so there was nothing left to swallow.

Measured on the corpus

specs/tri/pipeline/pipeline_parallel.t27 loses four declarations to one comment:

pub id: U8command:Stringargs:Stringgroup_id:U8status:JobStatus,

Durable evidence was already on disk: 11 seal files under .trinity/seals/ are
named after the wreckage rather than after a module — "[]const u8", Str = "",,
String # phi, trinity, gematria, evolution, safety. Each points at a spec that
exists and already has a correctly-named seal, so they are extra seals created from a
parse artifact.

Shipped with it: a new shape in tri misread

rust: pub a: Xb:Y, — a bare colon inside a type. A Rust type never has one; a
path spells its separator ::.

It is named for what the output shows, not for a cause, and that took a correction:
I called it RustSwallowedField first, and the corpus answered with two of eight hits
being something else — pub env: Vec<str:str>, a map type [str: str] the emitter
cannot spell. Same footprint, different wreck. The module's own header says to name a
shape by the output because the intent is exactly what was lost, and I broke that rule
on the first try.

The census now reads 22 / 1 / 0 / 1 / 8 with all five shapes firing on the control.

Not proposed here

The repair is in the lexer or the field parser, which is further upstream than
anything this pass has touched, and the correct behaviour of # inside a declaration
is a language question rather than a mapping one.

Boundary

  • specs/tri/pipeline/pipeline_parallel.t27

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

    needs-boundaryNo '## Boundary' section, so the Queen can reserve nothing for it and no bee can take it

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions