Skip to content

feat(monomorphize): enforce closure-signature conformance for call-argument literals #67

feat(monomorphize): enforce closure-signature conformance for call-argument literals

feat(monomorphize): enforce closure-signature conformance for call-argument literals #67

Triggered via pull request July 13, 2026 23:07
Status Success
Total duration 42m 51s
Artifacts –

ci-core.yml

on: pull_request
Matrix: phpunit
PHPStan
22s
PHPStan
PHPStan pass (xphp check)
28s
PHPStan pass (xphp check)
xphp check (self-test)
11s
xphp check (self-test)
Mutation testing
42m 3s
Mutation testing
Fit to window
Zoom out
Zoom in

Annotations

16 warnings
xphp check (self-test)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809, actions/checkout@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
PHPUnit (PHP 8.5)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809, actions/checkout@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
PHPStan
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809, actions/checkout@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
PHPUnit (PHP 8.4)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809, actions/checkout@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
PHPStan pass (xphp check)
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809, actions/checkout@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
Mutation testing
Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809, actions/checkout@v4, actions/upload-artifact@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
Mutation testing: src/Transpiler/Monomorphize/Compiler.php#L324
Escaped Mutant for Mutator "Continue_": @@ @@ if ($definition === null) { if ($resilient) { $skip[$generatedFqn] = true; - continue; + break; } throw new RuntimeException( Registry::undefinedTemplateMessage($instantiation->templateFqn, $generatedFqn),
Mutation testing: src/Transpiler/Monomorphize/Compiler.php#L323
Escaped Mutant for Mutator "TrueValue": @@ @@ $definition = $registry->definition($instantiation->templateFqn); if ($definition === null) { if ($resilient) { - $skip[$generatedFqn] = true; + $skip[$generatedFqn] = false; continue; } throw new RuntimeException(
Mutation testing: src/Transpiler/Monomorphize/Compiler.php#L309
Escaped Mutant for Mutator "DecrementInteger": @@ @@ /** @var array<string, true> $skip instantiations that could not be specialized (resilient mode only) */ $skip = []; $closer = new SpecializationCloser($hierarchy, new VarianceSubtyping($hierarchy), $this->specializer, $this->hashLength); - $depth = 0; + $depth = -1; while (true) { $countBefore = count($registry->instantiations()); $newlyProcessed = false;
Mutation testing: src/Transpiler/Monomorphize/ClosureSignatureParam.php#L25
Escaped Mutant for Mutator "FalseValue": @@ @@ public function __construct( public SigType $type, public bool $byRef = false, - public bool $variadic = false, + public bool $variadic = true, public bool $optional = false, ) { }
Mutation testing: src/Transpiler/Monomorphize/ClosureSignatureParam.php#L24
Escaped Mutant for Mutator "FalseValue": @@ @@ { public function __construct( public SigType $type, - public bool $byRef = false, + public bool $byRef = true, public bool $variadic = false, public bool $optional = false, ) {
Mutation testing: src/Transpiler/Monomorphize/ClosureSignatureConformance.php#L98
Escaped Mutant for Mutator "Continue_": @@ @@ $candidateParam = $candidateParams[$i] ?? $this->variadicTailOf($candidateParams); if ($candidateParam === null) { - continue; + break; } if ($this->provablyNotSubtype($targetParam->type, $candidateParam->type)) { return new ClosureConformanceViolation(
Mutation testing: src/Transpiler/Monomorphize/ClosureSignature.php#L28
Escaped Mutant for Mutator "FalseValue": @@ @@ public function __construct( public array $params, public ?SigType $return, - public bool $nullable = false, + public bool $nullable = true, ) { } }
Mutation testing: src/Transpiler/Monomorphize/ClosureConformanceValidator.php#L524
Escaped Mutant for Mutator "UnwrapArrayValues": @@ @@ { $index = []; foreach ($node->getMethods() as $method) { - $index[$method->name->toLowerString()] = array_values($method->params); + $index[$method->name->toLowerString()] = $method->params; } return $index; }
Mutation testing: src/Transpiler/Monomorphize/ClosureConformanceValidator.php#L438
Escaped Mutant for Mutator "FunctionCallRemoval": @@ @@ if ($node instanceof Function_ || $node instanceof ClassMethod || $node instanceof Closure) { array_pop($this->returnTypeNodes); } elseif ($node instanceof ClassLike) { - array_pop($this->selfMethodParams); + } return null;
Mutation testing: src/Transpiler/Monomorphize/ClosureConformanceValidator.php#L435
Escaped Mutant for Mutator "LogicalOr": @@ @@ public function leaveNode(Node $node): null { - if ($node instanceof Function_ || $node instanceof ClassMethod || $node instanceof Closure) { + if ($node instanceof Function_ && $node instanceof ClassMethod || $node instanceof Closure) { array_pop($this->returnTypeNodes); } elseif ($node instanceof ClassLike) { array_pop($this->selfMethodParams);