Skip to content

Naive Conversion of Coalesce to UnionType #8097

Description

@Bellardia

Bug Report

Subject Details
Rector version Rector 0.17.7

Minimal PHP Code Causing Issue

NodeTypeResolver resolves Coalesce Expressions by converting them to UnionTypes, but ignores the non-nullability property of the overall expression.

if ($node instanceof Coalesce) {
    $first = $this->getType($node->left);
    $second = $this->getType($node->right);
    if ($this->isUnionTypeable($first, $second)) {
        return new UnionType([$first, $second]);
    }
}

Consider a minimal function:

<?php

class MyClass {
    public function MyFunction(?string $string = null) {
        return strpos($string ?? '', 'search_string');
    }
}

With type detection on the Coalesce Expr:

public function refactor(Node $node): ?Node
{
    $type = $this->getType($argument);
    var_dump($type->isNull()->maybe());
}

Output:

bool(true)

The left side of Coalesce is nullable, but the right side isn't, so we know that the final expression here is for sure a non-nullable string. The net effect here is when detecting types at scale, many end up null poisoned.

Expected Behaviour

The nullability of left side expressions should be ignored when constructing UnionTypes from Coalesce

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions