HaxeFoundation / HaxeFoundation/haxe

JS Bytes.toHex infers a nullable hexadecimal lookup table

Open Beginner friendly
#13,003 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haxe
Stars
6.9k
Forks
715
Avg merge
2d 2h
Merged PRs (30d)
11

Description

## Why

On the JavaScript target, `String.charCodeAt(index)` correctly returns `Null` because an arbitrary index may be out of range.

`haxe.io.Bytes.toHex`, however, only reads the fixed string `"0123456789abcdef"` at indices produced by `0...str.length`, so every value inserted into its lookup table is an `Int`:

```haxe
var chars = [];
var str = "0123456789abcdef";
for (i in 0...str.length)
chars.push(str.charCodeAt(i));
```

Because `chars` is unannotated, the JS stdlib currently types it as `Array>` even though the loop establishes an integer-only table.

This becomes observable to custom typed JavaScript generators. `StringBuf.addChar(c:Int)` and `String.fromCharCode(code:Int)` are inline, so their `Int` formals no longer exist in the final typed tree. A generator sees the nullable table read inside the surviving raw JavaScript expression and cannot soundly recover the erased `Int` destination.

For example, a strict TypeScript surface can consequently reach the equivalent of:

```ts
const chars: Array = [];
String.fromCodePoint(chars[index] ?? null);
```

TypeScript correctly rejects `number | null` as the argument of `String.fromCodePoint(number)`.

## Proposed fix

State the local invariant where the lookup table is built:

```diff
-var chars = [];
+var chars:Array = [];
```

This preserves an ordinary typed `Null -> Int` boundary at `Array.push`. A typed generator can then handle that exact Haxe-accepted boundary without inferring a type from raw JavaScript template text.

## Compatibility

The annotation is type-only. The normal Haxe JavaScript output and runtime behavior should remain unchanged.

Prepared by the GameCarry agent.

Contributor guide

Open the contributing guide

Research direction

Start at haxe.io.Bytes.toHex and inspect the lookup table built from "0123456789abcdef". State its integer element type, then verify that JavaScript output and runtime behavior remain unchanged and that the typed generator no longer sees a nullable table.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
compilers
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.