diff --git a/src/Psalm/Checker/Statements/Block/IfChecker.php b/src/Psalm/Checker/Statements/Block/IfChecker.php index b90f14921..1d80eadc1 100644 --- a/src/Psalm/Checker/Statements/Block/IfChecker.php +++ b/src/Psalm/Checker/Statements/Block/IfChecker.php @@ -594,7 +594,11 @@ class IfChecker $negated_keys = []; foreach ($negated_elseif_types as $var_id => $type) { - if (!$has_leaving_statements || $type !== '!empty') { + if (!$has_leaving_statements || + $type !== '!empty' || + !isset($elseif_context->vars_in_scope[$var_id]) || + $elseif_context->vars_in_scope[$var_id]->hasObjectType() + ) { $negated_keys[] = $var_id; } } diff --git a/src/Psalm/Checker/Statements/Block/SwitchChecker.php b/src/Psalm/Checker/Statements/Block/SwitchChecker.php index d1ed07ca3..86f90eae0 100644 --- a/src/Psalm/Checker/Statements/Block/SwitchChecker.php +++ b/src/Psalm/Checker/Statements/Block/SwitchChecker.php @@ -45,6 +45,7 @@ class SwitchChecker $new_vars_possibly_in_scope = []; $redefined_vars = null; + $possibly_redefined_vars = null; // the last statement always breaks, by default $last_case_exit_type = 'break'; @@ -148,6 +149,21 @@ class SwitchChecker Type::redefineGenericUnionTypes($case_redefined_vars, $context); + if ($possibly_redefined_vars === null) { + $possibly_redefined_vars = $case_redefined_vars; + } else { + foreach ($case_redefined_vars as $var_id => $type) { + if (!isset($possibly_redefined_vars[$var_id])) { + $possibly_redefined_vars[$var_id] = $type; + } else { + $possibly_redefined_vars[$var_id] = Type::combineUnionTypes( + $type, + $possibly_redefined_vars[$var_id] + ); + } + } + } + if ($redefined_vars === null) { $redefined_vars = $case_redefined_vars; } else { @@ -206,8 +222,8 @@ class SwitchChecker if ($redefined_vars) { $context->vars_in_scope = array_merge($context->vars_in_scope, $redefined_vars); } - } elseif ($redefined_vars) { - foreach ($redefined_vars as $var_id => $type) { + } elseif ($possibly_redefined_vars) { + foreach ($possibly_redefined_vars as $var_id => $type) { $context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $context->vars_in_scope[$var_id]); } } diff --git a/tests/ArrayAssignmentTest.php b/tests/ArrayAssignmentTest.php index 0a83a6b4d..150eb07f1 100644 --- a/tests/ArrayAssignmentTest.php +++ b/tests/ArrayAssignmentTest.php @@ -169,7 +169,7 @@ class ArrayAssignmentTest extends PHPUnit_Framework_TestCase $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); - $this->assertEquals('array', (string) $context->vars_in_scope['$out']); + $this->assertEquals('array', (string) $context->vars_in_scope['$out']); } /**