Skip to content

Commit 7a512e0

Browse files
committed
Check original type for unresolvable types only when resolved type has one
In `FunctionCallParametersCheck::check()`, each argument's resolved parameter type and original parameter type were both passed to `UnresolvableTypeHelper::getUnresolvableType()`, and only afterwards did the code check whether the resolved type actually had an unresolvable type. The original type is only reported as an error when the resolved type has an unresolvable type and the original one does not, so walking the original type was wasted work whenever the resolved type was fine. This reorders the check to walk the resolved type first and only then the original type, with the same reordering applied to the return type check a few lines below. Both calls are pure, so the reported errors are unchanged. `getUnresolvableType()` walks the whole type, which gets expensive on large array shapes. The `CssStyles` shape from symfony/ux-css has 847 keys, 144 of them a nested shape alias; every call site using it as a parameter type paid for two full walks of that shape, and the second one was almost never needed. TwigStan, which compiles templates to PHP, would produce such calls for every `css()` in a template. Benchmark: 50 calls to `CssRuntime::css()` with literal arrays (3 to 8 keys, up to two nested conditions like `_hover` or `md`) spread over 10 classes, analysed against the reproducer's nested shape ([sf-ux-css-phpstan-reproducer](https://github.com/Kocal/sf-ux-css-phpstan-reproducer), `phpstan-nested.neon`), `--debug`, interleaved runs: | Scenario | Before | After | |---|---|---| | 2.3.x, no turbo | 1 min 12 s | 48.5-49.1 s | | 2.3.x, turbo | 21.99-22.16 s | 14.43-14.54 s | | 2.3.x + #6652 + #6671 + #6672 + #6673, no turbo | 2.05-2.11 s | 1.74-1.75 s | `make tests` passes with and without the turbo extension, `make phpstan` and `make cs` pass. Refs phpstan/phpstan#15348
1 parent 0e156a6 commit 7a512e0

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

‎src/Rules/FunctionCallParametersCheck.php‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,9 @@ public function check(
418418

419419
$unresolvableParameterType = $this->unresolvableTypeHelper->getUnresolvableType($parameterType);
420420
if (
421-
$originalParameter !== null
421+
$unresolvableParameterType !== null
422+
&& $originalParameter !== null
422423
&& $this->unresolvableTypeHelper->getUnresolvableType($originalParameter->getType()) === null
423-
&& $unresolvableParameterType !== null
424424
) {
425425
$errorBuilder = RuleErrorBuilder::message(sprintf(
426426
$unresolvableParameterTypeMessage,
@@ -644,8 +644,8 @@ static function (Type $type, callable $traverse) use (&$returnTemplateTypes): Ty
644644

645645
$unresolvableReturnType = $this->unresolvableTypeHelper->getUnresolvableType($parametersAcceptor->getReturnType());
646646
if (
647-
$this->unresolvableTypeHelper->getUnresolvableType($originalParametersAcceptor->getReturnType()) === null
648-
&& $unresolvableReturnType !== null
647+
$unresolvableReturnType !== null
648+
&& $this->unresolvableTypeHelper->getUnresolvableType($originalParametersAcceptor->getReturnType()) === null
649649
) {
650650
$errorBuilder = RuleErrorBuilder::message($unresolvableReturnTypeMessage)
651651
->identifier(sprintf('%s.unresolvableReturnType', $nodeType))

0 commit comments

Comments
 (0)