Skip to content

Commit d385e15

Browse files
ondrejmirtesVincentLanglet
authored andcommitted
Preserve vacuously true conditional expressions during scope merging
Fixes phpstan/phpstan#4173
1 parent 4c6ef6e commit d385e15

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

src/Analyser/MutatingScope.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3372,6 +3372,16 @@ public function mergeWith(?self $otherScope): self
33723372

33733373
$mergedExpressionTypes = $this->mergeVariableHolders($ourExpressionTypes, $theirExpressionTypes);
33743374
$conditionalExpressions = $this->intersectConditionalExpressions($otherScope->conditionalExpressions);
3375+
$conditionalExpressions = $this->preserveVacuousConditionalExpressions(
3376+
$conditionalExpressions,
3377+
$this->conditionalExpressions,
3378+
$theirExpressionTypes,
3379+
);
3380+
$conditionalExpressions = $this->preserveVacuousConditionalExpressions(
3381+
$conditionalExpressions,
3382+
$otherScope->conditionalExpressions,
3383+
$ourExpressionTypes,
3384+
);
33753385
$conditionalExpressions = $this->createConditionalExpressions(
33763386
$conditionalExpressions,
33773387
$ourExpressionTypes,
@@ -3477,6 +3487,43 @@ private function intersectConditionalExpressions(array $otherConditionalExpressi
34773487
return $newConditionalExpressions;
34783488
}
34793489

3490+
/**
3491+
* @param array<string, ConditionalExpressionHolder[]> $currentConditionalExpressions
3492+
* @param array<string, ConditionalExpressionHolder[]> $sourceConditionalExpressions
3493+
* @param array<string, ExpressionTypeHolder> $otherExpressionTypes
3494+
* @return array<string, ConditionalExpressionHolder[]>
3495+
*/
3496+
private function preserveVacuousConditionalExpressions(
3497+
array $currentConditionalExpressions,
3498+
array $sourceConditionalExpressions,
3499+
array $otherExpressionTypes,
3500+
): array
3501+
{
3502+
foreach ($sourceConditionalExpressions as $exprString => $holders) {
3503+
foreach ($holders as $key => $holder) {
3504+
if (isset($currentConditionalExpressions[$exprString][$key])) {
3505+
continue;
3506+
}
3507+
3508+
foreach ($holder->getConditionExpressionTypeHolders() as $guardExprString => $guardTypeHolder) {
3509+
if (!array_key_exists($guardExprString, $otherExpressionTypes)) {
3510+
continue;
3511+
}
3512+
3513+
$otherType = $otherExpressionTypes[$guardExprString]->getType();
3514+
$guardType = $guardTypeHolder->getType();
3515+
3516+
if ($otherType->isSuperTypeOf($guardType)->no()) {
3517+
$currentConditionalExpressions[$exprString][$key] = $holder;
3518+
break;
3519+
}
3520+
}
3521+
}
3522+
}
3523+
3524+
return $currentConditionalExpressions;
3525+
}
3526+
34803527
/**
34813528
* @param array<string, ConditionalExpressionHolder[]> $newConditionalExpressions
34823529
* @param array<string, ConditionalExpressionHolder[]> $existingConditionalExpressions

tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -911,12 +911,7 @@ public function testBug4173(): void
911911
$this->polluteScopeWithLoopInitialAssignments = false;
912912
$this->checkMaybeUndefinedVariables = true;
913913
$this->polluteScopeWithAlwaysIterableForeach = true;
914-
$this->analyse([__DIR__ . '/data/bug-4173.php'], [
915-
[
916-
'Variable $value might not be defined.', // could be fixed
917-
30,
918-
],
919-
]);
914+
$this->analyse([__DIR__ . '/data/bug-4173.php'], []);
920915
}
921916

922917
public function testBug5805(): void
@@ -1119,29 +1114,13 @@ public function testDynamicAccess(): void
11191114
18,
11201115
],
11211116
[
1122-
'Variable $foo might not be defined.',
1123-
36,
1124-
],
1125-
[
1126-
'Variable $foo might not be defined.',
1127-
37,
1128-
],
1129-
[
1130-
'Variable $bar might not be defined.',
1117+
'Undefined variable: $bar',
11311118
38,
11321119
],
11331120
[
1134-
'Variable $bar might not be defined.',
1135-
40,
1136-
],
1137-
[
1138-
'Variable $foo might not be defined.',
1121+
'Undefined variable: $foo',
11391122
41,
11401123
],
1141-
[
1142-
'Variable $bar might not be defined.',
1143-
42,
1144-
],
11451124
[
11461125
'Undefined variable: $buz',
11471126
44,

0 commit comments

Comments
 (0)