Skip to content

Commit 6cf2238

Browse files
committed
ArrayType::describe - explicit mixed should be stated explicitly
1 parent a934639 commit 6cf2238

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+151
-154
lines changed

phpstan-baseline.neon

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ parameters:
1313
path: src/Analyser/AnalyserResultFinalizer.php
1414

1515
-
16-
message: '#^Cannot assign offset ''realCount'' to array\|string\.$#'
16+
message: '#^Cannot assign offset ''realCount'' to array\<mixed\>\|string\.$#'
1717
identifier: offsetAssign.dimType
1818
count: 1
1919
path: src/Analyser/Ignore/IgnoredErrorHelperResult.php

src/Type/ArrayType.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ public function equals(Type $type): bool
128128

129129
public function describe(VerbosityLevel $level): string
130130
{
131-
$isMixedKeyType = $this->keyType instanceof MixedType && $this->keyType->describe(VerbosityLevel::precise()) === 'mixed';
132-
$isMixedItemType = $this->itemType instanceof MixedType && $this->itemType->describe(VerbosityLevel::precise()) === 'mixed';
131+
$isMixedKeyType = $this->keyType instanceof MixedType && $this->keyType->describe(VerbosityLevel::precise()) === 'mixed' && !$this->keyType->isExplicitMixed();
132+
$isMixedItemType = $this->itemType instanceof MixedType && $this->itemType->describe(VerbosityLevel::precise()) === 'mixed' && !$this->itemType->isExplicitMixed();
133133

134134
$valueHandler = function () use ($level, $isMixedKeyType, $isMixedItemType): string {
135135
if ($isMixedKeyType || $this->keyType instanceof NeverType) {
@@ -500,8 +500,8 @@ public function traverse(callable $cb): Type
500500

501501
public function toPhpDocNode(): TypeNode
502502
{
503-
$isMixedKeyType = $this->keyType instanceof MixedType && $this->keyType->describe(VerbosityLevel::precise()) === 'mixed';
504-
$isMixedItemType = $this->itemType instanceof MixedType && $this->itemType->describe(VerbosityLevel::precise()) === 'mixed';
503+
$isMixedKeyType = $this->keyType instanceof MixedType && $this->keyType->describe(VerbosityLevel::precise()) === 'mixed' && !$this->keyType->isExplicitMixed();
504+
$isMixedItemType = $this->itemType instanceof MixedType && $this->itemType->describe(VerbosityLevel::precise()) === 'mixed' && !$this->itemType->isExplicitMixed();
505505

506506
if ($isMixedKeyType) {
507507
if ($isMixedItemType) {

src/Type/Php/ArraySearchFunctionTypeSpecifyingExtension.php

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
use PHPStan\Analyser\TypeSpecifierContext;
1111
use PHPStan\Reflection\FunctionReflection;
1212
use PHPStan\Type\Accessory\NonEmptyArrayType;
13-
use PHPStan\Type\ArrayType;
1413
use PHPStan\Type\FunctionTypeSpecifyingExtension;
15-
use PHPStan\Type\MixedType;
16-
use PHPStan\Type\TypeCombinator;
1714
use function strtolower;
1815

1916
final class ArraySearchFunctionTypeSpecifyingExtension implements FunctionTypeSpecifyingExtension, TypeSpecifierAwareExtension
@@ -45,7 +42,7 @@ public function specifyTypes(
4542

4643
return $this->typeSpecifier->create(
4744
$arrayArg,
48-
TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new NonEmptyArrayType()),
45+
new NonEmptyArrayType(),
4946
$context,
5047
$scope,
5148
);

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,7 @@ public function testBug9459(): void
11981198
{
11991199
$errors = $this->runAnalyse(__DIR__ . '/data/bug-9459.php');
12001200
$this->assertCount(1, $errors);
1201-
$this->assertSame('PHPDoc tag @var with type callable(): array is not subtype of native type Closure(): array{}.', $errors[0]->getMessage());
1201+
$this->assertSame('PHPDoc tag @var with type callable(): array<mixed> is not subtype of native type Closure(): array{}.', $errors[0]->getMessage());
12021202
$this->assertSame(10, $errors[0]->getLine());
12031203
}
12041204

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,7 @@ public function dataProperties(): array
17631763
'$this->arrayPropertyOne',
17641764
],
17651765
[
1766-
'array',
1766+
'array<mixed>',
17671767
'$this->arrayPropertyOther',
17681768
],
17691769
[
@@ -3423,7 +3423,7 @@ public function dataTypeFromFunctionPhpDocs(): array
34233423
'$arrayParameterOne',
34243424
],
34253425
[
3426-
'array',
3426+
'array<mixed>',
34273427
'$arrayParameterOther',
34283428
],
34293429
[
@@ -5779,7 +5779,7 @@ public function dataSpecifiedTypesUsingIsFunctions(): array
57795779
'$null',
57805780
],
57815781
[
5782-
'array',
5782+
'array<mixed, mixed>',
57835783
'$array',
57845784
],
57855785
[
@@ -9252,7 +9252,7 @@ public function dataInferPrivatePropertyTypeFromConstructor(): array
92529252
'$this->bool',
92539253
],
92549254
[
9255-
'array',
9255+
'array<mixed, mixed>',
92569256
'$this->array',
92579257
],
92589258
];

tests/PHPStan/Analyser/TypeSpecifierTest.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -1218,8 +1218,8 @@ public function dataCondition(): iterable
12181218
),
12191219
new Identical(new Expr\ConstFetch(new Name('null')), new Variable('a')),
12201220
),
1221-
['$a' => 'non-empty-array|null'],
1222-
['$a' => 'mixed~non-empty-array & ~null'],
1221+
['$a' => 'non-empty-array<mixed, mixed>|null'],
1222+
['$a' => 'mixed~non-empty-array<mixed, mixed> & ~null'],
12231223
],
12241224
[
12251225
new Expr\BinaryOp\BooleanAnd(
@@ -1234,7 +1234,7 @@ public function dataCondition(): iterable
12341234
),
12351235
[
12361236
'$foo' => 'array<string, mixed>',
1237-
'array_filter($foo, \'is_string\', ARRAY_FILTER_USE_KEY)' => 'array', // could be 'array<string, mixed>'
1237+
'array_filter($foo, \'is_string\', ARRAY_FILTER_USE_KEY)' => 'array<mixed, mixed>', // could be 'array<string, mixed>'
12381238
],
12391239
[],
12401240
],
@@ -1250,7 +1250,7 @@ public function dataCondition(): iterable
12501250
),
12511251
),
12521252
[
1253-
'$foo' => 'non-empty-array',
1253+
'$foo' => 'non-empty-array<mixed, mixed>',
12541254
'count($foo)' => 'mixed~(0.0|int<min, 1>|false|null)',
12551255
],
12561256
[],
@@ -1267,7 +1267,7 @@ public function dataCondition(): iterable
12671267
),
12681268
),
12691269
[
1270-
'$foo' => 'non-empty-array',
1270+
'$foo' => 'non-empty-array<mixed, mixed>',
12711271
'count($foo)' => '2',
12721272
],
12731273
[],

tests/PHPStan/Analyser/data/param-out.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ function testParseStr() {
315315
echo $output['arr'][1];//baz
316316
*/
317317

318-
\PHPStan\Testing\assertType('array<int|string, array|lowercase-string>', $output);
318+
\PHPStan\Testing\assertType('array<int|string, array<mixed>|lowercase-string>', $output);
319319
}
320320

321321
function fooSimilar() {
@@ -392,10 +392,10 @@ function fooHeadersSent() {
392392

393393
function fooMbParseStr() {
394394
mb_parse_str("foo=bar", $output);
395-
assertType('array<string, array|string>', $output);
395+
assertType('array<string, array<mixed>|string>', $output);
396396

397397
mb_parse_str('[email protected]&city=town&x=1&y[g]=3&f=1.23', $output);
398-
assertType('array<string, array|string>', $output);
398+
assertType('array<string, array<mixed>|string>', $output);
399399
}
400400

401401
function fooPreg()

tests/PHPStan/Analyser/nsrt/array-chunk.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public function generalArrays(array $arr): void
1111
{
1212
/** @var mixed[] $arr */
1313
assertType('list<non-empty-list<mixed>>', array_chunk($arr, 2));
14-
assertType('list<non-empty-array>', array_chunk($arr, 2, true));
14+
assertType('list<non-empty-array<mixed>>', array_chunk($arr, 2, true));
1515

1616
/** @var array<string, int> $arr */
1717
assertType('list<non-empty-list<int>>', array_chunk($arr, 2));

tests/PHPStan/Analyser/nsrt/array-fill-keys-php8.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
function mixedAndSubtractedArray($mixed): void
88
{
99
if (is_array($mixed)) {
10-
assertType("array<'b'>", array_fill_keys($mixed, 'b'));
10+
assertType("array<mixed, 'b'>", array_fill_keys($mixed, 'b'));
1111
} else {
1212
assertType("*NEVER*", array_fill_keys($mixed, 'b'));
1313
}

tests/PHPStan/Analyser/nsrt/array-flip-php8.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function mixedAndSubtractedArray($mixed)
99
if (is_array($mixed)) {
1010
assertType('array<int|string, (int|string)>', array_flip($mixed));
1111
} else {
12-
assertType('mixed~array', $mixed);
12+
assertType('mixed~array<mixed, mixed>', $mixed);
1313
assertType('*NEVER*', array_flip($mixed));
1414
}
1515
}

tests/PHPStan/Analyser/nsrt/array-intersect-key-php8.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function mixedAndSubtractedArray($mixed, array $otherArrs): void
1616
/** @var array<string, int> $otherArrs */
1717
assertType('array<string, mixed>', array_intersect_key($mixed, $otherArrs));
1818
} else {
19-
assertType('mixed~array', $mixed);
19+
assertType('mixed~array<mixed, mixed>', $mixed);
2020
/** @var array<int, string> $otherArrs */
2121
assertType('*NEVER*', array_intersect_key($mixed, $otherArrs));
2222
/** @var array<string, int> $otherArrs */

tests/PHPStan/Analyser/nsrt/array-pop.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function foo1($mixed): void
7777
if(is_array($mixed)) {
7878
assertType('mixed', array_pop($mixed));
7979
} else {
80-
assertType('mixed~array', $mixed);
80+
assertType('mixed~array<mixed, mixed>', $mixed);
8181
assertType('mixed', array_pop($mixed));
8282
assertType('*ERROR*', $mixed);
8383
}

tests/PHPStan/Analyser/nsrt/array-reverse.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class Foo
1414
*/
1515
public function normalArrays(array $a, array $b): void
1616
{
17-
assertType('array', array_reverse($a));
18-
assertType('array', array_reverse($a, true));
17+
assertType('array<mixed>', array_reverse($a));
18+
assertType('array<mixed>', array_reverse($a, true));
1919

2020
assertType('array<string, int>', array_reverse($b));
2121
assertType('array<string, int>', array_reverse($b, true));
@@ -68,8 +68,8 @@ public function list(array $a, array $b): void
6868

6969
public function mixed(mixed $mixed): void
7070
{
71-
assertType('array', array_reverse($mixed));
72-
assertType('array', array_reverse($mixed, true));
71+
assertType('array<mixed, mixed>', array_reverse($mixed));
72+
assertType('array<mixed, mixed>', array_reverse($mixed, true));
7373

7474
if (array_key_exists('foo', $mixed)) {
7575
assertType('non-empty-array', array_reverse($mixed));

tests/PHPStan/Analyser/nsrt/array-search-php8.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function mixedAndSubtractedArray($mixed, string $string): void
1616
assertType('int|string|false', array_search('foo', $mixed));
1717
assertType('int|string|false', array_search($string, $mixed, true));
1818
} else {
19-
assertType('mixed~array', $mixed);
19+
assertType('mixed~array<mixed, mixed>', $mixed);
2020
assertType('*NEVER*', array_search('foo', $mixed, true));
2121
assertType('*NEVER*', array_search('foo', $mixed));
2222
assertType('*NEVER*', array_search($string, $mixed, true));

tests/PHPStan/Analyser/nsrt/array-shift.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function foo1($mixed): void
7777
if(is_array($mixed)) {
7878
assertType('mixed', array_shift($mixed));
7979
} else {
80-
assertType('mixed~array', $mixed);
80+
assertType('mixed~array<mixed, mixed>', $mixed);
8181
assertType('mixed', array_shift($mixed));
8282
assertType('*ERROR*', $mixed);
8383
}

tests/PHPStan/Analyser/nsrt/array-slice.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function nonEmpty(array $a, array $b, array $c): void
2424
*/
2525
public function fromMixed($arr): void
2626
{
27-
assertType('array', array_slice($arr, 1, 2));
27+
assertType('array<mixed, mixed>', array_slice($arr, 1, 2));
2828
}
2929

3030
public function normalArrays(array $arr): void

tests/PHPStan/Analyser/nsrt/array_keys.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public function sayHello($mixed): void
1111
if(is_array($mixed)) {
1212
assertType('list<(int|string)>', array_keys($mixed));
1313
} else {
14-
assertType('mixed~array', $mixed);
14+
assertType('mixed~array<mixed, mixed>', $mixed);
1515
assertType('*NEVER*', array_keys($mixed));
1616
}
1717
}

tests/PHPStan/Analyser/nsrt/array_values.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public function foo1($mixed): void
1111
if(is_array($mixed)) {
1212
assertType('list<mixed>', array_values($mixed));
1313
} else {
14-
assertType('mixed~array', $mixed);
14+
assertType('mixed~array<mixed, mixed>', $mixed);
1515
assertType('*NEVER*', array_values($mixed));
1616
}
1717
}

tests/PHPStan/Analyser/nsrt/assert-docblock.php

+11-11
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function validateNotNull($value) : void {}
5656
* @param mixed[] $arr
5757
*/
5858
function takesArray(array $arr) : void {
59-
assertType('array', $arr);
59+
assertType('array<mixed>', $arr);
6060

6161
validateStringArray($arr);
6262
assertType('array<string>', $arr);
@@ -66,22 +66,22 @@ function takesArray(array $arr) : void {
6666
* @param mixed[] $arr
6767
*/
6868
function takesArrayIfTrue(array $arr) : void {
69-
assertType('array', $arr);
69+
assertType('array<mixed>', $arr);
7070

7171
if (validateStringArrayIfTrue($arr)) {
7272
assertType('array<string>', $arr);
7373
} else {
74-
assertType('array', $arr);
74+
assertType('array<mixed>', $arr);
7575
}
7676
}
7777
/**
7878
* @param mixed[] $arr
7979
*/
8080
function takesArrayIfTrue1(array $arr) : void {
81-
assertType('array', $arr);
81+
assertType('array<mixed>', $arr);
8282

8383
if (!validateStringArrayIfTrue($arr)) {
84-
assertType('array', $arr);
84+
assertType('array<mixed>', $arr);
8585
} else {
8686
assertType('array<string>', $arr);
8787
}
@@ -91,23 +91,23 @@ function takesArrayIfTrue1(array $arr) : void {
9191
* @param mixed[] $arr
9292
*/
9393
function takesArrayIfFalse(array $arr) : void {
94-
assertType('array', $arr);
94+
assertType('array<mixed>', $arr);
9595

9696
if (!validateStringArrayIfFalse($arr)) {
9797
assertType('array<string>', $arr);
9898
} else {
99-
assertType('array', $arr);
99+
assertType('array<mixed>', $arr);
100100
}
101101
}
102102

103103
/**
104104
* @param mixed[] $arr
105105
*/
106106
function takesArrayIfFalse1(array $arr) : void {
107-
assertType('array', $arr);
107+
assertType('array<mixed>', $arr);
108108

109109
if (validateStringArrayIfFalse($arr)) {
110-
assertType('array', $arr);
110+
assertType('array<mixed>', $arr);
111111
} else {
112112
assertType('array<string>', $arr);
113113
}
@@ -117,7 +117,7 @@ function takesArrayIfFalse1(array $arr) : void {
117117
* @param mixed[] $arr
118118
*/
119119
function takesStringOrIntArray(array $arr) : void {
120-
assertType('array', $arr);
120+
assertType('array<mixed>', $arr);
121121

122122
if (validateStringOrIntArray($arr)) {
123123
assertType('array<string>', $arr);
@@ -130,7 +130,7 @@ function takesStringOrIntArray(array $arr) : void {
130130
* @param mixed[] $arr
131131
*/
132132
function takesStringOrNonEmptyIntArray(array $arr) : void {
133-
assertType('array', $arr);
133+
assertType('array<mixed>', $arr);
134134

135135
if (validateStringOrNonEmptyIntArray($arr)) {
136136
assertType('array<string>', $arr);

tests/PHPStan/Analyser/nsrt/assert-methods.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function doBar($mixed)
3737
public function doBar2(array $objects)
3838
{
3939
self::doFoo($objects, stdClass::class);
40-
assertType('array<stdClass>', $objects);
40+
assertType('array<mixed, stdClass>', $objects);
4141
}
4242

4343
/**
@@ -47,7 +47,7 @@ public function doBar2(array $objects)
4747
public function doBar3(array $strings)
4848
{
4949
self::doFoo($strings, stdClass::class);
50-
assertType('array<class-string<stdClass>>', $strings);
50+
assertType('array<mixed, class-string<stdClass>>', $strings);
5151
}
5252

5353
/**

tests/PHPStan/Analyser/nsrt/bug-1209.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public function sayHello($value): void
1313
{
1414
$isArray = is_array($value);
1515
if($isArray){
16-
assertType('array', $value);
16+
assertType('array<mixed>', $value);
1717
}
1818
}
1919

tests/PHPStan/Analyser/nsrt/bug-1233.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ public function toArray($value): array
1010
{
1111
assertType('mixed', $value);
1212
if (is_array($value)) {
13-
assertType('array', $value);
13+
assertType('array<mixed, mixed>', $value);
1414
return $value;
1515
}
1616

17-
assertType('mixed~array', $value);
17+
assertType('mixed~array<mixed, mixed>', $value);
1818

1919
if (is_iterable($value)) {
2020
assertType('Traversable<mixed, mixed>', $value);
2121
return iterator_to_array($value);
2222
}
2323

24-
assertType('mixed~array', $value);
24+
assertType('mixed~array<mixed, mixed>', $value);
2525

2626
throw new \LogicException();
2727
}

0 commit comments

Comments
 (0)