Skip to content

Commit 9c17795

Browse files
committed
Fix #3631 - apply assertions to RHS of equality in conditional
1 parent 29eb830 commit 9c17795

File tree

4 files changed

+39
-18
lines changed

4 files changed

+39
-18
lines changed

src/Psalm/Internal/Analyzer/FunctionAnalyzer.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ public static function getReturnTypeFromCallMapWithArgs(
193193
return clone $array_type->type_param;
194194
}
195195
} elseif ($first_arg_type->hasScalarType()
196-
&& isset($call_args[1])
197-
&& ($second_arg = $call_args[1]->value)
196+
&& ($second_arg = ($call_args[1]->value ?? null))
198197
&& ($second_arg_type = $statements_analyzer->node_data->getType($second_arg))
199198
&& $second_arg_type->hasScalarType()
200199
) {

src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php

+23-14
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,29 @@ public static function scrapeAssertions(
123123
return $if_types;
124124
}
125125

126+
if ($conditional instanceof PhpParser\Node\Expr\Assign) {
127+
$var_name = ExpressionIdentifier::getArrayVarId(
128+
$conditional->var,
129+
$this_class_name,
130+
$source
131+
);
132+
133+
$if_types = self::scrapeAssertions(
134+
$conditional->expr,
135+
$this_class_name,
136+
$source,
137+
$codebase,
138+
$inside_negation,
139+
$cache
140+
);
141+
142+
if ($var_name) {
143+
$if_types[$var_name] = [['!falsy']];
144+
}
145+
146+
return $if_types;
147+
}
148+
126149
$var_name = ExpressionIdentifier::getArrayVarId(
127150
$conditional,
128151
$this_class_name,
@@ -139,20 +162,6 @@ public static function scrapeAssertions(
139162
}
140163
}
141164

142-
if ($conditional instanceof PhpParser\Node\Expr\Assign) {
143-
$var_name = ExpressionIdentifier::getArrayVarId(
144-
$conditional->var,
145-
$this_class_name,
146-
$source
147-
);
148-
149-
if ($var_name) {
150-
$if_types[$var_name] = [['!falsy']];
151-
}
152-
153-
return $if_types;
154-
}
155-
156165
if ($conditional instanceof PhpParser\Node\Expr\BooleanNot) {
157166
$expr_assertions = null;
158167

src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ public static function fetch(
8585

8686
if (InternalCallMapHandler::inCallMap((string) $call_map_id)) {
8787
if (($template_result->upper_bounds || $class_storage->stubbed)
88-
&& isset($class_storage->methods[$method_id->method_name])
89-
&& ($method_storage = $class_storage->methods[$method_id->method_name])
88+
&& ($method_storage = ($class_storage->methods[$method_id->method_name] ?? null))
9089
&& $method_storage->return_type
9190
) {
9291
$return_type_candidate = clone $method_storage->return_type;

tests/TypeReconciliation/ConditionalTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -2781,6 +2781,20 @@ function sayHi(string $greeting): void {
27812781
$a->format("d-m-Y");
27822782
}',
27832783
],
2784+
'applyTruthyAssertionsToRightHandSideOfAssignment' => [
2785+
'<?php
2786+
function takesAString(string $name): void {}
2787+
2788+
function randomReturn(): ?string {
2789+
return rand(1,2) === 1 ? "foo" : null;
2790+
}
2791+
2792+
$name = randomReturn();
2793+
2794+
if ($foo = ($name !== null)) {
2795+
takesAString($name);
2796+
}'
2797+
],
27842798
];
27852799
}
27862800

0 commit comments

Comments
 (0)