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