Skip to content

Commit d504ad6

Browse files
committed
Fixes
1 parent 580d343 commit d504ad6

File tree

4 files changed

+55
-19
lines changed

4 files changed

+55
-19
lines changed

psalm-baseline.xml

+17-4
Original file line numberDiff line numberDiff line change
@@ -2386,10 +2386,6 @@
23862386
? null
23872387
: [$is_list ? Type::getListKey() : Type::getArrayKey(), Type::getMixed()]
23882388
)]]></code>
2389-
<code><![CDATA[$extra_params ?? ($sealed
2390-
? null
2391-
: [Type::getListKey(), Type::getMixed()]
2392-
)]]></code>
23932389
</InvalidArgument>
23942390
<InvalidOperand>
23952391
<code><![CDATA[$property_key - 1]]></code>
@@ -2701,11 +2697,28 @@
27012697
<ImpurePropertyAssignment>
27022698
<code><![CDATA[$key_type->possibly_undefined]]></code>
27032699
</ImpurePropertyAssignment>
2700+
<InvalidReturnStatement>
2701+
<code><![CDATA[new TArray([
2702+
$never, $never,
2703+
], $this->from_docblock)]]></code>
2704+
<code><![CDATA[new TArray([
2705+
$replaced_list_type, $replaced_list_type,
2706+
], $this->from_docblock)]]></code>
2707+
<code><![CDATA[new TArray([
2708+
$never, $never,
2709+
], $this->from_docblock)]]></code>
2710+
</InvalidReturnStatement>
2711+
<InvalidReturnType>
2712+
<code><![CDATA[self|TArray]]></code>
2713+
<code><![CDATA[self|TArray]]></code>
2714+
</InvalidReturnType>
27042715
<PossiblyInvalidOperand>
27052716
<code><![CDATA[$name]]></code>
27062717
<code><![CDATA[$name]]></code>
27072718
</PossiblyInvalidOperand>
27082719
<PossiblyUndefinedIntArrayOffset>
2720+
<code><![CDATA[$fallback_params[1]]]></code>
2721+
<code><![CDATA[$fallback_params[1]]]></code>
27092722
<code><![CDATA[$this->properties[0]]]></code>
27102723
<code><![CDATA[$this->properties[0]]]></code>
27112724
</PossiblyUndefinedIntArrayOffset>

src/Psalm/Internal/Type/Comparator/CallableTypeComparator.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use Psalm\Type\Atomic;
2121
use Psalm\Type\Atomic\TArray;
2222
use Psalm\Type\Atomic\TCallable;
23-
use Psalm\Type\Atomic\TCallableInterface;
2423
use Psalm\Type\Atomic\TClassString;
2524
use Psalm\Type\Atomic\TClosure;
2625
use Psalm\Type\Atomic\TKeyedArray;
@@ -31,6 +30,7 @@
3130
use UnexpectedValueException;
3231

3332
use function array_slice;
33+
use function assert;
3434
use function count;
3535
use function end;
3636
use function strtolower;
@@ -67,6 +67,7 @@ public static function isContainedBy(
6767
) {
6868
return true;
6969
}
70+
assert($input_type_part instanceof TClosure || $input_type_part instanceof TCallable);
7071

7172
if ($container_type_part->is_pure && !$input_type_part->is_pure) {
7273
if ($atomic_comparison_result) {

src/Psalm/Type/Atomic/TKeyedArray.php

+35-13
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,21 @@ public function setIsCallable(bool $is_callable): self
140140

141141
/**
142142
* @param non-empty-array<string|int, Union> $properties
143-
* @return static
144143
*/
145-
public function setProperties(array $properties): self
144+
public function setProperties(array $properties): self|TArray
146145
{
147146
if ($properties === $this->properties) {
148147
return $this;
149148
}
149+
if (count($properties) === 1
150+
&& $properties[array_key_first($properties)]->isNever()
151+
&& ($this->fallback_params === null || $this->fallback_params[1]->isNever())
152+
) {
153+
$never = $properties[array_key_first($properties)];
154+
return new TArray([
155+
$never, $never,
156+
], $this->from_docblock);
157+
}
150158
$cloned = clone $this;
151159
$cloned->properties = $properties;
152160
if ($cloned->is_list) {
@@ -169,9 +177,6 @@ public function setProperties(array $properties): self
169177
return $cloned;
170178
}
171179

172-
/**
173-
* @return static
174-
*/
175180
public function makeSealed(): self
176181
{
177182
if ($this->fallback_params === null) {
@@ -543,9 +548,6 @@ public function getKey(bool $include_extra = true): string
543548
return 'array';
544549
}
545550

546-
/**
547-
* @return static
548-
*/
549551
#[Override]
550552
public function replaceTemplateTypesWithStandins(
551553
TemplateResult $template_result,
@@ -558,7 +560,7 @@ public function replaceTemplateTypesWithStandins(
558560
bool $replace = true,
559561
bool $add_lower_bound = false,
560562
int $depth = 0,
561-
): self {
563+
): self|TArray {
562564
if ($input_type instanceof TKeyedArray
563565
&& $input_type->is_list
564566
&& $input_type->isSealed()
@@ -581,6 +583,11 @@ public function replaceTemplateTypesWithStandins(
581583
->type_params[1]
582584
->setPossiblyUndefined(!$this->isNonEmpty());
583585

586+
if ($replaced_list_type->isNever()) {
587+
return new TArray([
588+
$replaced_list_type, $replaced_list_type,
589+
], $this->from_docblock);
590+
}
584591
$cloned = clone $this;
585592
$cloned->properties = [$replaced_list_type];
586593
$cloned->fallback_params = [$this->fallback_params[1], $replaced_list_type];
@@ -647,20 +654,26 @@ public function replaceTemplateTypesWithStandins(
647654
return $this;
648655
}
649656
$cloned = clone $this;
657+
if (count($properties) === 1
658+
&& $properties[array_key_first($properties)]->isNever()
659+
&& ($fallback_params === null || $fallback_params[1]->isNever())
660+
) {
661+
$never = $properties[array_key_first($properties)];
662+
return new TArray([
663+
$never, $never,
664+
], $this->from_docblock);
665+
}
650666
$cloned->properties = $properties;
651667
/** @psalm-suppress PropertyTypeCoercion */
652668
$cloned->fallback_params = $fallback_params;
653669
return $cloned;
654670
}
655671

656-
/**
657-
* @return static
658-
*/
659672
#[Override]
660673
public function replaceTemplateTypesWithArgTypes(
661674
TemplateResult $template_result,
662675
?Codebase $codebase,
663-
): self {
676+
): self|TArray {
664677
$properties = $this->properties;
665678
foreach ($properties as $offset => $property) {
666679
$properties[$offset] = TemplateInferredTypeReplacer::replace(
@@ -679,6 +692,15 @@ public function replaceTemplateTypesWithArgTypes(
679692
}
680693
if ($properties !== $this->properties || $fallback_params !== $this->fallback_params) {
681694
$cloned = clone $this;
695+
if (count($properties) === 1
696+
&& $properties[array_key_first($properties)]->isNever()
697+
&& ($fallback_params === null || $fallback_params[1]->isNever())
698+
) {
699+
$never = $properties[array_key_first($properties)];
700+
return new TArray([
701+
$never, $never,
702+
], $this->from_docblock);
703+
}
682704
$cloned->properties = $properties;
683705
/** @psalm-suppress PropertyTypeCoercion */
684706
$cloned->fallback_params = $fallback_params;

tests/CallableTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2297,7 +2297,7 @@ function int_int_int_int(Closure $f): void {}
22972297
],
22982298
'callableArrayTypes' => [
22992299
'code' => '<?php
2300-
/** @var callable-array $c */
2300+
/** @var callable-list $c */
23012301
$c;
23022302
[$a, $b] = $c;
23032303
',

0 commit comments

Comments
 (0)