Repository navigation
fix(hy-check): reject mismatched operand types in binary arithmetic and comparisons (fixes #922) - #1458
Closed
Ljunqiang wants to merge 1 commit into
Closed
fix(hy-check): reject mismatched operand types in binary arithmetic and comparisons (fixes #922)#1458Ljunqiang wants to merge 1 commit into
Ljunqiang wants to merge 1 commit into
Conversation
…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.
Ljunqiang
force-pushed
the
fix/issue-922-binop-operand-types
branch
from
October 24, 2026 12:16
47eb793 to
84a050e
Compare
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 |
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 #922
Root cause
BuildableChecker::check_binary_operandscompared numeric families, not concrete kinds:<<=>>=lk.is_numeric() != rk.is_numeric()intvsfloat64both numeric → never mismatched+x + faccepted-*/{Unknown, Int, Float}onlyx - f,x * 2.5acceptedAll six issue repros checked clean (0 diagnostics), then
go buildrefused each withinvalid operation: ... (mismatched types int and float64)— GUARANTEES.md Row 13 (BUILDABLE).Fix
New
Collector::numeric_adapt_conflict(lk, rk, lhs, rhs)— applied as anelse ifin the three arms — rejects cross-kind numeric pairs unless Go's only implicit numeric conversion bridges them:1 + 2.5,a + b(both untyped consts)f + 1,1 + f,f + k(untypedconst k = 1)float64adaptationx + 1,x < 10,s + "b",s < "c"x + f,f + x,x - f,x * f,x / fx < f,f <= x,x > f,x >= fx + 2.5,2.5 - x,x < 2.5intf + kwithconst k int = 1ktypedDefine.untyped_const(new field, from the already-recordedLocalDecl.ty) distinguishes fn-localconst k = 1fromconst k int = 1— the annotation existed but was never consulted (tightens #1112's fail-open on this site; assignment sites keep #1112's rule until a dedupe).Validation (all on this branch @ 47eb793)
hy-check/tests/binop_operand_types_issue_922.rs24/24 (15 reject faces, 9 accept controls)cargo test --workspacegreen except pre-existing local-CRLFspec_t3_strings(reproduces on cleanupstream/main)binop-mismatched-numeric-reject.hy—EXPECTED-VERDICT: REJECT BUILDABLE+HYB-E1002; census 126 → 127 on all 7 surfaces (parse-all assertion included)upstream/mainbuildable.rs) accepts the pin → harness 126/127 with the pin FAILing; restoring the fix → 127/127Credit / coordination
bot:stale-base+bot:conflict) proposed the same rule family with literal-only helpers — this take supersedes it with untyped-const-ident support (f + k) and the fn-local annotation check.numeric_adapt_conflictcarries a NOTE against Fixes #1112: typed int values no longer satisfy float64 targets (untyped-constant clause across all 20 value positions) #1447'sis_untyped_constant(near-identical walk) — thekinds_conflict/ PR fix(hy-check): close the call-arity and return-statement accept-side bypasses (#577 C9/C10) #620 duplicate-helper precedent; whoever lands second collapses the pair.