1--TEST-- 2Test array promotion does not violate type restrictions 3--FILE-- 4<?php 5 6class Foo { 7 public ?string $p; 8 public ?iterable $i; 9 public static ?string $s; 10 public static ?array $a; 11} 12 13$a = new Foo; 14 15$a->i[] = 1; 16var_dump($a->i); 17 18try { 19 $a->p[] = "test"; 20} catch (TypeError $e) { var_dump($e->getMessage()); } 21try { // must be uninit 22 var_dump($a->p); // WRONG! 23} catch (Error $e) { var_dump($e->getMessage()); } 24 25$a->p = null; 26try { 27 $a->p[] = "test"; 28} catch (TypeError $e) { var_dump($e->getMessage()); } 29var_dump($a->p); 30 31Foo::$a["bar"] = 2; 32var_dump(Foo::$a); 33 34try { 35 Foo::$s["baz"][] = "baz"; 36} catch (TypeError $e) { var_dump($e->getMessage()); } 37try { // must be uninit 38 var_dump(Foo::$s); 39} catch (Error $e) { var_dump($e->getMessage()); } 40 41Foo::$a = null; 42$ref = &Foo::$a; 43$ref[] = 3; 44var_dump($ref); 45 46$ref = &$a->p; 47try { 48 $ref[] = "bar"; 49} catch (TypeError $e) { var_dump($e->getMessage()); } 50var_dump($ref); 51 52try { 53 $ref["baz"][] = "bar"; // indirect assign 54} catch (TypeError $e) { var_dump($e->getMessage()); } 55var_dump($ref); 56 57?> 58--EXPECT-- 59array(1) { 60 [0]=> 61 int(1) 62} 63string(71) "Cannot auto-initialize an array inside property Foo::$p of type ?string" 64string(65) "Typed property Foo::$p must not be accessed before initialization" 65string(71) "Cannot auto-initialize an array inside property Foo::$p of type ?string" 66NULL 67array(1) { 68 ["bar"]=> 69 int(2) 70} 71string(71) "Cannot auto-initialize an array inside property Foo::$s of type ?string" 72string(72) "Typed static property Foo::$s must not be accessed before initialization" 73array(1) { 74 [0]=> 75 int(3) 76} 77string(91) "Cannot auto-initialize an array inside a reference held by property Foo::$p of type ?string" 78NULL 79string(91) "Cannot auto-initialize an array inside a reference held by property Foo::$p of type ?string" 80NULL 81