Skip to content

Commit

Permalink
Remove some logic that didn't need to be there (#9209)
Browse files Browse the repository at this point in the history
* Remove check to see what breaks

* Simplify following logic

* Add tests from @kkmuffme‘s branch

* Reduce scope of fix

* Clean up logic a little

* Add failing test

* Improvements

* Fix for non-Paradoxical Condition result
  • Loading branch information
muglug committed Feb 4, 2023
1 parent 498cc45 commit d450b40
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 20 deletions.
8 changes: 2 additions & 6 deletions docs/running_psalm/issues/ParadoxicalCondition.md
Expand Up @@ -5,11 +5,7 @@ Emitted when a paradox is encountered in your programs logic that could not be c
```php
<?php

function foo($a, $b) : void {
if ($a && $b) {
echo "a";
} elseif ($a && $b) {
echo "cannot happen";
}
function foo(string $input) : string {
return $input === "a" ? "bar" : ($input === "a" ? "foo" : "b");
}
```
18 changes: 7 additions & 11 deletions src/Psalm/Internal/Algebra.php
Expand Up @@ -373,21 +373,17 @@ public static function getTruthsFromFormula(
$things_that_can_be_said = [];

foreach ($possible_types as $assertion) {
if ($assertion instanceof Falsy || !$assertion->isNegation()) {
$things_that_can_be_said[(string)$assertion] = $assertion;
}
$things_that_can_be_said[(string)$assertion] = $assertion;
}

if ($things_that_can_be_said && count($things_that_can_be_said) === count($possible_types)) {
if ($clause->generated && count($possible_types) > 1) {
unset($cond_referenced_var_ids[$var]);
}
if ($clause->generated && count($possible_types) > 1) {
unset($cond_referenced_var_ids[$var]);
}

$truths[$var] = [array_values($things_that_can_be_said)];
$truths[$var] = [array_values($things_that_can_be_said)];

if ($creating_conditional_id && $creating_conditional_id === $clause->creating_conditional_id) {
$active_truths[$var] = [array_values($things_that_can_be_said)];
}
if ($creating_conditional_id && $creating_conditional_id === $clause->creating_conditional_id) {
$active_truths[$var] = [array_values($things_that_can_be_said)];
}
}
}
Expand Down
Expand Up @@ -272,6 +272,9 @@ public static function analyze(
// this has to go on a separate line because the phar compactor messes with precedence
$scope_to_clone = $if_scope->post_leaving_if_context ?? $post_if_context;
$else_context = clone $scope_to_clone;
$else_context->clauses = Algebra::simplifyCNF(
[...$else_context->clauses, ...$if_scope->negated_clauses],
);

// check the elseifs
foreach ($stmt->elseifs as $elseif) {
Expand Down
Expand Up @@ -151,7 +151,10 @@ public static function analyze(
$right_context = clone $left_context;
}

$partitioned_clauses = Context::removeReconciledClauses($left_clauses, $changed_var_ids);
$partitioned_clauses = Context::removeReconciledClauses(
[...$left_context->clauses, ...$left_clauses],
$changed_var_ids
);

$right_context->clauses = $partitioned_clauses[0];

Expand Down
16 changes: 16 additions & 0 deletions tests/AssertAnnotationTest.php
Expand Up @@ -2110,6 +2110,22 @@ function consumeAOrB(string $aOrB): void {}
consumeAOrB($abc);
',
],
'assertDocblockTypeContradictionCorrectType' => [
'code' => '<?php
function takesAnInt(int $i): void {}
function takesAFloat(float $i): void {}
$foo = rand() / 2;
/** @psalm-suppress TypeDoesNotContainType */
if (is_int($foo) || !is_float($foo)) {
takesAnInt($foo);
exit;
}
takesAFloat($foo);',
],
];
}

Expand Down
39 changes: 37 additions & 2 deletions tests/TypeReconciliation/TypeAlgebraTest.php
Expand Up @@ -1211,6 +1211,40 @@ function test(string|object $s, bool $b) : string {
'ignored_issues' => [],
'php_version' => '8.0',
],
'subclassAfterNegation' => [
'code' => '<?php
abstract class Base {}
class A extends Base {}
class AChild extends A {}
class B extends Base {
public string $s = "";
}
function foo(Base $base): void {
if (!$base instanceof A || $base instanceof AChild) {
if ($base instanceof B && rand(0, 1)) {
echo $base->s;
}
}
}'
],
'subclassAfterElseifNegation' => [
'code' => '<?php
abstract class Base {}
class A extends Base {}
class AChild extends A {}
class B extends Base {
public string $s = "";
}
function foo(Base $base): void {
if ($base instanceof A && !($base instanceof AChild)) {
// do nothing
} elseif ($base instanceof B && rand(0, 1)) {
echo $base->s;
}
}'
],
];
}

Expand Down Expand Up @@ -1347,14 +1381,15 @@ function foo(?object $a): void {
],
'repeatedAndConditional' => [
'code' => '<?php
function foo(string $a, string $b): void {
class C {}
function foo(?C $a, ?C $b): void {
if ($a && $b) {
echo "a";
} elseif ($a && $b) {
echo "b";
}
}',
'error_message' => 'ParadoxicalCondition',
'error_message' => 'TypeDoesNotContainType',
],
'andConditionalAfterOrConditional' => [
'code' => '<?php
Expand Down

0 comments on commit d450b40

Please sign in to comment.