What happened
I found Map/Set inside class instance field doesn't work in for...of loop
What you expected
It should works like module level Map/Set do
Minimal reproduction
/**
* Minimal reproduction for Perry bug:
* `for...of` loop body is silently skipped when the iterable is a class instance field Map or Set.
*
* Tested with: ~/Projects/perry/target/release/perry (latest local build)
* Reproduces with: perry test_minimal_repro.ts && ./test_minimal_repro
*
* Expected output (Bun / Node.js):
* class Map size: 2
* class Map for...of:
* entry 1 -> a
* entry 2 -> b <-- Perry: MISSING
* class Set size: 2
* class Set for...of:
* elem x <-- Perry: MISSING
* elem y <-- Perry: MISSING
* module-level Map (works in Perry):
* entry 1 -> x
* entry 2 -> y
*
* Actual Perry output:
* class Map size: 2
* class Map for...of: <-- loop body never executes
* class Set size: 2
* class Set for...of: <-- loop body never executes
* module-level Map (works in Perry):
* entry 1 -> x
* entry 2 -> y
*
* Notes:
* - .size, .get(), .has(), .set(), .add(), .clear() all work correctly on class field Map/Set
* - for...of on class field Array works correctly
* - for...of on module-level Map/Set works correctly
* - Affects both `private` and `public` class fields
* - Affects both same-file and imported classes
*/
class Example {
public classMap: Map<number, string> = new Map();
public classSet: Set<string> = new Set();
run(): void {
this.classMap.set(1, "a");
this.classMap.set(2, "b");
this.classSet.add("x");
this.classSet.add("y");
// .size works correctly
console.log("class Map size:", this.classMap.size); // 2 ✓
console.log("class Map for...of:");
for (const [k, v] of this.classMap) {
console.log(" entry", k, "->", v); // Perry: never printed ✗
}
console.log("class Set size:", this.classSet.size); // 2 ✓
console.log("class Set for...of:");
for (const v of this.classSet) {
console.log(" elem", v); // Perry: never printed ✗
}
}
}
new Example().run();
// Module-level Map/Set: for...of works correctly in Perry
const m = new Map<number, string>([
[1, "x"],
[2, "y"],
]);
console.log("module-level Map (works in Perry):");
for (const [k, v] of m) {
console.log(" entry", k, "->", v); // Perry: works ✓
}
Command you ran:
Environment
- Perry version: 0.5.386
- Host OS: ArchLinux
- Target: native
- Rust toolchain (if building from source): rustc 1.95.0 (59807616e 2026-04-14)
- Installed via: from source
Diagnostic output
Perry Doctor
Environment Checks
──────────────────
✓ perry version: 0.5.386
✓ update status: up to date
✓ clang (LLVM codegen): clang version 22.1.3
✓ system linker (cc): cc (GCC) 15.2.1 20260209
✓ runtime library: /home/codehz/Projects/perry/target/release/libperry_runtime.a
⚠ project config (perry.toml): not found - run: perry init
All critical checks passed with some warnings.
Anything else
I found it in my ecs demo, it hit infinite loop, so I create a minimal repro it using AI
What happened
I found Map/Set inside class instance field doesn't work in for...of loop
What you expected
It should works like module level Map/Set do
Minimal reproduction
Command you ran:
perry test.ts && ./testEnvironment
Diagnostic output
Anything else
I found it in my ecs demo, it hit infinite loop, so I create a minimal repro it using AI