From d532133325bd37986277b0876826f4e84b415046 Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Sun, 4 Oct 2020 00:17:16 -0400 Subject: [PATCH] Add support for Stringable --- .../Type/Comparator/AtomicTypeComparator.php | 36 +++++++++++++------ tests/ToStringTest.php | 23 +++++++++++- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php b/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php index 58dea4ad2..aea970a40 100644 --- a/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php @@ -495,19 +495,33 @@ class AtomicTypeComparator if ($container_type_part instanceof TString || $container_type_part instanceof TScalar) { if ($input_type_part instanceof TNamedObject) { // check whether the object has a __toString method - if ($codebase->classOrInterfaceExists($input_type_part->value) - && $codebase->methods->methodExists( - new \Psalm\Internal\MethodIdentifier( - $input_type_part->value, - '__tostring' - ) - ) - ) { - if ($atomic_comparison_result) { - $atomic_comparison_result->to_string_cast = true; + if ($codebase->classOrInterfaceExists($input_type_part->value)) { + if ($codebase->php_major_version >= 8 + && ($input_type_part->value === 'Stringable' + || ($codebase->classlikes->classExists($input_type_part->value) + && $codebase->classlikes->classImplements($input_type_part->value, 'Stringable')) + || $codebase->classlikes->interfaceExtends($input_type_part->value, 'Stringable')) + ) { + if ($atomic_comparison_result) { + $atomic_comparison_result->to_string_cast = true; + } + + return true; } - return true; + if ($codebase->methods->methodExists( + new \Psalm\Internal\MethodIdentifier( + $input_type_part->value, + '__tostring' + ) + ) + ) { + if ($atomic_comparison_result) { + $atomic_comparison_result->to_string_cast = true; + } + + return true; + } } // PHP 5.6 doesn't support this natively, so this introduces a bug *just* when checking PHP 5.6 code diff --git a/tests/ToStringTest.php b/tests/ToStringTest.php index 5eb3fd8b2..0247f5a0a 100644 --- a/tests/ToStringTest.php +++ b/tests/ToStringTest.php @@ -145,8 +145,29 @@ class ToStringTest extends TestCase if (is_callable([$object, \'__toString\'])) { $a = (string) $object; echo $a; + }' + ], + 'stringableInterface' => [ + '