Repository navigation
fix(hir): infer bool && value as the value's type, not Boolean (#3527) - #3771
Merged
Merged
Conversation
`infer_type_from_expr` typed a logical `A && B` / `A || B` as A's type
whenever B inferred to `Any`. But `&&` yields B's value when A is truthy, so
the result can be the (unknown) right value — A's type is wrong. This mistyped
a common idiom:
var hasMap = typeof Map === "function" && Map.prototype; // → Boolean (!)
`hasMap` holds an object at runtime but was typed `Boolean`, so codegen treated
it as a boolean in a later `hasMap && d && typeof d.get === "function"` chain
(object-inspect's Map-size feature-detect), miscompiling the short-circuit and
dereferencing `null` → `TypeError: Cannot read properties of null (reading
'get')` while compiling Express (#3527).
Fix: when the right operand is `Any`, the logical result is `Any` (the value
could be that right operand), not the left operand's type. The concrete-right
heuristic (`x && knownTyped` → knownTyped) is unchanged. This only makes the
inferred type more dynamic (always codegen-safe), never less.
Verified: object-inspect's init works; the Express tree advances past it.
New gap test test_gap_logical_and_value_type.ts is byte-identical to Node.
This was referenced May 31, 2026
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.
Summary
infer_type_from_exprmis-typed a logicalA && B/A || Bas A's type whenever B inferred toAny. But&&yields B's value when A is truthy, so the result can be the (unknown) right value — A's type is wrong. This advances the #3527 Express compile past object-inspect.Root cause
A textbook feature-detect idiom:
hasMapholds an object at runtime but was typedBoolean(the left operand's type). Codegen then treated it as a boolean in object-inspect's later chain:miscompiling the short-circuit and dereferencing
null→TypeError: Cannot read properties of null (reading 'get')during init while compiling Express. (Minimal repro:var hm = typeof Map === "function" && Map.prototype; hm && null && (null).getthrows; the same chain withhmtypedanydoes not.)Fix
In
lower_types.rs, forLogicalAnd | LogicalOr: when the right operand isAny, the result isAny(the value could be that right operand), not the left operand's type. The concrete-right heuristic (x && knownTyped→knownTyped) is unchanged. This only makes the inferred type more dynamic — always codegen-safe, never less.Verification
test_gap_logical_and_value_type.ts(thehasMapidiom,&&/||returning the right value, chained property guards) — byte-identical to Node.cargo test -p perry-hirgreen. Pre-existing failures (bind_replace, async_hooks/perf_hooks timestamp nondeterminism) verified identical on baseline — not caused by this change.cargo fmt --checkclean.Part of the #3527 chain (prior: #3537/#3543/#3546, #3551, #3733, #3751, #3764). No version bump / changelog — folded in at merge per the worktree-PR convention.