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