Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3863,7 +3863,12 @@ private function processStmtVarAnnotation(MutatingScope $scope, Node\Stmt $stmt,
$certainty = TrinaryLogic::createYes();
}

$scope = $scope->assignVariable($name, $varTag->getType(), new MixedType(), $certainty);
$scope = $scope->assignVariable(
$name,
$varTag->getType(),
$scope->getNativeType(new Variable($name)),
$certainty,
);
}
}

Expand Down
12 changes: 12 additions & 0 deletions tests/PHPStan/Analyser/data/native-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,15 @@ function fooFunction(
assertType('string', $nonNullableString);
assertNativeType('string', $nonNullableString);
}

function phpDocDoesNotInfluenceExistingNativeType(): void
{
$array = [];

assertType('array{}', $array);
assertNativeType('array{}', $array);

/** @var array<string> $array */
assertType('array<string>', $array);
assertNativeType('array{}', $array);
}
28 changes: 26 additions & 2 deletions tests/PHPStan/Analyser/data/shuffle.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,28 @@
class Foo
{

public function normalArrays(array $arr): void
public function normalArrays1(array $arr): void
{
/** @var mixed[] $arr */
shuffle($arr);
assertType('list<mixed>', $arr);
assertNativeType('list<mixed>', $arr);
assertType('list<int<0, max>>', array_keys($arr));
assertType('list<mixed>', array_values($arr));
}

public function normalArrays2(array $arr): void
{
/** @var non-empty-array<string, int> $arr */
shuffle($arr);
assertType('non-empty-list<int>', $arr);
assertNativeType('list<mixed>', $arr);
assertType('non-empty-list<int<0, max>>', array_keys($arr));
assertType('non-empty-list<int>', array_values($arr));
}

public function normalArrays3(array $arr): void
{
/** @var array<mixed> $arr */
if (array_key_exists('foo', $arr)) {
shuffle($arr);
Expand All @@ -32,7 +38,10 @@ public function normalArrays(array $arr): void
assertType('non-empty-list<int<0, max>>', array_keys($arr));
assertType('non-empty-list<mixed>', array_values($arr));
}
}

public function normalArrays4(array $arr): void
{
/** @var array<mixed> $arr */
if (array_key_exists('foo', $arr) && $arr['foo'] === 'bar') {
shuffle($arr);
Expand All @@ -43,43 +52,58 @@ public function normalArrays(array $arr): void
}
}

public function constantArrays(array $arr): void
public function constantArrays1(array $arr): void
{
$arr = [];
shuffle($arr);
assertType('array{}', $arr);
assertNativeType('array{}', $arr);
assertType('array{}', array_keys($arr));
assertType('array{}', array_values($arr));
}

public function constantArrays2(array $arr): void
{
/** @var array{0?: 1, 1?: 2, 2?: 3} $arr */
shuffle($arr);
assertType('array<0|1|2, 1|2|3>&list', $arr);
assertNativeType('list<mixed>', $arr);
assertType('list<0|1|2>', array_keys($arr));
assertType('list<1|2|3>', array_values($arr));
}

public function constantArrays3(array $arr): void
{
$arr = [1, 2, 3];
shuffle($arr);
assertType('non-empty-array<0|1|2, 1|2|3>&list', $arr);
assertNativeType('non-empty-array<0|1|2, 1|2|3>&list', $arr);
assertType('non-empty-list<0|1|2>', array_keys($arr));
assertType('non-empty-list<1|2|3>', array_values($arr));
}

public function constantArrays4(array $arr): void
{
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
shuffle($arr);
assertType('non-empty-array<0|1|2, 1|2|3>&list', $arr);
assertNativeType('non-empty-array<0|1|2, 1|2|3>&list', $arr);
assertType('non-empty-list<0|1|2>', array_keys($arr));
assertType('non-empty-list<1|2|3>', array_values($arr));
}

public function constantArrays5(array $arr): void
{
$arr = [0 => 1, 3 => 2, 42 => 3];
shuffle($arr);
assertType('non-empty-array<0|1|2, 1|2|3>&list', $arr);
assertNativeType('non-empty-array<0|1|2, 1|2|3>&list', $arr);
assertType('non-empty-list<0|1|2>', array_keys($arr));
assertType('non-empty-list<1|2|3>', array_values($arr));
}

public function constantArrays6(array $arr): void
{
/** @var array{foo?: 1, bar: 2, }|array{baz: 3, foobar?: 4} $arr */
shuffle($arr);
assertType('non-empty-array<0|1, 1|2|3|4>&list', $arr);
Expand Down