Skip to content

Loop that does not loop different behaviour depending on else #1991

@reedy

Description

@reedy
Subject Details
Plugin EA Extended 5.4.0
Language level 8.1.0

Current behaviour

This does not report as "loop that does not loop":

		foreach ( $inputTree->getArgs() as $value ) {
			if ( $value instanceof Fun2 && $value->getFname() === "\\intent" ) {
				$intentStr = MMLutil::squashLitsToUnitIntent( $value->getArg2() );
				$intentContent = MMLParsingUtil::getIntentContent( $intentStr );
				$intentArg = MMLParsingUtil::getIntentArgs( $intentStr );
				$argch = self::checkIntentArg( $intentArg );
				if ( !$argch ) {
					$retval = [];
					$retval["success"] = false;
					$retval["info"] = "malformatted intent argument";
					return $retval;
				}
				// do check on arg1
				$ret = !$intentContent ? true : self::checkIntent( $intentContent );
				if ( !$ret || ( isset( $ret["success"] ) && $ret["success"] == false ) ) {
					return $ret;
				}
				return $this->checkTreeIntents( $value->getArg1() );
			} else {
				return self::checkTreeIntents( $value );
			}
		}

But this does, and are functionally the same code:

		foreach ( $inputTree->getArgs() as $value ) {
			if ( $value instanceof Fun2 && $value->getFname() === "\\intent" ) {
				$intentStr = MMLutil::squashLitsToUnitIntent( $value->getArg2() );
				$intentContent = MMLParsingUtil::getIntentContent( $intentStr );
				$intentArg = MMLParsingUtil::getIntentArgs( $intentStr );
				$argch = self::checkIntentArg( $intentArg );
				if ( !$argch ) {
					$retval = [];
					$retval["success"] = false;
					$retval["info"] = "malformatted intent argument";
					return $retval;
				}
				// do check on arg1
				$ret = !$intentContent ? true : self::checkIntent( $intentContent );
				if ( !$ret || ( isset( $ret["success"] ) && $ret["success"] == false ) ) {
					return $ret;
				}
				return $this->checkTreeIntents( $value->getArg1() );
			}

			return self::checkTreeIntents( $value );
		}

The underlying idea that it is a loop that does not loop is indeed correct, but there being an else shouldn't make the warning go away.

Expected behaviour

The two blocks of code both get the same warning.

Environment details

PhpStorm 2025.3 EAP
Build #PS-253.27642.37, built on October 17, 2025
Source revision: 9515438f712bd
Licensed to PhpStorm EAP user: Sam Reed
Expiration date: November 16, 2025
Runtime version: 21.0.8+9-b1163.59 aarch64 (JCEF 137.0.17)
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Toolkit: sun.lwawt.macosx.LWCToolkit
macOS 15.7.1
GC: G1 Young Generation, G1 Concurrent GC, G1 Old Generation
Memory: 4096M
Cores: 8
Metal Rendering is ON
Registry:
  debugger.new.tool.window.layout=true
  run.processes.with.pty=TRUE
  ide.experimental.ui=true
  completion.cloud.adaptive.debounce.is.active=true
Non-Bundled Plugins:
  com.intellij.properties (253.27642.34)
  com.intellij.lang.jsgraphql (253.27642.17)
  de.femtopedia.diffplugin (2.2.3)
  dev.turingcomplete.intellijdevelopertoolsplugins (7.1.0)
  com.intellij.aqua (253.27642.30)
  com.intellij.ml.llm (253.27642.37)
  com.kalessil.phpStorm.phpInspectionsEA (5.4.0)
  org.mediawiki (0.6.3)
  net.rentalhost.plugins.php.hammer (0.33.0)
  com.dmarcotte.handlebars (253.27642.17)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions