@@ -2554,6 +2554,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context): Exp
25542554 $ scope = $ nameResult ->getScope ();
25552555 $ throwPoints = $ nameResult ->getThrowPoints ();
25562556 $ impurePoints = $ nameResult ->getImpurePoints ();
2557+ $ isAlwaysTerminating = $ nameResult ->isAlwaysTerminating ();
25572558 if (
25582559 $ nameType ->isObject ()->yes ()
25592560 && $ nameType ->isCallable ()->yes ()
@@ -2569,6 +2570,7 @@ static function (): void {
25692570 );
25702571 $ throwPoints = array_merge ($ throwPoints , $ invokeResult ->getThrowPoints ());
25712572 $ impurePoints = array_merge ($ impurePoints , $ invokeResult ->getImpurePoints ());
2573+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ invokeResult ->isAlwaysTerminating ();
25722574 } elseif ($ parametersAcceptor instanceof CallableParametersAcceptor) {
25732575 $ callableThrowPoints = array_map (static fn (SimpleThrowPoint $ throwPoint ) => $ throwPoint ->isExplicit () ? ThrowPoint::createExplicit ($ scope , $ throwPoint ->getType (), $ expr , $ throwPoint ->canContainAnyThrowable ()) : ThrowPoint::createImplicit ($ scope , $ expr ), $ parametersAcceptor ->getThrowPoints ());
25742576 if (!$ this ->implicitThrows ) {
@@ -2604,13 +2606,14 @@ static function (): void {
26042606 if ($ parametersAcceptor !== null ) {
26052607 $ expr = ArgumentsNormalizer::reorderFuncArguments ($ parametersAcceptor , $ expr ) ?? $ expr ;
26062608 $ returnType = $ parametersAcceptor ->getReturnType ();
2607- $ isAlwaysTerminating = $ returnType instanceof NeverType && $ returnType ->isExplicit ();
2609+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ returnType instanceof NeverType && $ returnType ->isExplicit ();
26082610 }
26092611 $ result = $ this ->processArgs ($ stmt , $ functionReflection , null , $ parametersAcceptor , $ expr , $ scope , $ nodeCallback , $ context );
26102612 $ scope = $ result ->getScope ();
26112613 $ hasYield = $ result ->hasYield ();
26122614 $ throwPoints = array_merge ($ throwPoints , $ result ->getThrowPoints ());
26132615 $ impurePoints = array_merge ($ impurePoints , $ result ->getImpurePoints ());
2616+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ result ->isAlwaysTerminating ();
26142617
26152618 if ($ functionReflection !== null ) {
26162619 $ functionThrowPoint = $ this ->getFunctionThrowPoint ($ functionReflection , $ parametersAcceptor , $ expr , $ scope );
@@ -5012,6 +5015,7 @@ private function processArgs(
50125015 $ hasYield = false ;
50135016 $ throwPoints = [];
50145017 $ impurePoints = [];
5018+ $ isAlwaysTerminating = false ;
50155019 foreach ($ args as $ i => $ arg ) {
50165020 $ assignByReference = false ;
50175021 $ parameter = null ;
@@ -5161,6 +5165,7 @@ private function processArgs(
51615165 $ exprResult = $ this ->processExprNode ($ stmt , $ arg ->value , $ scopeToPass , $ nodeCallback , $ context ->enterDeep ());
51625166 $ throwPoints = array_merge ($ throwPoints , $ exprResult ->getThrowPoints ());
51635167 $ impurePoints = array_merge ($ impurePoints , $ exprResult ->getImpurePoints ());
5168+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ exprResult ->isAlwaysTerminating ();
51645169 $ scope = $ exprResult ->getScope ();
51655170 $ hasYield = $ hasYield || $ exprResult ->hasYield ();
51665171
@@ -5285,7 +5290,7 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
52855290 }
52865291 }
52875292
5288- return new ExpressionResult ($ scope , $ hasYield , $ throwPoints , $ impurePoints );
5293+ return new ExpressionResult ($ scope , $ hasYield , $ throwPoints , $ impurePoints, isAlwaysTerminating: $ isAlwaysTerminating );
52895294 }
52905295
52915296 /**
0 commit comments