diff --git a/src/Analyser/ExprHandler/AssignHandler.php b/src/Analyser/ExprHandler/AssignHandler.php index 8f3fbeedae..f5b30e63bb 100644 --- a/src/Analyser/ExprHandler/AssignHandler.php +++ b/src/Analyser/ExprHandler/AssignHandler.php @@ -619,9 +619,6 @@ public function processAssignVar( )); } else { - $offsetTypes[] = [$scope->getType($dimExpr), $dimFetch]; - $offsetNativeTypes[] = [$scope->getNativeType($dimExpr), $dimFetch]; - if ($enterExpressionAssign) { $scope->enterExpressionAssign($dimExpr); } @@ -635,6 +632,8 @@ public function processAssignVar( impurePoints: [], )); $result = $nodeScopeResolver->processExprNode($stmt, $dimExpr, $scope, $storage, $nodeCallback, $context->enterDeep()); + $offsetTypes[] = [$result->getType(), $dimFetch]; + $offsetNativeTypes[] = [$result->getNativeType(), $dimFetch]; $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $scope = $result->getScope(); diff --git a/src/Analyser/ExprHandler/FuncCallHandler.php b/src/Analyser/ExprHandler/FuncCallHandler.php index 5f649ef3da..3b5d306ffc 100644 --- a/src/Analyser/ExprHandler/FuncCallHandler.php +++ b/src/Analyser/ExprHandler/FuncCallHandler.php @@ -124,7 +124,10 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex $impurePoints = []; $isAlwaysTerminating = false; if ($expr->name instanceof Expr) { - $nameType = $scope->getType($expr->name); + // process the dynamic callee name first, then consume its type rather + // than reading it before processExprNode() stores its result + $nameResult = $nodeScopeResolver->processExprNode($stmt, $expr->name, $scope, $storage, $nodeCallback, $context->enterDeep()); + $nameType = $nameResult->getType(); if (!$nameType->isCallable()->no()) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( $scope, @@ -134,7 +137,6 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex ); } - $nameResult = $nodeScopeResolver->processExprNode($stmt, $expr->name, $scope, $storage, $nodeCallback, $context->enterDeep()); $scope = $nameResult->getScope(); $throwPoints = $nameResult->getThrowPoints(); $impurePoints = $nameResult->getImpurePoints(); diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 8b4964a53a..82efccb10b 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -1378,8 +1378,8 @@ public function processStmtNode( $condScope = $scope; foreach ($stmt->elseifs as $elseif) { $this->callNodeCallback($nodeCallback, $elseif, $scope, $storage); - $elseIfConditionType = ($this->treatPhpDocTypesAsCertain ? $condScope->getType($elseif->cond) : $scope->getNativeType($elseif->cond))->toBoolean(); $condResult = $this->processExprNode($stmt, $elseif->cond, $condScope, $storage, $nodeCallback, ExpressionContext::createDeep()); + $elseIfConditionType = ($this->treatPhpDocTypesAsCertain ? $condResult->getType() : $condResult->getNativeType())->toBoolean(); $throwPoints = array_merge($throwPoints, $condResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $condResult->getImpurePoints()); $branchScopeStatementResult = $this->processStmtNodesInternal($elseif, $elseif->stmts, $condResult->getTruthyScope(), $storage, $nodeCallback, $context); @@ -1726,7 +1726,7 @@ public function processStmtNode( $originalStorage = $storage; $storage = $originalStorage->duplicate(); $condResult = $this->processExprNode($stmt, $stmt->cond, $scope, $storage, new NoopNodeCallback(), ExpressionContext::createDeep()); - $beforeCondBooleanType = ($this->treatPhpDocTypesAsCertain ? $scope->getType($stmt->cond) : $scope->getNativeType($stmt->cond))->toBoolean(); + $beforeCondBooleanType = ($this->treatPhpDocTypesAsCertain ? $condResult->getType() : $condResult->getNativeType())->toBoolean(); $condScope = $condResult->getFalseyScope(); if (!$context->isTopLevel() && $beforeCondBooleanType->isFalse()->yes()) { if (!$this->polluteScopeWithLoopInitialAssignments) {