mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Strict int/float comparison for conditional types, improve range return type (#5601)
This commit is contained in:
parent
5f4a21190f
commit
518d0af895
@ -229,7 +229,12 @@ class TemplateInferredTypeReplacer
|
||||
if (UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
new Type\Union([$candidate_atomic_type]),
|
||||
$atomic_type->conditional_type
|
||||
$atomic_type->conditional_type,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
)
|
||||
&& (!$candidate_atomic_type instanceof Type\Atomic\TInt
|
||||
|| $atomic_type->conditional_type->getId() !== 'float')
|
||||
@ -238,7 +243,12 @@ class TemplateInferredTypeReplacer
|
||||
} elseif (!UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$atomic_type->conditional_type,
|
||||
new Type\Union([$candidate_atomic_type])
|
||||
new Type\Union([$candidate_atomic_type]),
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
)) {
|
||||
$matching_else_types[] = $candidate_atomic_type;
|
||||
}
|
||||
@ -251,7 +261,12 @@ class TemplateInferredTypeReplacer
|
||||
&& UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$if_candidate_type,
|
||||
$atomic_type->conditional_type
|
||||
$atomic_type->conditional_type,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
)
|
||||
) {
|
||||
$if_template_type = clone $atomic_type->if_type;
|
||||
@ -274,7 +289,12 @@ class TemplateInferredTypeReplacer
|
||||
&& UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$else_candidate_type,
|
||||
$atomic_type->as_type
|
||||
$atomic_type->as_type,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
)
|
||||
) {
|
||||
$else_template_type = clone $atomic_type->else_type;
|
||||
|
@ -430,7 +430,7 @@ function abs($number) {}
|
||||
* @param TStep $step
|
||||
* @return (
|
||||
* T is int
|
||||
* ? (TStep is int ? non-empty-list<int> : non-empty-list<int|float>)
|
||||
* ? (TStep is int ? non-empty-list<int> : non-empty-list<float>)
|
||||
* : (
|
||||
* T is float
|
||||
* ? non-empty-list<float>
|
||||
|
@ -851,6 +851,26 @@ class FunctionCallTest extends TestCase
|
||||
foo($x);
|
||||
}',
|
||||
],
|
||||
'rangeWithIntOrFloatStep' => [
|
||||
'<?php
|
||||
/** @var int|float */
|
||||
$step = 1;
|
||||
$a = range(1, 10, $step);
|
||||
|
||||
/** @var int */
|
||||
$step = 1;
|
||||
$b = range(1, 10, $step);
|
||||
|
||||
/** @var float */
|
||||
$step = 1.;
|
||||
$c = range(1, 10, $step);
|
||||
',
|
||||
'assertions' => [
|
||||
'$a' => 'non-empty-list<float|int>',
|
||||
'$b' => 'non-empty-list<int>',
|
||||
'$c' => 'non-empty-list<float>',
|
||||
],
|
||||
],
|
||||
'duplicateNamespacedFunction' => [
|
||||
'<?php
|
||||
namespace Bar;
|
||||
|
@ -2562,6 +2562,33 @@ class ConditionalTest extends \Psalm\Tests\TestCase
|
||||
return "";
|
||||
}'
|
||||
],
|
||||
'strictIntFloatComparison' => [
|
||||
'<?php
|
||||
/**
|
||||
* @psalm-suppress InvalidReturnType
|
||||
* @psalm-suppress MismatchingDocblockReturnType
|
||||
* @return ($bar is int ? list<int> : list<float>)
|
||||
*/
|
||||
function foo($bar): string {}
|
||||
|
||||
/** @var int */
|
||||
$baz = 1;
|
||||
$a = foo($baz);
|
||||
|
||||
/** @var float */
|
||||
$baz = 1.;
|
||||
$b = foo($baz);
|
||||
|
||||
/** @var int|float */
|
||||
$baz = 1;
|
||||
$c = foo($baz);
|
||||
',
|
||||
'assertions' => [
|
||||
'$a' => 'list<int>',
|
||||
'$b' => 'list<float>',
|
||||
'$c' => 'list<float|int>',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user