Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -3229,6 +3229,32 @@
}
}

foreach ($scope->conditionalExpressions as $conditionalExprString => $conditionalExpressions) {
if (array_key_exists($conditionalExprString, $conditions)) {
continue;
}
if (
!array_key_exists($conditionalExprString, $scope->expressionTypes)
|| $scope->expressionTypes[$conditionalExprString]->getCertainty()->yes()
|| !$scope->expressionTypes[$conditionalExprString]->getExpr() instanceof Variable
) {
continue;
}
foreach ($conditionalExpressions as $conditionalExpression) {
foreach ($conditionalExpression->getConditionExpressionTypeHolders() as $holderExprString => $conditionalTypeHolder) {
if (
!array_key_exists($holderExprString, $specifiedExpressions)
|| !$specifiedExpressions[$holderExprString]->getCertainty()->equals($conditionalTypeHolder->getCertainty())
|| !$conditionalTypeHolder->getType()->isSuperTypeOf($specifiedExpressions[$holderExprString]->getType())->yes()

Check warning on line 3248 in src/Analyser/MutatingScope.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ if ( !array_key_exists($holderExprString, $specifiedExpressions) || !$specifiedExpressions[$holderExprString]->getCertainty()->equals($conditionalTypeHolder->getCertainty()) - || !$conditionalTypeHolder->getType()->isSuperTypeOf($specifiedExpressions[$holderExprString]->getType())->yes() + || $conditionalTypeHolder->getType()->isSuperTypeOf($specifiedExpressions[$holderExprString]->getType())->no() ) { continue 2; }

Check warning on line 3248 in src/Analyser/MutatingScope.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ if ( !array_key_exists($holderExprString, $specifiedExpressions) || !$specifiedExpressions[$holderExprString]->getCertainty()->equals($conditionalTypeHolder->getCertainty()) - || !$conditionalTypeHolder->getType()->isSuperTypeOf($specifiedExpressions[$holderExprString]->getType())->yes() + || $conditionalTypeHolder->getType()->isSuperTypeOf($specifiedExpressions[$holderExprString]->getType())->no() ) { continue 2; }
) {
continue 2;
}
}

$conditions[$conditionalExprString][] = $conditionalExpression;
}
}

foreach ($conditions as $conditionalExprString => $expressions) {
$certainty = TrinaryLogic::lazyExtremeIdentity($expressions, static fn (ConditionalExpressionHolder $holder) => $holder->getTypeHolder()->getCertainty());
if ($certainty->no()) {
Expand Down
9 changes: 9 additions & 0 deletions tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,15 @@ public function testBug8212(): void
$this->analyse([__DIR__ . '/data/bug-8212.php'], []);
}

public function testBug12597(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = true;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;
$this->analyse([__DIR__ . '/data/bug-12597.php'], []);
}

public function testBug4173(): void
{
$this->cliArgumentsVariablesRegistered = true;
Expand Down
68 changes: 68 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-12597.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types = 1);

namespace Bug12597;

class HelloWorld
{
private const TYPE_1 = 1;
private const TYPE_2 = 2;

public function test(int $type): void
{
if (in_array($type, [self::TYPE_1, self::TYPE_2], true)) {
$message = 'Hello!';
}

if ($type === self::TYPE_1) {
$this->message($message);
}
}

public function message(string $message): void {}
}

class HelloWorld2
{
public function test(mixed $type): void
{
if (is_int($type) || is_string($type)) {
$message = 'Hello!';
}

if (is_int($type)) {
$this->message($message);
}
}

public function message(string $message): void {}
}

class Foo {}
class Bar {}

class HelloWorld3
{
public function test(mixed $type): void
{
if (is_int($type) || is_object($type)) {
$message = 'Hello!';
}

if (is_int($type)) {
$this->message($message);
}
}

public function test2(mixed $type): void
{
if ($type instanceof Foo || $type instanceof Bar) {
$message = 'Hello!';
}

if ($type instanceof Foo) {
$this->message($message);
}
}

public function message(string $message): void {}
}
Loading