Skip to content

Commit aaef434

Browse files
Fix non-converging generic parameter inference loop (review doc A3) (#216)
Two defects fed each other in resolveGenericParamsFromFunctionCall: - optional/multi-args params past the call operands were counted as progress every round without being marked processed, inflating totalProcessed past the == termination check - the origin of the "loop detected" +100 guard. They are now marked processed and counted once. - that double-counting was also load-bearing: for signatures like reduce2<T, V = T>(..., initial?: V) a callback param typed by a defaulted type param can never resolve inside the loop (defaults zip after it), and only the inflated count let the loop exit. A no-progress round now breaks out instead of erroring, letting the default zipping and the existing completeness check decide. The +100 guard is now defensive-only (each param counted at most once). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent de6b8ca commit aaef434

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

tslang/lib/TypeScript/MLIRGen.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,15 +2577,19 @@ class MLIRGenImpl
25772577

25782578
if (callOpsCount <= paramIndex)
25792579
{
2580-
// there is no more ops
2580+
// there is no more ops; mark processed so the param is counted once -
2581+
// recounting it every round inflated totalProcessed past the termination
2582+
// equality below and spun the loop into the "loop detected" guard
25812583
if (paramInfo->getIsOptional() || isa<mlir_ts::OptionalType>(paramType))
25822584
{
2585+
paramInfo->processed = true;
25832586
processed++;
25842587
continue;
25852588
}
25862589

25872590
if (paramInfo->getIsMultiArgsParam())
25882591
{
2592+
paramInfo->processed = true;
25892593
processed++;
25902594
continue;
25912595
}
@@ -2640,8 +2644,11 @@ class MLIRGenImpl
26402644

26412645
if (processed == 0)
26422646
{
2643-
emitError(location) << "not all types could be inferred";
2644-
return mlir::failure();
2647+
// no progress in a full round: some params (e.g. a callback typed by a
2648+
// type param that only gets its value from a default) can't be inferred
2649+
// here; the default zipping and the completeness check below decide
2650+
// whether that is an error
2651+
break;
26452652
}
26462653

26472654
totalProcessed += processed;
@@ -2653,7 +2660,7 @@ class MLIRGenImpl
26532660

26542661
if (totalProcessed > funcOp->getParams().size() + 100)
26552662
{
2656-
// TODO: find out the issue
2663+
// defensive only: with params counted exactly once this is unreachable
26572664
emitError(location) << "loop detected.";
26582665
return mlir::failure();
26592666
}

0 commit comments

Comments
 (0)