Skip to content

Commit

Permalink
Fix list checking on level 7 vs. level 8
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Oct 5, 2022
1 parent f4eee76 commit 9260584
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
3 changes: 1 addition & 2 deletions src/Rules/RuleLevelHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\BenevolentUnionType;
use PHPStan\Type\CompoundType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateMixedType;
use PHPStan\Type\MixedType;
Expand Down Expand Up @@ -98,7 +97,7 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp
}

$accepts = $acceptingType->accepts($acceptedType, $strictTypes);
if (!$accepts->yes() && $acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
if (!$accepts->yes() && $acceptingType instanceof UnionType) {
foreach ($acceptingType->getTypes() as $innerType) {
if (self::accepts($innerType, $acceptedType, $strictTypes)) {
return true;
Expand Down
36 changes: 34 additions & 2 deletions tests/PHPStan/Rules/Functions/ReturnTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@
class ReturnTypeRuleTest extends RuleTestCase
{

private bool $checkExplicitMixed = false;
private bool $checkNullables;

private bool $checkExplicitMixed;

protected function getRule(): Rule
{
return new ReturnTypeRule(new FunctionReturnTypeCheck(new RuleLevelHelper($this->createReflectionProvider(), true, false, true, $this->checkExplicitMixed, false)));
return new ReturnTypeRule(new FunctionReturnTypeCheck(new RuleLevelHelper($this->createReflectionProvider(), $this->checkNullables, false, true, $this->checkExplicitMixed, false)));
}

public function testReturnTypeRule(): void
{
require_once __DIR__ . '/data/returnTypes.php';
$this->checkNullables = true;
$this->checkExplicitMixed = false;
$this->analyse([__DIR__ . '/data/returnTypes.php'], [
[
Expand Down Expand Up @@ -71,6 +74,7 @@ public function testReturnTypeRule(): void
public function testReturnTypeRulePhp70(): void
{
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/returnTypes-7.0.php'], [
[
'Function ReturnTypes\Php70\returnInteger() should return int but empty return statement found.',
Expand All @@ -82,20 +86,23 @@ public function testReturnTypeRulePhp70(): void
public function testIsGenerator(): void
{
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/is-generator.php'], []);
}

public function testBug2568(): void
{
require_once __DIR__ . '/data/bug-2568.php';
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-2568.php'], []);
}

public function testBug2723(): void
{
require_once __DIR__ . '/data/bug-2723.php';
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-2723.php'], [
[
'Function Bug2723\baz() should return Bug2723\Bar<Bug2723\Foo<T4>> but returns Bug2723\BarOfFoo<string>.',
Expand All @@ -107,36 +114,42 @@ public function testBug2723(): void
public function testBug5706(): void
{
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-5706.php'], []);
}

public function testBug5844(): void
{
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-5844.php'], []);
}

public function testBug7218(): void
{
$this->checkExplicitMixed = true;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-7218.php'], []);
}

public function testBug5751(): void
{
$this->checkExplicitMixed = true;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-5751.php'], []);
}

public function testBug3931(): void
{
$this->checkExplicitMixed = true;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-3931.php'], []);
}

public function testBug3801(): void
{
$this->checkExplicitMixed = true;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-3801.php'], [
[
'Function Bug3801\do_foo() should return array{bool, null}|array{null, bool} but returns array{false, true}.',
Expand All @@ -149,4 +162,23 @@ public function testBug3801(): void
]);
}

public function testListWithNullablesChecked(): void
{
$this->checkExplicitMixed = false;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/return-list-nullables.php'], [
[
'Function ReturnListNullables\doFoo() should return array<string>|null but returns array<int, string|null>.',
16,
],
]);
}

public function testListWithNullablesUnchecked(): void
{
$this->checkExplicitMixed = false;
$this->checkNullables = false;
$this->analyse([__DIR__ . '/data/return-list-nullables.php'], []);
}

}
17 changes: 17 additions & 0 deletions tests/PHPStan/Rules/Functions/data/return-list-nullables.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace ReturnListNullables;

/**
* @param array<string|null> $x
* @return array<string>|null
*/
function doFoo(array $x): ?array
{
$list = [];
foreach ($x as $v) {
$list[] = $v;
}

return $list;
}

0 comments on commit 9260584

Please sign in to comment.