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