diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php index bc11d8644..15d3c62c1 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php @@ -100,20 +100,12 @@ class LoopAnalyzer $does_always_break = $final_actions === [ScopeAnalyzer::ACTION_BREAK]; - $has_continue = in_array(ScopeAnalyzer::ACTION_CONTINUE, $final_actions, true); - if ($assignment_map) { $first_var_id = array_keys($assignment_map)[0]; $assignment_depth = self::getAssignmentMapDepth($first_var_id, $assignment_map); } - if ($has_continue) { - // this intuitively feels right to me – if there's a continue statement, - // maybe more assignment intrigue is possible - $assignment_depth++; - } - $pre_outer_context = $loop_scope->loop_parent_context; if ($assignment_depth === 0 || $does_always_break) { @@ -142,7 +134,7 @@ class LoopAnalyzer $inner_context->protected_var_ids = $loop_scope->protected_var_ids; $statements_analyzer->analyze($stmts, $inner_context); - self::updateLoopScopeContexts($loop_scope, $loop_scope->loop_parent_context); + self::updateLoopScopeContexts($loop_scope, $inner_context, $loop_scope->loop_parent_context); foreach ($post_expressions as $post_expression) { if (ExpressionAnalyzer::analyze( @@ -203,7 +195,7 @@ class LoopAnalyzer $statements_analyzer->analyze($stmts, $inner_context); - self::updateLoopScopeContexts($loop_scope, $pre_outer_context); + self::updateLoopScopeContexts($loop_scope, $inner_context, $pre_outer_context); $inner_context->protected_var_ids = $original_protected_var_ids; @@ -380,7 +372,7 @@ class LoopAnalyzer $statements_analyzer->analyze($stmts, $inner_context); - self::updateLoopScopeContexts($loop_scope, $pre_outer_context); + self::updateLoopScopeContexts($loop_scope, $inner_context, $pre_outer_context); $inner_context->protected_var_ids = $original_protected_var_ids; @@ -567,6 +559,7 @@ class LoopAnalyzer private static function updateLoopScopeContexts( LoopScope $loop_scope, + Context $loop_context, Context $pre_outer_context ): void { $updated_loop_vars = []; @@ -575,21 +568,20 @@ class LoopAnalyzer $loop_scope->loop_context->vars_in_scope = $pre_outer_context->vars_in_scope; } else { foreach ($loop_scope->redefined_loop_vars as $var => $type) { - $loop_scope->loop_context->vars_in_scope[$var] = $type; + $loop_context->vars_in_scope[$var] = $type; $updated_loop_vars[$var] = true; } if ($loop_scope->possibly_redefined_loop_vars) { foreach ($loop_scope->possibly_redefined_loop_vars as $var => $type) { - if ($loop_scope->loop_context->hasVariable($var)) { + if ($loop_context->hasVariable($var)) { if (!isset($updated_loop_vars[$var])) { - $loop_scope->loop_context->vars_in_scope[$var] = Type::combineUnionTypes( - $loop_scope->loop_context->vars_in_scope[$var], + $loop_context->vars_in_scope[$var] = Type::combineUnionTypes( + $loop_context->vars_in_scope[$var], $type ); } else { - $loop_scope->loop_context->vars_in_scope[$var]->parent_nodes - += $type->parent_nodes; + $loop_context->vars_in_scope[$var]->parent_nodes += $type->parent_nodes; } } } diff --git a/tests/Loop/WhileTest.php b/tests/Loop/WhileTest.php index d873f8a58..9e09b4916 100644 --- a/tests/Loop/WhileTest.php +++ b/tests/Loop/WhileTest.php @@ -751,6 +751,22 @@ class WhileTest extends TestCase } }' ], + 'continuingEducation' => [ + 'code' => '