Make ExprTree's TInfer type param covariant
[hiphop-php.git] / hphp / hack / test / typecheck / expression_trees / splice_infer.php
blob9089ddc3b1b400e8fa88baf0e5c47e263eaa4e57
1 <?hh
3 <<file:__EnableUnstableFeatures('expression_trees')>>
5 function foo(): void {
6 $x = Code`4`;
7 $y = Code`5`;
9 // Inferred type needs to be compatible
10 $z = Code`${$y} + ${$x}`;
13 //// BEGIN DEFS
14 // Placeholder definition so we don't get naming/typing errors.
15 class Code {
16 const type TAst = mixed;
17 // Lifting literals.
18 public static function intLiteral(
19 int $_,
20 ): ExprTree<Code, Code::TAst, ExampleInt> {
21 throw new Exception();
23 public static function floatLiteral(
24 float $_,
25 ): ExprTree<Code, Code::TAst, ExampleFloat> {
26 throw new Exception();
28 public static function boolLiteral(bool $_):
29 ExprTree<Code, Code::TAst, ExampleBool>
31 throw new Exception();
33 public static function stringLiteral(string $_):
34 ExprTree<Code, Code::TAst, ExampleString>
36 throw new Exception();
38 public static function nullLiteral(): ExprTree<Code, Code::TAst, null> {
39 throw new Exception();
42 // Symbols
43 public static function symbol<T>(
44 string $_,
45 (function(ExampleContext): ExprTree<Code, Code::TAst, T>) $_,
46 ): ExprTree<Code, Code::TAst, T> {
47 throw new Exception();
50 // Expressions
51 public function localVar(?ExprPos $_, string $_): Code::TAst {
52 throw new Exception();
54 public function lambdaLiteral(
55 ?ExprPos $_,
56 vec<string> $_args,
57 vec<Code::TAst> $_body,
58 ): Code::TAst {
59 throw new Exception();
62 // Operators
63 public function methCall(
64 ?ExprPos $_,
65 Code::TAst $_,
66 string $_,
67 vec<Code::TAst> $_,
68 ): Code::TAst {
69 throw new Exception();
72 // Old style operators
73 public function call<T>(
74 ?ExprPos $_,
75 Code::TAst $_callee,
76 vec<Code::TAst> $_args,
77 ): Code::TAst {
78 throw new Exception();
81 public function assign(
82 ?ExprPos $_,
83 Code::TAst $_,
84 Code::TAst $_,
85 ): Code::TAst {
86 throw new Exception();
89 public function ternary(
90 ?ExprPos $_,
91 Code::TAst $_condition,
92 ?Code::TAst $_truthy,
93 Code::TAst $_falsy,
94 ): Code::TAst {
95 throw new Exception();
98 // Statements.
99 public function ifStatement(
100 ?ExprPos $_,
101 Code::TAst $_cond,
102 vec<Code::TAst> $_then_body,
103 vec<Code::TAst> $_else_body,
104 ): Code::TAst {
105 throw new Exception();
107 public function whileStatement(
108 ?ExprPos $_,
109 Code::TAst $_cond,
110 vec<Code::TAst> $_body,
111 ): Code::TAst {
112 throw new Exception();
114 public function returnStatement(
115 ?ExprPos $_,
116 ?Code::TAst $_,
117 ): Code::TAst {
118 throw new Exception();
120 public function forStatement(
121 ?ExprPos $_,
122 vec<Code::TAst> $_,
123 Code::TAst $_,
124 vec<Code::TAst> $_,
125 vec<Code::TAst> $_,
126 ): Code::TAst {
127 throw new Exception();
129 public function breakStatement(?ExprPos $_): Code::TAst {
130 throw new Exception();
132 public function continueStatement(?ExprPos $_,): Code::TAst {
133 throw new Exception();
136 // Splice
137 public function splice<T>(
138 ?ExprPos $_,
139 string $_key,
140 ExprTree<Code, Code::TAst, T> $_,
141 ): Code::TAst {
142 throw new Exception();
145 // TODO: Discard unsupported syntax nodes while lowering
146 public function unsupportedSyntax(string $msg): Code::TAst {
147 throw new Exception($msg);
151 final class ExprTree<TVisitor, TResult, +TInfer>{
152 public function __construct(
153 private ?ExprPos $pos,
154 private string $filepath,
155 private dict<string, mixed> $spliced_values,
156 private (function(TVisitor): TResult) $x,
157 private (function(): TInfer) $err,
158 ) {}
161 final class ExprPos {
162 public function __construct(
163 private int $begin_line,
164 private int $begin_col,
165 private int $end_line,
166 private int $end_col,
167 ) {}
170 final class ExampleInt {
171 public function __plus(ExampleInt $_): ExampleInt {
172 throw new Exception();
174 public function __minus(ExampleInt $_): ExampleInt {
175 throw new Exception();
177 public function __star(ExampleInt $_): ExampleInt {
178 throw new Exception();
180 public function __slash(ExampleInt $_): ExampleInt {
181 throw new Exception();
184 public function __lessThan(ExampleInt $_): ExampleBool {
185 throw new Exception();
188 public function __lessThanEqual(ExampleInt $_): ExampleBool {
189 throw new Exception();
192 public function __greaterThan(ExampleInt $_): ExampleBool {
193 throw new Exception();
196 public function __greaterThanEqual(ExampleInt $_): ExampleBool {
197 throw new Exception();
200 public function __tripleEquals(ExampleInt $_): ExampleBool {
201 throw new Exception();
204 public function __notTripleEquals(ExampleInt $_): ExampleBool {
205 throw new Exception();
209 final class ExampleBool {
210 public function __ampamp(ExampleBool $_): ExampleBool {
211 throw new Exception();
214 public function __barbar(ExampleBool $_): ExampleBool {
215 throw new Exception();
218 public function __bool(): bool {
219 throw new Exception();
222 public function __exclamationMark(): ExampleBool {
223 throw new Exception();
227 final class ExampleString {}
229 final class ExampleContext {}
231 final class ExampleFloat {}
233 //// END DEFS