With --no-default-lib (which is how the test suite compiles), the result of the built-in .map/.filter can't be used as an array. Chaining them fails to compile under every memory model (gc, rc, none, own), and the error shown doesn't say why. With the default library it all works, and prints 3 5 7.
function main() {
const a: number[] = [1, 2, 3];
for (const v of a.map(x => x * 2).map(x => x + 1)) print(v);
}
tslang --emit=jit --no-default-lib chain.ts
chain.ts:1:1: error: the condition has no value
chain.ts:1:1: error: failed statement
a.filter(f).map(g) fails the same way, and so does splitting the chain into const m = a.map(f); for (const v of m.map(g)) ....
There are two problems here.
1. The built-in .map/.filter return a generator, not an array
mlirGenArrayMap and mlirGenArrayFilter (MLIRGenImpl.h) build function* .iter() { for (const v of .src_array) yield .func(v); }, call it, and return the generator object. In TypeScript, map and filter return an array. So anything except iterating the result fails:
const m = a.map(x => x * 2);
for (const v of m) print(v); // ok
m.next(); // ok
m.map(x => x + 1); // error: Can't resolve property 'map' of type {.step:s32, .i:s32, .a:number[], ..., next(): {value:number, done:boolean}, .captured:...}
m.forEach(x => print(x)); // the same error, for 'forEach'
m.length; m[0]; // the same error, for 'length'
Possible fixes:
- Collect the yielded values into a new array, which gives TypeScript's semantics.
- Keep the generator but give it array-like methods.
- At least report
.map on a .map result as unsupported.
2. The real error is replaced by "the condition has no value"
Outside a condition, the message is accurate (Can't resolve property 'map' of type ..., with its position). In a condition, the only error is "the condition has no value":
const o = { x: 1 };
if (o.foo) print(1); // 3:25: error: the condition has no value
for (const v of a.map(f).map(g)) print(v); // 1:1: error: the condition has no value
In the for...of case the position is 1:1, the start of the function, so nothing points at the line either.
A likely cause: mlirGenPropertyAccessExpression returns success with no value, and no message, during a dummyRun/allowPartialResolve run (MLIRGenAccessCall.cpp, around line 400). Then conditionHasValue (MLIRGenImpl.h) finds no value and reports its own generic message. The "Can't resolve property" message is never emitted, because the real run doesn't reach the access.
Found while testing -mm=own phase 7b (#441); the chained .map was removed from own_generator_borrow.ts because of this.
With
--no-default-lib(which is how the test suite compiles), the result of the built-in.map/.filtercan't be used as an array. Chaining them fails to compile under every memory model (gc, rc, none, own), and the error shown doesn't say why. With the default library it all works, and prints3 5 7.a.filter(f).map(g)fails the same way, and so does splitting the chain intoconst m = a.map(f); for (const v of m.map(g)) ....There are two problems here.
1. The built-in
.map/.filterreturn a generator, not an arraymlirGenArrayMapandmlirGenArrayFilter(MLIRGenImpl.h) buildfunction* .iter() { for (const v of .src_array) yield .func(v); }, call it, and return the generator object. In TypeScript,mapandfilterreturn an array. So anything except iterating the result fails:Possible fixes:
.mapon a.mapresult as unsupported.2. The real error is replaced by "the condition has no value"
Outside a condition, the message is accurate (
Can't resolve property 'map' of type ..., with its position). In a condition, the only error is "the condition has no value":In the
for...ofcase the position is 1:1, the start of the function, so nothing points at the line either.A likely cause:
mlirGenPropertyAccessExpressionreturns success with no value, and no message, during adummyRun/allowPartialResolverun (MLIRGenAccessCall.cpp, around line 400). ThenconditionHasValue(MLIRGenImpl.h) finds no value and reports its own generic message. The "Can't resolve property" message is never emitted, because the real run doesn't reach the access.Found while testing
-mm=ownphase 7b (#441); the chained.mapwas removed fromown_generator_borrow.tsbecause of this.