Repository navigation
?? takes the right side only for null or undefined, and a number never equals null - #431
Merged
Merged
Conversation
…ver equals null
`n ?? -1` for `n?: number` tested the value's truthiness, so `f(0)` gave -1, and
compared every left value with null through a cast to a pointer ("invalid cast from
'f64' to '!llvm.ptr'"); `s ?? "x"` for `s?: string` and `y ?? 8` for `number | null`
did not compile. The test is now chosen by the left side's type (mlirGenIsNullish):
an optional is nullish when it has no value (its value is tested only when there is
one), a value type never, a union / any / reference is compared with null and with
undefined. The result type is the left side's without null and undefined, or the
right side's when the left can only be nullish.
`n === null` / `n == null` for a number compared it with null read as 0, so `0 === null`
was true, also for an optional number holding 0, and `x === null` for `0 | 1 | 42` failed
in LLVM lowering. foldNullishCompare gives the answer the type implies; `mlirGen(BinaryExpression)`'s
value part is now mlirGenBinaryValues, so `??` uses the same compare.
A finished generator's `{value: undefined, done: true}` of a value type built its zero
through a cast that warned "using casting to undefined value" in every such generator;
the field now takes the zero directly (InternalFlags::GeneratorDoneValue).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem
n ?? -1forn?: number:f(0)returned -1;nullthrough a cast to a pointer, which warnedinvalid cast from 'f64' to '!llvm.ptr';number | undefined.s ?? "x"fors?: string, andy ?? 8fornumber | null, did not compile.0 === nullwas true, becausenullwas read as 0. The same happened for an optional number holding 0.x === nullforx: 0 | 1 | 42failed in LLVM lowering ('llvm.icmp' op requires all operands to have the same type).using casting to undefined value. The warning came from the generator's finished{value: undefined, done: true}.Fix
??now tests whether the left side is null or undefined according to its type (mlirGenIsNullish):anyor a pointer type is compared withnulland withundefined.a ?? bisa's type withoutnullandundefined, combined withb's. Whenacan only be nullish, it isb's type.null/undefinedwhose answer the type already decides are folded (foldNullishCompare):=== null;== nullexactly when it has no value.mlirGen(BinaryExpression)is nowmlirGenBinaryValues, so??uses the same compare. Behaviour is unchanged.InternalFlags::GeneratorDoneValue). That is what the cast already lowered to. Other types keep the cast, so a string still gets the text"undefined".Tests
00nullish_values.ts, run as compile and jit. It passes under gc, rc and none.-mm=own.🤖 Generated with Claude Code