Skip to content

Commit cc57957

Browse files
cs278ondrejmirtes
authored andcommitted
Remember value of arguments passed to {min,max}()
1 parent 76b094d commit cc57957

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/Type/Php/MinMaxFunctionReturnTypeExtension.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PhpParser\Node\Expr\FuncCall;
77
use PhpParser\Node\Expr\Ternary;
88
use PHPStan\Analyser\Scope;
9+
use PHPStan\Node\Expr\AlwaysRememberedExpr;
910
use PHPStan\Php\PhpVersion;
1011
use PHPStan\Reflection\FunctionReflection;
1112
use PHPStan\Type\Constant\ConstantArrayType;
@@ -60,15 +61,20 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
6061
$argType1 = $scope->getType($args[1]->value);
6162

6263
if ($argType0->isArray()->no() && $argType1->isArray()->no()) {
64+
$comparisonExpr = new Smaller(
65+
new AlwaysRememberedExpr($args[0]->value, $argType0, $scope->getNativeType($args[0]->value)),
66+
new AlwaysRememberedExpr($args[1]->value, $argType1, $scope->getNativeType($args[1]->value)),
67+
);
68+
6369
if ($functionName === 'min') {
6470
return $scope->getType(new Ternary(
65-
new Smaller($args[0]->value, $args[1]->value),
71+
$comparisonExpr,
6672
$args[0]->value,
6773
$args[1]->value,
6874
));
6975
} elseif ($functionName === 'max') {
7076
return $scope->getType(new Ternary(
71-
new Smaller($args[0]->value, $args[1]->value),
77+
$comparisonExpr,
7278
$args[1]->value,
7379
$args[0]->value,
7480
));
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Bug12731;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/** @phpstan-impure */
8+
function impure_int(): int {
9+
return rand(0, 100) - 50;
10+
}
11+
12+
/** @phpstan-pure */
13+
function pure_int(): int {
14+
return -42;
15+
}
16+
17+
assertType('int<4, max>', max(4, pure_int()));
18+
19+
$_ = impure_int();
20+
assertType('int<4, max>', max(4, $_));
21+
22+
assertType('int<4, max>', max(4, impure_int()));
23+
assertType('int<4, max>', max(impure_int(), 4));
24+
assertType('int', impure_int());

0 commit comments

Comments
 (0)