Skip to content

[bug] t27o: str_chain never opens with a text field, so let t = n.value.trim(); t.starts_with(..) is refused while the inline chain converts #10834

Closed

Description

@gHashTag

What is wrong

str_chain (specs/tools/t27o/rust_convert.t27) is meant to tell that let t = node.value.trim(); binds a text when value is a text field of node's struct (its comment: "the chain may open with a text field of the head name's own type"; recv_class does the same for an inline chain). Its field branch tests the wrong thing:

if (f < src.len and is_alpha(src[f]) and fe <= b and tok_is(src, skip_ws(src, fe), "(")) {
    base = field_of_class(src, st, a, e, f, fe) == C_STR;
    c = skip_ws(src, fe);
}

It asks for a ( right after the field name, i.e. node.value( -- a method call, not a field -- and, when that holds, the loop that follows needs a . at c and returns false on the (. For node.value.trim() the token after value is ., so the branch is never taken, base stays false and str_chain answers false. recv_class's same step reads !tok_is(src, skip_ws(src, f0e), "(").

Repro (t27o of the branch of #10817)

pub struct Node { pub value: &'static str }
pub fn f(n: &Node) -> bool { let t = n.value.trim(); t.starts_with("a") }
pub fn g(n: &Node) -> bool { n.value.trim().starts_with("a") }

tri t27o converts g and refuses f: method starts_with``. The only difference is that f goes through the `let`, i.e. through name_class -> str_chain.

Expected

f converts like g: t is a text, so t.starts_with("a") takes the text entry of the std table.

Found by

Writing the direct tests of str_chain (lane C1 of #10522, issue #10825). The test that shows it is known_defect_str_chain_does_not_open_with_a_text_field in rust_convert.t27: it pins the current answer and flips when this is fixed.

User Scenarios

  • Given a Rust function f with let t = n.value.trim(); t.starts_with("a") where n.value is a text field, when t27o converts it, then the conversion succeeds because str_chain recognizes t as text via the field access.
  • Given a Rust function g with n.value.trim().starts_with("a") (inline chain), when t27o converts it, then the conversion succeeds as it does today.

Requirements

  • FR-001: str_chain in specs/tools/t27o/rust_convert.t27 MUST treat a field access (.) after the field name as a valid continuation for a text field, not require a method call (().
  • FR-002: The field branch condition MUST match recv_class's logic: allow . after the field and reject ( immediately after the field.
  • FR-003: The existing test known_defect_str_chain_does_not_open_with_a_text_field MUST flip from pinning the current (wrong) answer to expecting the fixed answer.

Success Criteria

  • tri t27o on the repro snippet converts both f and g without error (exit 0).
  • The test known_defect_str_chain_does_not_open_with_a_text_field in specs/tools/t27o/rust_convert.t27 passes (1 test).
  • t27c specs/tools/t27o/rust_convert.t27 compiles the spec without error (exit 0).

Boundary

  • specs/tools/t27o/rust_convert.t27

Activity

  1. added
    shape-refusedClosed by the issue-shape gate (specs/policy/issue_shape.t27); a passing edit reopens it
    on Oct 19, 2026
  2. github-actions commented on Oct 19, 2026

    @github-actions
    Contributor

    Closed by the issue-shape gate (specs/policy/issue_shape.t27, #7498): an issue must have the template's sections. Edit the body; an edit that passes reopens it.

    • missing: ## Boundary -- list every file this task may touch, one per line (- specs/x.t27); without it the Queen reserves nothing and no bee can take the issue
    • missing: ## User Scenarios -- at least one Given/When/Then scenario
    • missing: ## Requirements -- numbered obligations, FR-001: ... MUST ...
    • missing: ## Success Criteria -- an outcome a machine can settle: a number with a unit, a backticked file, exit 0, or a backticked command
  3. removed
    shape-refusedClosed by the issue-shape gate (specs/policy/issue_shape.t27); a passing edit reopens it
    on Oct 19, 2026
  4. gHashTag commented on Oct 19, 2026

    @gHashTag
    OwnerAuthor

    Reopened by the self-heal of #11007. The issue-shape gate closed this issue with a queued run that judged an older body from its event payload; the current body passes gen/c/policy/issue_shape.c, and the gate's own contract is that a passing body stays open. If the work is in fact finished or obsolete, close it as completed.

  5. added 3 commits that reference this issue on Oct 19, 2026
    838b29f
    c6f2ade
    b1077e9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions