Skip to content

[TypeDeclaration] Map accessory string intersection to string in union return type#8125

Merged
TomasVotruba merged 1 commit into
mainfrom
fix-union-numeric-string-intersection
Jun 30, 2026
Merged

[TypeDeclaration] Map accessory string intersection to string in union return type#8125
TomasVotruba merged 1 commit into
mainfrom
fix-union-numeric-string-intersection

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Problem

ReturnUnionTypeRector failed to add a return type to methods like:

private function getAssetSize(): int { /* ... */ }

public function getTotalFilesize($assets)
{
    if (empty($assets)) {
        return 0;
    }

    $size = $this->getAssetSize($assets);

    if ($size) {
        $size = (string) $size;
    }

    return $size;
}

PHPStan infers the native return type as 0 | (numeric-string & non-falsy-string) — i.e. int | string. But IntersectionTypeMapper::mapToPhpParserNode() only handled object intersections; the string-accessory member (numeric-string & non-falsy-string) hit the ! $type instanceof ObjectType branch and returned null, which aborted the whole UnionTypeMapper. Net result: no return type was added at all.

Fix

A pure-string intersection is just string. Map it directly before the object handling:

if ($type->isString()->yes()) {
    return new Identifier('string');
}

Now the rule adds int|string as expected.

Test

Added fixture int_or_numeric_string.php.inc mirroring the real-world shape.

…n return type

ReturnUnionTypeRector inferred 0|(numeric-string&non-falsy-string) returns but IntersectionTypeMapper only handled object intersections, returning null for the string-accessory member and aborting the whole union. Map a pure-string intersection to string so int|string is added.
@TomasVotruba TomasVotruba merged commit 010e843 into main Jun 30, 2026
65 checks passed
@TomasVotruba TomasVotruba deleted the fix-union-numeric-string-intersection branch June 30, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant