Skip to content

Commit 57567df

Browse files
committed
1 parent 9f68496 commit 57567df

12 files changed

+252
-0
lines changed

tests/PHPStan/Analyser/NodeScopeResolverTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ public function dataFileAsserts(): iterable
858858
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-3853.php');
859859
yield from $this->gatherAssertTypes(__DIR__ . '/data/conditional-types.php');
860860
yield from $this->gatherAssertTypes(__DIR__ . '/data/constant-array-optional-set.php');
861+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6383.php');
862+
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/bug-3284.php');
861863
}
862864

863865
/**
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Bug6383Types;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
function doFoo(string $country): void {
11+
$options = [
12+
[
13+
'value' => 'a',
14+
'checked' => false,
15+
'only_in_country' => ['DE'],
16+
],
17+
[
18+
'value' => 'b',
19+
'checked' => false,
20+
'only_in_country' => ['BE', 'CH', 'DE', 'DK', 'FR', 'NL', 'SE'],
21+
],
22+
[
23+
'value' => 'c',
24+
'checked' => false,
25+
],
26+
];
27+
28+
foreach ($options as $key => $option) {
29+
if (isset($option['only_in_country'])) {
30+
assertType("array{value: 'a'|'b'|'c', checked: false, only_in_country: array{0: 'BE'|'DE', 1?: 'CH', 2?: 'DE', 3?: 'DK', 4?: 'FR', 5?: 'NL', 6?: 'SE'}}", $option);
31+
continue;
32+
}
33+
}
34+
}
35+
36+
}

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -367,4 +367,9 @@ public function testBug4747(): void
367367
$this->analyse([__DIR__ . '/data/bug-4747.php'], []);
368368
}
369369

370+
public function testBug6379(): void
371+
{
372+
$this->analyse([__DIR__ . '/data/bug-6379.php'], []);
373+
}
374+
370375
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Bug6379;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @param array{
9+
* cr?: string,
10+
* c?: string
11+
* } $params
12+
*/
13+
public static function paramsToString(array $params): string
14+
{
15+
if (isset($params['cr']) === true || isset($params['c']) === true) {
16+
return sprintf('-c%s', $params['cr'] ?? $params['c']);
17+
}
18+
19+
return '';
20+
}
21+
}

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -961,4 +961,9 @@ public function testBug4413(): void
961961
]);
962962
}
963963

964+
public function testBug6383(): void
965+
{
966+
$this->analyse([__DIR__ . '/data/bug-6383.php'], []);
967+
}
968+
964969
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Bug6383;
4+
5+
class Foo
6+
{
7+
8+
function doFoo(string $country): void {
9+
$options = [
10+
[
11+
'value' => 'a',
12+
'checked' => false,
13+
'only_in_country' => ['DE'],
14+
],
15+
[
16+
'value' => 'b',
17+
'checked' => false,
18+
'only_in_country' => ['BE', 'CH', 'DE', 'DK', 'FR', 'NL', 'SE'],
19+
],
20+
[
21+
'value' => 'c',
22+
'checked' => false,
23+
],
24+
];
25+
26+
foreach ($options as $key => $option) {
27+
if (isset($option['only_in_country'])
28+
&& !in_array($country, $option['only_in_country'], true)) {
29+
unset($options[$key]);
30+
31+
continue;
32+
}
33+
}
34+
}
35+
36+
}

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

+9
Original file line numberDiff line numberDiff line change
@@ -2504,4 +2504,13 @@ public function testBug6917(): void
25042504
$this->analyse([__DIR__ . '/data/bug-6917.php'], []);
25052505
}
25062506

2507+
public function testBug3284(): void
2508+
{
2509+
$this->checkThisOnly = false;
2510+
$this->checkNullables = true;
2511+
$this->checkUnionTypes = true;
2512+
$this->checkExplicitMixed = false;
2513+
$this->analyse([__DIR__ . '/data/bug-3284.php'], []);
2514+
}
2515+
25072516
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Bug3284;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class HelloWorld
8+
{
9+
/**
10+
* @param array{a?:string, b?:string, a?:string} $settings
11+
*/
12+
public function sayHello(array $settings): void
13+
{
14+
assertType('array{a?: string, b?: string}', $settings);
15+
echo 'Hello' . ($settings['b'] ?? 'unknown');
16+
}
17+
18+
public function doFoo()
19+
{
20+
$this->sayHello(['b' => 'name']);
21+
}
22+
}

tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php

+9
Original file line numberDiff line numberDiff line change
@@ -420,4 +420,13 @@ public function testGenericObjectWithUnspecifiedTemplateTypesLevel8(): void
420420
]);
421421
}
422422

423+
public function testBug5382(): void
424+
{
425+
if (PHP_VERSION_ID < 70400) {
426+
$this->markTestSkipped('Test requires PHP 7.4.');
427+
}
428+
$this->checkExplicitMixed = false;
429+
$this->analyse([__DIR__ . '/data/bug-5382.php'], []);
430+
}
431+
423432
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace Bug5382;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @var non-empty-list<\stdClass>
9+
*/
10+
public array $providers;
11+
12+
/**
13+
* @param non-empty-list<\stdClass>|null $providers
14+
*/
15+
public function __construct(?array $providers = null)
16+
{
17+
$this->providers = $providers ?? [
18+
new \stdClass(),
19+
];
20+
}
21+
}
22+
23+
class HelloWorld2
24+
{
25+
/**
26+
* @var non-empty-list<\stdClass>
27+
*/
28+
public array $providers;
29+
30+
/**
31+
* @param non-empty-list<\stdClass>|null $providers
32+
*/
33+
public function __construct(?array $providers = null)
34+
{
35+
$this->providers = $providers ?? [
36+
new \stdClass(),
37+
];
38+
39+
$this->providers = $providers ?: [
40+
new \stdClass(),
41+
];
42+
43+
$this->providers = $providers !== null ? $providers : [
44+
new \stdClass(),
45+
];
46+
47+
$providers ??= [
48+
new \stdClass(),
49+
];
50+
$this->providers = $providers;
51+
}
52+
}
53+
54+
class HelloWorld3
55+
{
56+
/**
57+
* @var non-empty-list<\stdClass>
58+
*/
59+
public array $providers;
60+
61+
/**
62+
* @param non-empty-list<\stdClass>|null $providers
63+
*/
64+
public function __construct(?array $providers = null)
65+
{
66+
/** @var non-empty-list<\stdClass> $newList */
67+
$newList = [new \stdClass()];
68+
$newList2 = [new \stdClass()];
69+
70+
$this->providers = $providers ?? $newList;
71+
$this->providers = $providers ?? $newList2;
72+
}
73+
}

tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,10 @@ public function testNullCoalesceInGlobalScope(): void
268268
]);
269269
}
270270

271+
public function testBug5933(): void
272+
{
273+
$this->treatPhpDocTypesAsCertain = true;
274+
$this->analyse([__DIR__ . '/data/bug-5933.php'], []);
275+
}
276+
271277
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Bug5933;
4+
5+
class HelloWorld
6+
{
7+
public function sayHello(): void
8+
{
9+
$arr = [];
10+
11+
for ($i = 0; $i < 100; $i++) {
12+
if (rand(0, 1) === 0) {
13+
$arr[$i]['a'] = $i;
14+
} else {
15+
$arr[$i]['b'] = $i;
16+
}
17+
}
18+
19+
foreach($arr as $val) {
20+
var_dump($val['a'] ?? null);
21+
}
22+
23+
// Suprisingly it doesn't have a problem with this
24+
for ($i = 0; $i < 100; $i++) {
25+
var_dump($arr[$i]['a'] ?? null);
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)