1--TEST--
2Computation of intersection types for typed reference to typed property assignments
3--FILE--
4<?php
5
6class A {}
7class B extends A {}
8
9class Test {
10    public int $int;
11    public float $float;
12    public ?int $nint;
13    public ?string $nstring;
14    public array $array;
15    public object $object;
16    public iterable $iterable;
17    public Iterator $Iterator;
18    public A $A;
19    public B $B;
20}
21
22function invalid(Test $test, string $prop1, string $prop2, $value) {
23    try {
24        $test->$prop2 = $value;
25        $test->$prop1 =& $test->$prop2;
26        echo "Invalid assignment $prop1 =& $prop2 did not error\n";
27    } catch (TypeError $e) {}
28    try {
29        $test->$prop1 = $value;
30        $test->$prop2 =& $test->$prop1;
31        echo "Invalid assignment $prop2 =& $prop1 did not error\n";
32    } catch (TypeError $e) {}
33}
34
35function valid(Test $test, string $prop1, string $prop2, $value) {
36    try {
37        $test->$prop2 = $value;
38        $test->$prop1 =& $test->$prop2;
39    } catch (TypeError $e) {
40        echo "Valid assignment $prop1 =& $prop2 threw {$e->getMessage()}\n";
41    }
42    try {
43        $test->$prop1 = $value;
44        $test->$prop2 =& $test->$prop1;
45    } catch (TypeError $e) {
46        echo "Valid assignment $prop2 =& $prop1 threw {$e->getMessage()}\n";
47    }
48}
49
50$test = new Test;
51invalid($test, 'int', 'float', 42.0);
52valid($test, 'int', 'nint', 42);
53invalid($test, 'int', 'nint', null);
54valid($test, 'nint', 'nstring', null);
55invalid($test, 'nint', 'nstring', '42');
56valid($test, 'A', 'A', new A);
57valid($test, 'A', 'B', new B);
58invalid($test, 'A', 'B', new A);
59valid($test, 'iterable', 'array', [1, 2, 3]);
60valid($test, 'A', 'object', new A);
61invalid($test, 'A', 'object', new Test);
62valid($test, 'iterable', 'Iterator', new ArrayIterator);
63invalid($test, 'Iterator', 'iterable', [1, 2, 3]);
64valid($test, 'object', 'iterable', new ArrayIterator);
65invalid($test, 'iterable', 'object', new stdClass);
66
67echo "Done\n";
68
69?>
70--EXPECT--
71Done
72