diff --git a/src/Type/Php/DateIntervalFormatDynamicReturnTypeExtension.php b/src/Type/Php/DateIntervalFormatDynamicReturnTypeExtension.php index f6d32b02ed..08f66913cc 100644 --- a/src/Type/Php/DateIntervalFormatDynamicReturnTypeExtension.php +++ b/src/Type/Php/DateIntervalFormatDynamicReturnTypeExtension.php @@ -56,17 +56,20 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } // The worst case scenario for the non-falsy-string check is that every number is 0. + // `%a` format gives `(unknown)` and removes numeric and uppercase accessory but then + // we'll have to manually check for the non-falsy one. $dateInterval = new DateInterval('P0D'); $possibleReturnTypes = []; foreach ($constantStrings as $string) { - $value = $dateInterval->format($string->getValue()); + $formatString = $string->getValue(); + $value = $dateInterval->format($formatString); $accessories = []; if (is_numeric($value)) { $accessories[] = new AccessoryNumericStringType(); } - if ($value !== '0' && $value !== '') { + if ($value !== '0' && $value !== '' && $formatString !== '%a') { $accessories[] = new AccessoryNonFalsyStringType(); } elseif ($value !== '') { $accessories[] = new AccessoryNonEmptyStringType(); diff --git a/tests/PHPStan/Analyser/nsrt/bug-1452.php b/tests/PHPStan/Analyser/nsrt/bug-1452.php index c4c40325c6..75e4676bdd 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-1452.php +++ b/tests/PHPStan/Analyser/nsrt/bug-1452.php @@ -6,5 +6,7 @@ $dateInterval = (new \DateTimeImmutable('now -60 minutes'))->diff(new \DateTimeImmutable('now')); -// Could be lowercase-string&non-falsy-string&numeric-string&uppercase-string -assertType('lowercase-string&non-falsy-string', $dateInterval->format('%a')); +assertType( + 'lowercase-string&non-empty-string', + $dateInterval->format('%a') +);