1--TEST--
2Typed references must be kept track of and always be only the intersection of the type currently holding that reference
3--FILE--
4<?php
5
6$a = new class {
7    public ?iterable $it = [];
8    public ?array $a;
9    public ?Traversable $t;
10};
11
12$ref = &$a->it;
13$a->a = &$ref;
14
15var_dump($ref);
16
17try {
18    $a->t = &$ref;
19} catch (TypeError $e) { var_dump($e->getMessage()); }
20var_dump($ref);
21
22$a->it = [1]; // type is still assignable
23var_dump($ref);
24
25try {
26    $ref = new ArrayIterator();
27} catch (TypeError $e) { var_dump($e->getMessage()); }
28var_dump($ref instanceof ArrayIterator);
29
30unset($a->a);
31
32$ref = null;
33
34$a->t = &$ref;
35
36try {
37    $ref = [];
38} catch (TypeError $e) { var_dump($e->getMessage()); }
39var_dump($ref instanceof ArrayIterator);
40
41$ref = new ArrayIterator();
42var_dump($ref instanceof ArrayIterator);
43
44?>
45--EXPECT--
46array(0) {
47}
48string(72) "Cannot assign array to property class@anonymous::$t of type ?Traversable"
49array(0) {
50}
51array(1) {
52  [0]=>
53  int(1)
54}
55string(92) "Cannot assign ArrayIterator to reference held by property class@anonymous::$a of type ?array"
56bool(false)
57string(90) "Cannot assign array to reference held by property class@anonymous::$t of type ?Traversable"
58bool(false)
59bool(true)
60