Skip to content

Commit 024e98e

Browse files
jiripudilondrejmirtes
authored andcommitted
Add an integration test case for generic variance
1 parent 8124183 commit 024e98e

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,6 +2512,32 @@ public function testGenericsInferCollectionLevel8(): void
25122512
]);
25132513
}
25142514

2515+
public function testGenericVariance(): void
2516+
{
2517+
$this->checkThisOnly = false;
2518+
$this->checkNullables = true;
2519+
$this->checkUnionTypes = true;
2520+
$this->checkExplicitMixed = false;
2521+
$this->analyse([__DIR__ . '/data/generic-variance.php'], [
2522+
[
2523+
'Parameter #1 $param of method GenericVarianceCall\Foo::invariant() expects GenericVarianceCall\Invariant<GenericVarianceCall\B>, GenericVarianceCall\Invariant<GenericVarianceCall\A> given.',
2524+
45,
2525+
],
2526+
[
2527+
'Parameter #1 $param of method GenericVarianceCall\Foo::invariant() expects GenericVarianceCall\Invariant<GenericVarianceCall\B>, GenericVarianceCall\Invariant<GenericVarianceCall\C> given.',
2528+
53,
2529+
],
2530+
[
2531+
'Parameter #1 $param of method GenericVarianceCall\Foo::covariant() expects GenericVarianceCall\Covariant<GenericVarianceCall\B>, GenericVarianceCall\Covariant<GenericVarianceCall\A> given.',
2532+
60,
2533+
],
2534+
[
2535+
'Parameter #1 $param of method GenericVarianceCall\Foo::contravariant() expects GenericVarianceCall\Contravariant<GenericVarianceCall\B>, GenericVarianceCall\Contravariant<GenericVarianceCall\C> given.',
2536+
83,
2537+
],
2538+
]);
2539+
}
2540+
25152541
public function testBug6904(): void
25162542
{
25172543
if (PHP_VERSION_ID < 80100) {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace GenericVarianceCall;
4+
5+
class A {}
6+
class B extends A {}
7+
class C extends B {}
8+
9+
/** @template T */
10+
class Invariant {}
11+
12+
/** @template-covariant T */
13+
class Covariant {}
14+
15+
/** @template-contravariant T */
16+
class Contravariant {}
17+
18+
class Foo
19+
{
20+
/**
21+
* @param Invariant<B> $param
22+
*/
23+
public function invariant(Invariant $param): void
24+
{
25+
}
26+
27+
/**
28+
* @param Covariant<B> $param
29+
*/
30+
public function covariant(Covariant $param): void
31+
{
32+
}
33+
34+
/**
35+
* @param Contravariant<B> $param
36+
*/
37+
public function contravariant(Contravariant $param): void
38+
{
39+
}
40+
41+
public function testInvariant(): void
42+
{
43+
/** @var Invariant<A> $invariantA */
44+
$invariantA = new Invariant();
45+
$this->invariant($invariantA);
46+
47+
/** @var Invariant<B> $invariantB */
48+
$invariantB = new Invariant();
49+
$this->invariant($invariantB);
50+
51+
/** @var Invariant<C> $invariantC */
52+
$invariantC = new Invariant();
53+
$this->invariant($invariantC);
54+
}
55+
56+
public function testCovariant(): void
57+
{
58+
/** @var Covariant<A> $covariantA */
59+
$covariantA = new Covariant();
60+
$this->covariant($covariantA);
61+
62+
/** @var Covariant<B> $covariantB */
63+
$covariantB = new Covariant();
64+
$this->covariant($covariantB);
65+
66+
/** @var Covariant<C> $covariantC */
67+
$covariantC = new Covariant();
68+
$this->covariant($covariantC);
69+
}
70+
71+
public function testContravariant(): void
72+
{
73+
/** @var Contravariant<A> $contravariantA */
74+
$contravariantA = new Contravariant();
75+
$this->contravariant($contravariantA);
76+
77+
/** @var Contravariant<B> $contravariantB */
78+
$contravariantB = new Contravariant();
79+
$this->contravariant($contravariantB);
80+
81+
/** @var Contravariant<C> $contravariantC */
82+
$contravariantC = new Contravariant();
83+
$this->contravariant($contravariantC);
84+
}
85+
}

0 commit comments

Comments
 (0)