Repository navigation
Conversation
… exits (limitlessprojects#1398) emit_return flushed O8/OQ slot loans at the top of the function, before the operands were evaluated: `return c.next()` stored the PRE-call value back into the map (bump printed `11 10` instead of `11 11`), and the propagate-error (`?`) exits never flushed at all, dropping every mutation performed before the failing call (printed `10` instead of `42`). Materialise non-trivial operands (everything except Ident/FnLit/Lit) into temps, flush the live loans, then return the temps; propagate_error and the E11 handler flush before their early returns. Loans-inactive emission is byte-identical, so no existing output moved. Pinned by 2 hy-emit tests (eval < store-back < return; store-back < propagate-error return) and the corpus fixture slot-loan-return-operand-flush (EXPECTED-OUTPUT locks `bump: 11 11 try: 42`); corpus census 126 -> 127. Verified: harness 127/127, differential accept 41/41 + reject 86/86, cargo test hy-emit / hy-syntax green.
Ljunqiang
pushed a commit
to Ljunqiang/Go-Hybrid
that referenced
this pull request
Oct 24, 2026
…nd comparisons (fixes limitlessprojects#922) Root cause: check_binary_operands compared numeric FAMILIES, not concrete kinds — for `< <= > >=` and `+` the mismatch term was `lk.is_numeric() != rk.is_numeric()` (int and float64 are both numeric, so never mismatched), and `- * /` only checked kind membership. `x + f`, `x - f`, `x * f`, `x / f`, `x < f`, `f <= x` checked clean while go build refused each with `mismatched types int and float64` (GUARANTEES Row 13). Fix: a new Collector::numeric_adapt_conflict routes cross-kind operand pairs through Go's only implicit numeric conversion — untyped-constant adaptation — and emits HYB-E1002 when it cannot bridge them: - `1 + 2.5` (both untyped) and `f + 1` / `1 + f` (int const -> float64) keep building, including untyped `const` identifiers (`f + k`); - `x + f`, `f + x`, `x - f`, `x < f`, `f <= x`, and the untyped float const against a typed int (`x + 2.5`) are rejected; - `Define.untyped_const` (from LocalDecl.ty) distinguishes `const k = 1` (untyped) from `const k int = 1` (typed like a variable) for fn-local consts — the annotation was recorded but never consulted. Validation: new hy-check/tests/binop_operand_types_issue_922.rs 24/24 (15 reject faces + 9 accept controls); corpus pin binop-mismatched-numeric-reject.hy (REJECT BUILDABLE + HYB-E1002), census 126 -> 127 on all 7 surfaces; harness 127/127, tripwire not fired; negative flip: baseline upstream accepts the pin (126/127, pin FAILs) and restores to 127/127; differential 40/40 accept + 87/87 reject; cargo test --workspace green except the pre-existing local-CRLF spec_t3_strings failure (reproduces on clean HEAD). Harvest credit: stale companion rickymulya PR limitlessprojects#923 (bot:stale-base + bot:conflict) proposed the same family of rules with literal-only helpers; this take supersedes it with const-ident support and the untyped_const annotation check. Coordination: limitlessprojects#1428, limitlessprojects#1430 and limitlessprojects#1447 also bump census 126 -> 127 — the PR that lands last rebases the count to 128+. The numeric_adapt_conflict doc carries a dedupe NOTE against limitlessprojects#1447's is_untyped_constant (the kinds_conflict / PR limitlessprojects#620 duplicate-helper precedent) for whoever lands second.
Owner
|
Queue-reset sweep: this repo now runs a rolling conveyor, and open PRs This is not a verdict on the work. If this change still matters:
Wildcard holds (verdict window 2026-11-01) and Pareto land candidates are |
Ljunqiang
pushed a commit
to Ljunqiang/Go-Hybrid
that referenced
this pull request
Oct 24, 2026
…nd comparisons (fixes limitlessprojects#922) Root cause: check_binary_operands compared numeric FAMILIES, not concrete kinds — for `< <= > >=` and `+` the mismatch term was `lk.is_numeric() != rk.is_numeric()` (int and float64 are both numeric, so never mismatched), and `- * /` only checked kind membership. `x + f`, `x - f`, `x * f`, `x / f`, `x < f`, `f <= x` checked clean while go build refused each with `mismatched types int and float64` (GUARANTEES Row 13). Fix: a new Collector::numeric_adapt_conflict routes cross-kind operand pairs through Go's only implicit numeric conversion — untyped-constant adaptation — and emits HYB-E1002 when it cannot bridge them: - `1 + 2.5` (both untyped) and `f + 1` / `1 + f` (int const -> float64) keep building, including untyped `const` identifiers (`f + k`); - `x + f`, `f + x`, `x - f`, `x < f`, `f <= x`, and the untyped float const against a typed int (`x + 2.5`) are rejected; - `Define.untyped_const` (from LocalDecl.ty) distinguishes `const k = 1` (untyped) from `const k int = 1` (typed like a variable) for fn-local consts — the annotation was recorded but never consulted. Validation: new hy-check/tests/binop_operand_types_issue_922.rs 24/24 (15 reject faces + 9 accept controls); corpus pin binop-mismatched-numeric-reject.hy (REJECT BUILDABLE + HYB-E1002), census 126 -> 127 on all 7 surfaces; harness 127/127, tripwire not fired; negative flip: baseline upstream accepts the pin (126/127, pin FAILs) and restores to 127/127; differential 40/40 accept + 87/87 reject; cargo test --workspace green except the pre-existing local-CRLF spec_t3_strings failure (reproduces on clean HEAD). Harvest credit: stale companion rickymulya PR limitlessprojects#923 (bot:stale-base + bot:conflict) proposed the same family of rules with literal-only helpers; this take supersedes it with const-ident support and the untyped_const annotation check. Coordination: limitlessprojects#1428, limitlessprojects#1430 and limitlessprojects#1447 also bump census 126 -> 127 — the PR that lands last rebases the count to 128+. The numeric_adapt_conflict doc carries a dedupe NOTE against limitlessprojects#1447's is_untyped_constant (the kinds_conflict / PR limitlessprojects#620 duplicate-helper precedent) for whoever lands second.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1398.
Bug
hy-emitflushed O8/OQ slot loans at the top ofemit_return— before the operands were evaluated — and the?error-propagation exits never flushed at all:return c.next()wrotem["k"] = cback pre-call: the post-call map kept the stale value (bump: 11 10instead ofbump: 11 11), and the evaluated result came from the loan's own copy, not the map.c.n = 42; x := fail_step()?dropped the42entirely on the propagate-error return (printed10instead of42).Fix (compiler/crates/hy-emit/src/stmt.rs)
emit_return: with live loans, materialise every non-trivial operand into a temp (hyRetN := <expr>; Ident/FnLit/Lit pass through untouched —nilwould not even build ashyRet := nil), then flush, then return the temps. Evaluation and write-back now straddle the flush exactly as the runtime contract requires.propagate_error: flush before its three early-return branches (covers every?exit, incl. the emitter's httptest helper).handler_writer+http.Error) flushes before its earlyreturntoo.has_live_loanshelper mirrorsflush_loans_for_return's sentinel-frame skip exactly.With no live loans the emission path is untouched (byte-identical), so no existing golden output moved —
loan_terminator/closure_loantests still pass unchanged.Regression pins
hy-emit/tests/loan_terminator.rs: +2 tests (eval < store-back < return; store-back < propagate-error return).tests/checker-corpus/slot-loan-return-operand-flush.hy(ACCEPT, Tier-0,--deny-managedclean) withEXPECTED-OUTPUT: bump: 11 11 try: 42locking both the return path and the?path at runtime. Census 126 → 127 (ACCEPT 39 · AM 2 · REJECT 86); VERDICTS.md + README registration appended.Verification
cargo test -p hy-emit/-p hy-syntax: green (incl. the 2 new tests,parse_allnow asserts 127).tools/corpus_harness.py: 127/127, tripwire not fired.tools/differential_loop.py: accept-side 41/41 (build+run, stdout matched), reject-side 86/86.REJECT A1b→ harness 126/127;EXPECTED-OUTPUTflipped tobump: 11 10 try: 42→ differential 40/41 with exact stdout-mismatch; both restored to green.bump: 11 11/try: 42.Note: sibling PR #1190 also moves the census numbers (126 → 130 with 4 REJECT pins). Whichever lands second rebases and renumbers.