Skip to content

Commit

Permalink
Support for conditional types in @param-out
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Mar 13, 2024
1 parent e76f64e commit effad95
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
13 changes: 8 additions & 5 deletions src/Reflection/ResolvedFunctionVariant.php
Expand Up @@ -84,11 +84,14 @@ function (ParameterReflectionWithPhpDocs $param): ParameterReflectionWithPhpDocs

$paramOutType = $param->getOutType();
if ($paramOutType !== null) {
$paramOutType = TemplateTypeHelper::resolveTemplateTypes(
$paramOutType,
$this->resolvedTemplateTypeMap,
$this->callSiteVarianceMap,
TemplateTypeVariance::createCovariant(),
$paramOutType = TypeUtils::resolveLateResolvableTypes(
TemplateTypeHelper::resolveTemplateTypes(
$this->resolveConditionalTypesForParameter($paramOutType),
$this->resolvedTemplateTypeMap,
$this->callSiteVarianceMap,
TemplateTypeVariance::createCovariant(),
),
false,
);
}

Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -333,6 +333,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4500.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4504.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4436.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10699.php');
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Properties/data/bug-3777.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2549.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-1945.php');
Expand Down
30 changes: 30 additions & 0 deletions tests/PHPStan/Analyser/data/bug-10699.php
@@ -0,0 +1,30 @@
<?php

namespace Bug10699;

use function PHPStan\Testing\assertType;

/**
* @param int $flags
* @param mixed $out
*
* @param-out ($flags is 2 ? 20 : 10) $out
*
* @return ($flags is 2 ? 20 : 10)
*/
function test(int $flags, &$out): int
{
$out = $flags === 2 ? 20 : 10;

return $out;
}

function (): void {
$res = test(1, $out);
assertType('10', $res);
assertType('10', $out);

$res = test(2, $out);
assertType('20', $res);
assertType('20', $out);
};

0 comments on commit effad95

Please sign in to comment.