@@ -2554,6 +2554,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context): Exp
2554
2554
$ scope = $ nameResult ->getScope ();
2555
2555
$ throwPoints = $ nameResult ->getThrowPoints ();
2556
2556
$ impurePoints = $ nameResult ->getImpurePoints ();
2557
+ $ isAlwaysTerminating = $ nameResult ->isAlwaysTerminating ();
2557
2558
if (
2558
2559
$ nameType ->isObject ()->yes ()
2559
2560
&& $ nameType ->isCallable ()->yes ()
@@ -2569,6 +2570,7 @@ static function (): void {
2569
2570
);
2570
2571
$ throwPoints = array_merge ($ throwPoints , $ invokeResult ->getThrowPoints ());
2571
2572
$ impurePoints = array_merge ($ impurePoints , $ invokeResult ->getImpurePoints ());
2573
+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ invokeResult ->isAlwaysTerminating ();
2572
2574
} elseif ($ parametersAcceptor instanceof CallableParametersAcceptor) {
2573
2575
$ callableThrowPoints = array_map (static fn (SimpleThrowPoint $ throwPoint ) => $ throwPoint ->isExplicit () ? ThrowPoint::createExplicit ($ scope , $ throwPoint ->getType (), $ expr , $ throwPoint ->canContainAnyThrowable ()) : ThrowPoint::createImplicit ($ scope , $ expr ), $ parametersAcceptor ->getThrowPoints ());
2574
2576
if (!$ this ->implicitThrows ) {
@@ -2604,13 +2606,14 @@ static function (): void {
2604
2606
if ($ parametersAcceptor !== null ) {
2605
2607
$ expr = ArgumentsNormalizer::reorderFuncArguments ($ parametersAcceptor , $ expr ) ?? $ expr ;
2606
2608
$ returnType = $ parametersAcceptor ->getReturnType ();
2607
- $ isAlwaysTerminating = $ returnType instanceof NeverType && $ returnType ->isExplicit ();
2609
+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ returnType instanceof NeverType && $ returnType ->isExplicit ();
2608
2610
}
2609
2611
$ result = $ this ->processArgs ($ stmt , $ functionReflection , null , $ parametersAcceptor , $ expr , $ scope , $ nodeCallback , $ context );
2610
2612
$ scope = $ result ->getScope ();
2611
2613
$ hasYield = $ result ->hasYield ();
2612
2614
$ throwPoints = array_merge ($ throwPoints , $ result ->getThrowPoints ());
2613
2615
$ impurePoints = array_merge ($ impurePoints , $ result ->getImpurePoints ());
2616
+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ result ->isAlwaysTerminating ();
2614
2617
2615
2618
if ($ functionReflection !== null ) {
2616
2619
$ functionThrowPoint = $ this ->getFunctionThrowPoint ($ functionReflection , $ parametersAcceptor , $ expr , $ scope );
@@ -5012,6 +5015,7 @@ private function processArgs(
5012
5015
$ hasYield = false ;
5013
5016
$ throwPoints = [];
5014
5017
$ impurePoints = [];
5018
+ $ isAlwaysTerminating = false ;
5015
5019
foreach ($ args as $ i => $ arg ) {
5016
5020
$ assignByReference = false ;
5017
5021
$ parameter = null ;
@@ -5161,6 +5165,7 @@ private function processArgs(
5161
5165
$ exprResult = $ this ->processExprNode ($ stmt , $ arg ->value , $ scopeToPass , $ nodeCallback , $ context ->enterDeep ());
5162
5166
$ throwPoints = array_merge ($ throwPoints , $ exprResult ->getThrowPoints ());
5163
5167
$ impurePoints = array_merge ($ impurePoints , $ exprResult ->getImpurePoints ());
5168
+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ exprResult ->isAlwaysTerminating ();
5164
5169
$ scope = $ exprResult ->getScope ();
5165
5170
$ hasYield = $ hasYield || $ exprResult ->hasYield ();
5166
5171
@@ -5285,7 +5290,7 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
5285
5290
}
5286
5291
}
5287
5292
5288
- return new ExpressionResult ($ scope , $ hasYield , $ throwPoints , $ impurePoints );
5293
+ return new ExpressionResult ($ scope , $ hasYield , $ throwPoints , $ impurePoints, isAlwaysTerminating: $ isAlwaysTerminating );
5289
5294
}
5290
5295
5291
5296
/**
0 commit comments