naming 2/2 - use naming_db_path provider
[hiphop-php.git] / hphp / hhbbc / type-system.h
blob222981f070c26a8173fa36ab8f33cad291a33667
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HHBBC_TYPE_SYSTEM_H_
17 #define incl_HHBBC_TYPE_SYSTEM_H_
19 #include <cstdint>
20 #include <vector>
21 #include <utility>
23 #include <folly/Optional.h>
25 #include "hphp/util/copy-ptr.h"
26 #include "hphp/util/low-ptr.h"
28 #include "hphp/runtime/base/repo-auth-type.h"
29 #include "hphp/runtime/base/repo-auth-type-array.h"
30 #include "hphp/runtime/base/array-provenance.h"
32 #include "hphp/hhbbc/array-like-map.h"
33 #include "hphp/hhbbc/index.h"
34 #include "hphp/hhbbc/misc.h"
36 namespace HPHP { namespace HHBBC {
38 struct Type;
40 //////////////////////////////////////////////////////////////////////
43 * Type system.
45 * Here's an unmaintainable ascii-art diagram:
47 * Top
48 * |
49 * +-----+
50 * | | InitCell := Cell - Uninit
51 * Cls | ?X := X + InitNull
52 * | |
53 * Cls<=c Cell
54 * | |
55 * Cls=c +-------------+--------+-------+-------+------------+
56 * | | | | | |
57 * Unc | | Obj Res Record
58 * | \ | | / \ |
59 * | \ | | Obj<=c Obj<=WaitHandle Record<=c
60 * Prim \ | | | | |
61 * / | InitUnc | | Obj=c WaitH<T> Record=c
62 * / | / | | | |
63 * / | / | | | |
64 * / | / | | | |
65 * / |/ | | | |
66 * Null InitPrim | | | |
67 * / | / | | | Arr Str
68 * / | / | | | / \ / \
69 * Uninit InitNull | | SArr ... / CStr
70 * | | | /
71 * | | ... /
72 * | | /
73 * | \ /
74 * | \ /
75 * | \ /
76 * | \ /
77 * | SStr
78 * | |
79 * | SStr=s
80 * |
81 * +----------+
82 * | |
83 * Bool Num
84 * / \ | \
85 * True False Int Dbl
86 * | |
87 * Int=n Dbl=n
89 * Some notes on some of the basic types:
91 * {Init,}Prim
93 * "Primitive" types---these can be represented in a TypedValue without a
94 * pointer to the heap.
96 * {Init,}Unc
98 * "Uncounted" types---values of these types don't require reference
99 * counting.
101 * WaitH<T>
103 * A WaitHandle that is known will either return a value of type T from
104 * its join() method (or Await), or else throw an exception.
106 * Array types:
108 * Arrays are divided along two dimensions: counted or uncounted, and empty
109 * or non-empty. Unions of either are allowed. The naming convention is
110 * {S,C,}Arr{N,E,}, where leaving out either bit means it's unknown along
111 * that dimension. All arrays are subtypes of the Arr type. The lattice
112 * here looks like this:
114 * Arr
116 * +----+--+--+---+
117 * | | | |
118 * | SArr CArr |
119 * | | | |
120 * +-------+---------------+
121 * | | | | |
122 * | ArrN +-----+ ArrE |
123 * | / \ | | / \ |
124 * SArrN CArrN CArrE SArrE
126 * NOTE: Having SArr be a sibling of CArr is problematic. There is
127 * an assumption that types in the index only ever get more refined,
128 * but eg we might "know" that a type is CArr early on (because eg
129 * we stored a value to it, thus modifying it), but later we might
130 * know the value both before and after the modification, and just
131 * replace each with a static array. In fact, this is almost
132 * guaranteed to happen when building arrays from constants (not
133 * literals), because on the first pass we won't know the constant
134 * values, and will produce a CArr, but eventually we could figure
135 * them out, and produce an SArr. This means that in practice, we
136 * can't use CArr anywhere, because it might be improved to SArr,
137 * which is not a subtype. Even if we only generated CArr after all
138 * modifications are done (eg during the insert-assertions phase) we
139 * could still run into problems where we annotate an array as CArr
140 * but jit time analysis/optimization was able to produce a static
141 * array - so it doesn't appear to be useful, except as a superclass
142 * of SArr.
144 * "Specialized" array types may be found as subtypes of any of the above
145 * types except SArrE and CArrE, or of optional versions of the above types
146 * (e.g. as a subtype of ?ArrN). The information about additional structure
147 * is dispayed in parenthesis, and probably best explained by some examples:
149 * SArrN(Bool,Int)
151 * Tuple-like static two-element array, with integer keys 0 and 1,
152 * containing a Bool and an Int with unknown values.
154 * Arr(Int,Dbl)
156 * An array of unknown countedness that is either empty, or a
157 * tuple-like array with two elements of types Int and Dbl.
159 * CArrN([Bool])
161 * Non-empty reference counted array with contiguous zero-based integer
162 * keys, unknown size, values all are subtypes of Bool.
164 * ArrN(x:Int,y:Int)
166 * Struct-like array with known fields "x" and "y" that have Int
167 * values, and no other fields. Struct-like arrays always have known
168 * string keys, and the type contains only those array values with
169 * exactly the given key set, in the order specified.
171 * Arr([SStr:InitCell])
173 * Possibly empty map-like array with unknown keys, but all
174 * non-reference counted strings, all values InitCell. In this case
175 * the array itself may or may not be static.
177 * Note that struct-like arrays will be subtypes of map-like arrays
178 * with string keys.
180 * ArrN([Int:InitPrim])
182 * Map-like array with only integer keys (not-necessarily contiguous)
183 * and values that are all subtypes of InitPrim. Note that the keys
184 * *may* be contiguous integers, so for example Arr([InitPrim]) <:
185 * Arr([Int => InitPrim]).
187 * Arr([ArrKey:InitCell])
189 * Map-like array with either integer or string keys, and InitCell
190 * values, or empty. Essentially this is the most generic array that
191 * can't contain php references.
194 //////////////////////////////////////////////////////////////////////
196 enum trep : uint64_t {
197 BBottom = 0,
199 BUninit = 1ULL << 0,
200 BInitNull = 1ULL << 1,
201 BFalse = 1ULL << 2,
202 BTrue = 1ULL << 3,
203 BInt = 1ULL << 4,
204 BDbl = 1ULL << 5,
205 BSStr = 1ULL << 6, // static string
206 BCStr = 1ULL << 7, // counted string
207 BFunc = 1ULL << 8,
209 BSPArrE = 1ULL << 9, // static empty "plain" array
210 BCPArrE = 1ULL << 10, // counted empty "plain" array
211 BSPArrN = 1ULL << 11, // static non-empty "plain" array
212 BCPArrN = 1ULL << 12ULL, // counted non-empty "plain array"
214 BSVArrE = 1ULL << 13, // static empty varray
215 BCVArrE = 1ULL << 14, // counted empty varray
216 BSVArrN = 1ULL << 15, // static non-empty varray
217 BCVArrN = 1ULL << 16, // counted non-empty varray
219 BSDArrE = 1ULL << 17, // static empty darray
220 BCDArrE = 1ULL << 18, // counted empty darray
221 BSDArrN = 1ULL << 19, // static non-empty darray
222 BCDArrN = 1ULL << 20, // counted non-empty darray
224 BClsMeth = 1ULL << 21,
226 BObj = 1ULL << 22,
227 BRes = 1ULL << 23,
228 BCls = 1ULL << 24,
230 BSVecE = 1ULL << 25, // static empty vec
231 BCVecE = 1ULL << 26, // counted empty vec
232 BSVecN = 1ULL << 27, // static non-empty vec
233 BCVecN = 1ULL << 28, // counted non-empty vec
234 BSDictE = 1ULL << 29, // static empty dict
235 BCDictE = 1ULL << 30, // counted empty dict
236 BSDictN = 1ULL << 31, // static non-empty dict
237 BCDictN = 1ULL << 32, // counted non-empty dict
238 BSKeysetE = 1ULL << 33, // static empty keyset
239 BCKeysetE = 1ULL << 34, // counted empty keyset
240 BSKeysetN = 1ULL << 35, // static non-empty keyset
241 BCKeysetN = 1ULL << 36, // counted non-empty keyset
243 BRecord = 1ULL << 37,
245 BSPArr = BSPArrE | BSPArrN,
246 BCPArr = BCPArrE | BCPArrN,
247 BPArrE = BSPArrE | BCPArrE,
248 BPArrN = BSPArrN | BCPArrN,
249 BPArr = BPArrE | BPArrN,
251 BSVArr = BSVArrE | BSVArrN,
252 BCVArr = BCVArrE | BCVArrN,
253 BVArrE = BSVArrE | BCVArrE,
254 BVArrN = BSVArrN | BCVArrN,
255 BVArr = BVArrE | BVArrN,
257 BSDArr = BSDArrE | BSDArrN,
258 BCDArr = BCDArrE | BCDArrN,
259 BDArrE = BSDArrE | BCDArrE,
260 BDArrN = BSDArrN | BCDArrN,
261 BDArr = BDArrE | BDArrN,
263 BSArrE = BSPArrE | BSVArrE | BSDArrE,
264 BCArrE = BCPArrE | BCVArrE | BCDArrE,
265 BSArrN = BSPArrN | BSVArrN | BSDArrN,
266 BCArrN = BCPArrN | BCVArrN | BCDArrN,
268 BNull = BUninit | BInitNull,
269 BBool = BFalse | BTrue,
270 BNum = BInt | BDbl,
271 BStr = BSStr | BCStr,
272 BSArr = BSArrE | BSArrN,
273 BCArr = BCArrE | BCArrN,
274 BArrE = BSArrE | BCArrE,
275 BArrN = BSArrN | BCArrN, // may have value / data
276 BArr = BArrE | BArrN,
277 BSVec = BSVecE | BSVecN,
278 BCVec = BCVecE | BCVecN,
279 BVecE = BSVecE | BCVecE,
280 BVecN = BSVecN | BCVecN,
281 BVec = BVecE | BVecN,
282 BSDict = BSDictE | BSDictN,
283 BCDict = BCDictE | BCDictN,
284 BDictE = BSDictE | BCDictE,
285 BDictN = BSDictN | BCDictN,
286 BDict = BDictE | BDictN,
287 BSKeyset = BSKeysetE | BSKeysetN,
288 BCKeyset = BCKeysetE | BCKeysetN,
289 BKeysetE = BSKeysetE | BCKeysetE,
290 BKeysetN = BSKeysetN | BCKeysetN,
291 BKeyset = BKeysetE | BKeysetN,
293 // Nullable types.
294 BOptTrue = BInitNull | BTrue,
295 BOptFalse = BInitNull | BFalse,
296 BOptBool = BInitNull | BBool,
297 BOptInt = BInitNull | BInt, // may have value
298 BOptDbl = BInitNull | BDbl, // may have value
299 BOptNum = BInitNull | BNum,
300 BOptSStr = BInitNull | BSStr, // may have value
301 BOptCStr = BInitNull | BCStr,
302 BOptStr = BInitNull | BStr,
303 BOptSArrE = BInitNull | BSArrE,
304 BOptCArrE = BInitNull | BCArrE,
305 BOptSArrN = BInitNull | BSArrN, // may have value / data
306 BOptCArrN = BInitNull | BCArrN, // may have value / data
307 BOptSArr = BInitNull | BSArr, // may have value / data
308 BOptCArr = BInitNull | BCArr, // may have value / data
309 BOptArrE = BInitNull | BArrE, // may have value / data
310 BOptArrN = BInitNull | BArrN, // may have value / data
311 BOptArr = BInitNull | BArr, // may have value / data
312 BOptObj = BInitNull | BObj, // may have data
313 BOptRes = BInitNull | BRes,
314 BOptFunc = BInitNull | BFunc,
315 BOptCls = BInitNull | BCls,
316 BOptClsMeth = BInitNull | BClsMeth,
317 BOptSVecE = BInitNull | BSVecE,
318 BOptCVecE = BInitNull | BCVecE,
319 BOptSVecN = BInitNull | BSVecN,
320 BOptCVecN = BInitNull | BCVecN,
321 BOptSVec = BInitNull | BSVec,
322 BOptCVec = BInitNull | BCVec,
323 BOptVecE = BInitNull | BVecE,
324 BOptVecN = BInitNull | BVecN,
325 BOptVec = BInitNull | BVec,
326 BOptSDictE = BInitNull | BSDictE,
327 BOptCDictE = BInitNull | BCDictE,
328 BOptSDictN = BInitNull | BSDictN,
329 BOptCDictN = BInitNull | BCDictN,
330 BOptSDict = BInitNull | BSDict,
331 BOptCDict = BInitNull | BCDict,
332 BOptDictE = BInitNull | BDictE,
333 BOptDictN = BInitNull | BDictN,
334 BOptDict = BInitNull | BDict,
335 BOptSKeysetE = BInitNull | BSKeysetE,
336 BOptCKeysetE = BInitNull | BCKeysetE,
337 BOptSKeysetN = BInitNull | BSKeysetN,
338 BOptCKeysetN = BInitNull | BCKeysetN,
339 BOptSKeyset = BInitNull | BSKeyset,
340 BOptCKeyset = BInitNull | BCKeyset,
341 BOptKeysetE = BInitNull | BKeysetE,
342 BOptKeysetN = BInitNull | BKeysetN,
343 BOptKeyset = BInitNull | BKeyset,
344 BOptRecord = BInitNull | BRecord,
346 BOptSPArrE = BInitNull | BSPArrE,
347 BOptCPArrE = BInitNull | BCPArrE,
348 BOptSPArrN = BInitNull | BSPArrN,
349 BOptCPArrN = BInitNull | BCPArrN,
350 BOptSPArr = BInitNull | BSPArr,
351 BOptCPArr = BInitNull | BCPArr,
352 BOptPArrE = BInitNull | BPArrE,
353 BOptPArrN = BInitNull | BPArrN,
354 BOptPArr = BInitNull | BPArr,
356 BOptSVArrE = BInitNull | BSVArrE,
357 BOptCVArrE = BInitNull | BCVArrE,
358 BOptSVArrN = BInitNull | BSVArrN,
359 BOptCVArrN = BInitNull | BCVArrN,
360 BOptSVArr = BInitNull | BSVArr,
361 BOptCVArr = BInitNull | BCVArr,
362 BOptVArrE = BInitNull | BVArrE,
363 BOptVArrN = BInitNull | BVArrN,
364 BOptVArr = BInitNull | BVArr,
366 BOptSDArrE = BInitNull | BSDArrE,
367 BOptCDArrE = BInitNull | BCDArrE,
368 BOptSDArrN = BInitNull | BSDArrN,
369 BOptCDArrN = BInitNull | BCDArrN,
370 BOptSDArr = BInitNull | BSDArr,
371 BOptCDArr = BInitNull | BCDArr,
372 BOptDArrE = BInitNull | BDArrE,
373 BOptDArrN = BInitNull | BDArrN,
374 BOptDArr = BInitNull | BDArr,
376 BUncArrKey = BInt | BSStr,
377 BArrKey = BUncArrKey | BCStr,
378 BOptUncArrKey = BInitNull | BUncArrKey,
379 BOptArrKey = BInitNull | BArrKey,
381 BFuncOrCls = BFunc | BCls,
382 BOptFuncOrCls = BInitNull | BFuncOrCls,
384 BStrLike = BFuncOrCls | BStr,
385 BUncStrLike = BFuncOrCls | BSStr,
387 BOptStrLike = BInitNull | BStrLike,
388 BOptUncStrLike = BInitNull | BUncStrLike,
390 BVArrLike = BClsMeth | BVArr,
391 BVArrLikeSA = BClsMeth | BSVArr,
393 BOptVArrLike = BInitNull | BVArrLike,
394 BOptVArrLikeSA = BInitNull | BVArrLikeSA,
396 BVecLike = BClsMeth | BVec,
397 BVecLikeSA = BClsMeth | BSVec,
399 BOptVecLike = BInitNull | BVecLike,
400 BOptVecLikeSA = BInitNull | BVecLikeSA,
402 BPArrLike = BClsMeth | BArr,
403 BPArrLikeSA = BClsMeth | BSArr,
405 BOptPArrLike = BInitNull | BPArrLike,
406 BOptPArrLikeSA = BInitNull | BPArrLikeSA,
408 BInitPrim = BInitNull | BBool | BNum | BFunc | BCls |
409 (use_lowptr ? BClsMeth : 0),
411 BPrim = BInitPrim | BUninit,
412 BInitUnc = BInitPrim | BSStr | BSArr | BSVec | BSDict | BSKeyset,
413 BUnc = BInitUnc | BUninit,
414 BInitCell = BInitNull | BBool | BInt | BDbl | BStr | BArr | BObj | BRes |
415 BVec | BDict | BKeyset | BFunc | BCls | BClsMeth | BRecord,
416 BCell = BUninit | BInitCell,
418 BTop = static_cast<uint64_t>(-1),
421 constexpr trep operator~(trep a) {
422 return static_cast<trep>(~static_cast<int64_t>(a));
425 constexpr trep operator&(trep a, trep b) {
426 return static_cast<trep>(static_cast<int64_t>(a) & b);
429 constexpr trep operator|(trep a, trep b) {
430 return static_cast<trep>(static_cast<int64_t>(a) | b);
433 constexpr const trep& operator&=(trep&a, trep b) {
434 a = a & b;
435 return a;
438 constexpr const trep& operator|=(trep&a, trep b) {
439 a = a | b;
440 return a;
443 // Useful constants. Don't put them in the enum itself, because they
444 // can't actually occur, but are convenient masks.
445 constexpr auto BArrLikeE = BArrE | BVecE | BDictE | BKeysetE;
446 constexpr auto BArrLikeN = BArrN | BVecN | BDictN | BKeysetN;
447 constexpr auto BArrLike = BArrLikeE | BArrLikeN;
448 constexpr auto BSArrLike = BSArr | BSVec | BSDict | BSKeyset;
449 constexpr auto BSArrLikeE = BSArrE | BSVecE | BSDictE | BSKeysetE;
451 #define DATATAGS \
452 DT(Str, SString, sval) \
453 DT(Int, int64_t, ival) \
454 DT(Dbl, double, dval) \
455 DT(ArrLikeVal, SArray, aval) \
456 DT(Obj, DObj, dobj) \
457 DT(Cls, DCls, dcls) \
458 DT(Record, DRecord, drec) \
459 DT(ArrLikePacked, copy_ptr<DArrLikePacked>, packed) \
460 DT(ArrLikePackedN, copy_ptr<DArrLikePackedN>, packedn) \
461 DT(ArrLikeMap, copy_ptr<DArrLikeMap>, map) \
462 DT(ArrLikeMapN, copy_ptr<DArrLikeMapN>, mapn)
464 // Tag for what kind of specialized data a Type object has.
465 enum class DataTag : uint8_t {
466 None,
467 #define DT(name,...) name,
468 DATATAGS
469 #undef DT
472 //////////////////////////////////////////////////////////////////////
475 * Information about a class type. The class is either exact or a
476 * subtype of the supplied class.
478 struct DCls {
479 enum Tag : uint16_t { Exact, Sub };
481 DCls(Tag type, res::Class cls)
482 : type(type)
483 , cls(cls)
486 Tag type;
487 bool isCtx = false;
488 res::Class cls;
492 * Information about a specific object type. The class is either
493 * exact or a subtype of the supplied class.
495 * If the class is WaitHandle, we can also carry a type that joining
496 * the wait handle will produce.
498 struct DObj {
499 enum Tag : uint16_t { Exact, Sub };
501 DObj(Tag type, res::Class cls)
502 : type(type)
503 , cls(cls)
506 Tag type;
507 bool isCtx = false;
508 res::Class cls;
509 copy_ptr<Type> whType;
513 * Information about a specific record type. The record type is either
514 * exact or a subtype of the supplied record.
516 struct DRecord {
517 enum Tag : uint16_t { Exact, Sub };
519 DRecord(Tag type, res::Record rec)
520 : type(type)
521 , rec(rec)
524 Tag type;
525 res::Record rec;
528 struct DArrLikePacked;
529 struct DArrLikePackedN;
530 struct DArrLikeMap;
531 struct DArrLikeMapN;
532 using MapElems = ArrayLikeMap<TypedValue>;
533 struct ArrKey;
534 struct IterTypes;
536 //////////////////////////////////////////////////////////////////////
539 * A provenance tag as tracked on a DArrLike{Packed,Map} (and, at runtime, on
540 * various kinds of arrays). The provenance tag on an array contains a file
541 * and line nubmer where that array is "from" (ideally, where the array was
542 * allocated---for static arrays the srcloc where the array is first
543 * referenced).
545 * This is tracked here in hhbbc because we both manipulate and create new
546 * static arrays.
548 * If the runtime option EvalArrayProvenance is not set, all ProvTags should be
549 * equal to ProvTag::Top.
551 * ProvTag::Top means the array type could have a provenance tag from anywhere,
552 * or no tag at all. (i.e. its provenance is unknown completely, a.k.a. NoTag).
554 * ProvTag::Some means the array type has one of several known tags and will
555 * be written out with a RepoUnion tag
557 * This information forms a sublattice like:
559 * top
560 * __________________________/ \_________________
561 * / \
562 * some tag |
563 * ____/|\___________ |
564 * / | \ |
565 * t_1 t_2 ... t_n (specific arrprov::Tag's) no tag
566 * \____ | ___________/___________________________________/
567 * \|/
568 * bottom (unrepresentable)
570 * If we would produce a Bottom provenance tag, (i.e. in intersectProvTag) we
571 * widen the result to ProvTag::Top.
573 struct ProvTag {
574 ProvTag() {}
575 /* implicit */ ProvTag(const arrprov::Tag& t)
576 : m_tag(t) {}
578 enum class KnownEmpty {};
579 /* implicit */ ProvTag(KnownEmpty)
580 : m_knownEmpty(true)
581 , m_tag() {}
583 static ProvTag Top;
584 static ProvTag NoTag;
585 static ProvTag SomeTag;
587 static ProvTag FromSArr(SArray a) {
588 assertx(RO::EvalArrayProvenance);
589 // It would be nice to assert a->isStatic() here, but, of course, SArrays
590 // (like the ones representing bytecode immediates) are not always static
591 // because we muck with them during various optimization passes.
592 return arrprov::getTag(a);
596 * Do we have a known provenance tag.
598 bool valid() const {
599 return !m_knownEmpty && m_tag.valid();
602 arrprov::Tag get() const { return m_tag; }
604 bool operator==(const ProvTag& o) const {
605 return m_knownEmpty == o.m_knownEmpty && m_tag == o.m_tag;
607 bool operator!=(const ProvTag& o) const {
608 return m_knownEmpty != o.m_knownEmpty || m_tag != o.m_tag;
611 private:
612 bool m_knownEmpty{false};
613 arrprov::Tag m_tag{};
616 constexpr auto kProvBits = BVec | BDict | BVArr | BDArr;
618 //////////////////////////////////////////////////////////////////////
620 enum class Emptiness {
621 Empty,
622 NonEmpty,
623 Maybe
626 enum class ThrowMode {
627 None,
628 MaybeMissingElement,
629 MaybeBadKey,
630 MissingElement,
631 BadOperation,
634 //////////////////////////////////////////////////////////////////////
636 struct Type {
637 Type() : m_bits(BTop) {
638 assert(checkInvariants());
640 explicit Type(trep t) : m_bits(t) {
641 assert(checkInvariants());
644 Type(const Type&) noexcept;
645 Type(Type&&) noexcept;
646 Type& operator=(const Type&) noexcept;
647 Type& operator=(Type&&) noexcept;
648 ~Type() noexcept;
651 * Exact equality or inequality of types, and hashing.
653 bool operator==(const Type& o) const;
654 bool operator!=(const Type& o) const { return !(*this == o); }
655 size_t hash() const;
657 const Type& operator |= (const Type& other);
658 const Type& operator |= (Type&& other);
659 const Type& operator &= (const Type& other);
660 const Type& operator &= (Type&& other);
663 * Returns true if this type is equivalently refined, more refined or strictly
664 * more refined than `o`. This is similar to the `==` and subtype operations
665 * defined below, except they take into account if a type is tagged as a
666 * context.
668 bool equivalentlyRefined(const Type& o) const;
669 bool moreRefined(const Type& o) const;
670 bool strictlyMoreRefined(const Type& o) const;
673 * Returns true if this type is definitely going to be a subtype or a strict
674 * subtype of `o' at runtime. If this function returns false, this may
675 * still be a subtype of `o' at runtime, it just may not be known.
677 bool subtypeOf(const Type& o) const;
678 bool strictSubtypeOf(const Type& o) const;
681 * Similar, but only check the trep (same as subtypeOf(Type{bits}),
682 * but cheaper).
684 bool subtypeOf(trep bits) const { return (m_bits & bits) == m_bits; }
685 bool subtypeOrNull(trep bits) const { return subtypeOf(bits | BNull); }
688 * Subtype of any of the list of types.
690 template<class... Types>
691 bool subtypeOfAny(const Type& t, Types... ts) const {
692 return subtypeOf(t) || subtypeOfAny(ts...);
694 bool subtypeOfAny() const { return false; }
696 template<bool contextSensitive>
697 bool equivImpl(const Type& o) const;
698 template<bool contextSensitive>
699 bool subtypeOfImpl(const Type& o) const;
702 * Returns whether there are any values of this type that are also
703 * values of the type `o'.
704 * When this function returns false, it is known that this type
705 * must not be in any subtype relationship with the argument Type 'o'.
706 * When true is returned the two types may still be unrelated but it is
707 * not possible to tell.
708 * Essentially this function can conservatively return true but must be
709 * precise when returning false.
711 bool couldBe(const Type& o) const;
712 bool couldBe(trep bits) const { return m_bits & bits; }
715 * Could-be any of the list of types.
717 template<class... Types>
718 bool couldBeAny(const Type& t, Types... ts) const {
719 return couldBe(t) || couldBeAny(ts...);
721 bool couldBeAny() const { return false; }
723 struct ArrayCat {
724 enum { None, Empty, Packed, Struct, Mixed } cat;
725 bool hasValue;
728 private:
729 friend folly::Optional<int64_t> arr_size(const Type& t);
730 friend ArrayCat categorize_array(const Type& t);
731 friend CompactVector<LSString> get_string_keys(const Type& t);
732 friend Type wait_handle(const Index&, Type);
733 friend bool is_specialized_wait_handle(const Type&);
734 friend bool is_specialized_array_like(const Type& t);
735 friend bool is_specialized_obj(const Type&);
736 friend bool is_specialized_record(const Type&);
737 friend bool is_specialized_cls(const Type&);
738 friend bool is_specialized_record(const Type&);
739 friend bool is_specialized_string(const Type&);
740 friend Type wait_handle_inner(const Type&);
741 friend Type sval(SString);
742 friend Type sval_nonstatic(SString);
743 friend Type ival(int64_t);
744 friend Type dval(double);
745 friend Type aval(SArray);
746 friend Type subObj(res::Class);
747 friend Type objExact(res::Class);
748 friend Type subCls(res::Class);
749 friend Type clsExact(res::Class);
750 friend Type exactRecord(res::Record);
751 friend Type subRecord(res::Record);
752 friend Type rname(SString);
753 friend Type packed_impl(trep, std::vector<Type>, ProvTag);
754 friend Type packedn_impl(trep, Type);
755 friend Type map_impl(trep, MapElems, Type, Type, ProvTag);
756 friend Type mapn_impl(trep bits, Type k, Type v, ProvTag);
757 friend Type mapn_impl_from_map(trep bits, Type k, Type v, ProvTag);
758 friend DObj dobj_of(const Type&);
759 friend DRecord drec_of(const Type&);
760 friend DCls dcls_of(Type);
761 friend SString sval_of(const Type&);
762 friend Type union_of(Type, Type);
763 friend Type intersection_of(Type, Type);
764 friend void widen_type_impl(Type&, uint32_t);
765 friend Type widen_type(Type);
766 friend Type widening_union(const Type&, const Type&);
767 friend Type promote_emptyish(Type, Type);
768 friend Emptiness emptiness(const Type&);
769 friend Type opt(Type);
770 friend Type unopt(Type);
771 friend Type unnullish(Type);
772 friend bool is_opt(const Type&);
773 friend bool is_nullish(const Type&);
774 friend Type project_data(Type t, trep bits);
775 friend bool must_be_counted(const Type&);
776 friend bool must_be_counted(const Type&, trep bits);
777 friend Type remove_counted(Type t);
778 template<typename R, bool>
779 friend R tvImpl(const Type&);
780 friend Type scalarize(Type t);
781 friend folly::Optional<size_t> array_size(const Type& t);
783 friend Type return_with_context(Type, Type);
784 friend Type setctx(Type, bool);
785 friend Type unctx(Type);
786 friend std::string show(const Type&);
787 friend ArrKey disect_array_key(const Type&);
788 friend ProvTag arr_like_update_prov_tag(const Type&, ProvTag);
789 friend std::pair<Type,bool> arr_val_elem(const Type& aval, const ArrKey& key);
790 friend std::pair<Type,bool> arr_map_elem(const Type& map, const ArrKey& key);
791 friend std::pair<Type,bool> arr_packed_elem(const Type& pack,
792 const ArrKey& key);
793 friend std::pair<Type,bool> arr_packedn_elem(const Type& pack,
794 const ArrKey& key);
795 friend std::pair<Type,ThrowMode> array_like_elem(const Type& arr,
796 const ArrKey& key,
797 const Type& defaultTy);
798 friend std::pair<Type,ThrowMode> array_like_set(Type arr,
799 const ArrKey& key,
800 const Type& val,
801 ProvTag src);
802 friend std::pair<Type,Type> array_like_newelem(Type arr, const Type& val,
803 ProvTag src);
804 friend bool arr_map_set(Type& map, const ArrKey& key,
805 const Type& val, ProvTag src);
806 friend bool arr_packed_set(Type& pack, const ArrKey& key,
807 const Type& val,
808 ProvTag src);
809 friend bool arr_packedn_set(Type& pack, const ArrKey& key,
810 const Type& val, bool maybeEmpty);
811 friend bool arr_mapn_set(Type& map, const ArrKey& key, const Type& val);
812 friend Type arr_map_newelem(Type& map, const Type& val, ProvTag src);
813 friend IterTypes iter_types(const Type&);
814 friend RepoAuthType make_repo_type_arr(ArrayTypeTable::Builder&,
815 const Type&);
817 friend struct ArrKey disect_vec_key(const Type&);
818 friend struct ArrKey disect_strict_key(const Type&);
820 friend Type spec_array_like_union(Type&, Type&, trep, trep);
821 friend Type aempty_varray(ProvTag);
822 friend Type aempty_darray(ProvTag);
823 friend Type vec_val(SArray);
824 friend Type vec_empty(ProvTag);
825 friend Type dict_val(SArray);
826 friend Type dict_empty(ProvTag);
827 friend Type some_aempty_darray(ProvTag);
828 friend Type some_vec_empty(ProvTag);
829 friend Type some_dict_empty(ProvTag);
830 friend Type keyset_val(SArray);
831 friend bool could_contain_objects(const Type&);
832 friend bool could_copy_on_write(const Type&);
833 friend Type loosen_staticness(Type);
834 friend Type loosen_dvarrayness(Type);
835 friend Type loosen_provenance(Type);
836 friend Type loosen_values(Type);
837 friend Type loosen_emptiness(Type);
838 friend Type loosen_likeness(Type);
839 friend Type add_nonemptiness(Type);
840 friend Type assert_emptiness(Type);
841 friend Type assert_nonemptiness(Type);
842 friend Type set_trep(Type&, trep);
843 friend Type remove_uninit(Type t);
844 friend Type to_cell(Type t);
845 friend bool inner_types_might_raise(const Type& t1, const Type& t2);
846 private:
847 union Data {
848 Data() {}
849 ~Data() {}
851 #define DT(tag_name,type,name) type name;
852 DATATAGS
853 #undef DT
856 template<class Ret, class T, class Function>
857 struct DDHelperFn;
859 private:
860 static Type unctxHelper(Type, bool&);
861 static Type unionArrLike(Type a, Type b);
862 template<class Ret, class T, class Function>
863 DDHelperFn<Ret,T,Function> ddbind(const Function& f, const T& t) const;
864 template<class Ret, class T, class Function>
865 Ret dd2nd(const Type&, DDHelperFn<Ret,T,Function>) const;
866 template<class Function> typename Function::result_type
867 dualDispatchDataFn(const Type&, Function) const;
868 bool hasData() const;
869 template<bool contextSensitive>
870 bool equivData(const Type&) const;
871 template<bool contextSensitive>
872 bool subtypeData(const Type&) const;
873 bool couldBeData(const Type&) const;
874 bool checkInvariants() const;
875 ProvTag getProvTag() const;
877 private:
878 trep m_bits;
879 DataTag m_dataTag = DataTag::None;
880 Data m_data;
883 //////////////////////////////////////////////////////////////////////
885 struct ArrKey {
886 folly::Optional<int64_t> i;
887 folly::Optional<SString> s;
888 Type type;
889 bool mayThrow = false;
891 folly::Optional<TypedValue> tv() const {
892 assert(!i || !s);
893 if (i) {
894 return make_tv<KindOfInt64>(*i);
896 if (s) {
897 return make_tv<KindOfPersistentString>(*s);
899 return folly::none;
903 struct DArrLikePacked {
904 explicit DArrLikePacked(std::vector<Type> elems, ProvTag tag)
905 : elems(std::move(elems))
906 , provenance(tag)
909 std::vector<Type> elems;
910 ProvTag provenance;
913 struct DArrLikePackedN {
914 explicit DArrLikePackedN(Type t) : type(std::move(t)) {}
915 Type type;
918 struct DArrLikeMap {
919 DArrLikeMap() {}
920 explicit DArrLikeMap(MapElems map, Type optKey, Type optVal, ProvTag tag)
921 : map(std::move(map))
922 , optKey(std::move(optKey))
923 , optVal(std::move(optVal))
924 , provenance(tag)
926 bool hasOptElements() const { return !optKey.subtypeOf(BBottom); }
927 // The array always starts with these known keys
928 MapElems map;
929 // Key/value types for optional elements after known keys. Bottom if
930 // none.
931 Type optKey;
932 Type optVal;
933 ProvTag provenance;
936 struct DArrLikeMapN {
937 explicit DArrLikeMapN(Type key, Type val)
938 : key(std::move(key))
939 , val(std::move(val))
941 Type key;
942 Type val;
945 //////////////////////////////////////////////////////////////////////
947 #define TYPES(X) \
948 X(Bottom) \
949 X(Uninit) \
950 X(InitNull) \
951 X(False) \
952 X(True) \
953 X(Int) \
954 X(Dbl) \
955 X(SStr) \
956 X(SArrE) \
957 X(SArrN) \
958 X(Obj) \
959 X(Res) \
960 X(Cls) \
961 X(Func) \
962 X(ClsMeth) \
963 X(Record) \
964 X(SVecE) \
965 X(SVecN) \
966 X(SDictE) \
967 X(SDictN) \
968 X(SKeysetE) \
969 X(SKeysetN) \
970 X(Null) \
971 X(Bool) \
972 X(Num) \
973 X(Str) \
974 X(SArr) \
975 X(ArrE) \
976 X(ArrN) \
977 X(Arr) \
978 X(SVec) \
979 X(VecE) \
980 X(VecN) \
981 X(Vec) \
982 X(SDict) \
983 X(DictE) \
984 X(DictN) \
985 X(Dict) \
986 X(SKeyset) \
987 X(KeysetE) \
988 X(KeysetN) \
989 X(Keyset) \
990 X(SPArrE) \
991 X(SPArrN) \
992 X(SPArr) \
993 X(PArrE) \
994 X(PArrN) \
995 X(PArr) \
996 X(SVArrE) \
997 X(SVArrN) \
998 X(SVArr) \
999 X(VArrE) \
1000 X(VArrN) \
1001 X(VArr) \
1002 X(SDArrE) \
1003 X(SDArrN) \
1004 X(SDArr) \
1005 X(DArrE) \
1006 X(DArrN) \
1007 X(DArr) \
1008 X(UncArrKey) \
1009 X(ArrKey) \
1010 X(FuncOrCls) \
1011 X(UncStrLike) \
1012 X(StrLike) \
1013 X(PArrLikeSA) \
1014 X(PArrLike) \
1015 X(VArrLikeSA) \
1016 X(VArrLike) \
1017 X(VecLikeSA) \
1018 X(VecLike) \
1019 X(InitPrim) \
1020 X(Prim) \
1021 X(InitUnc) \
1022 X(Unc) \
1023 X(OptTrue) \
1024 X(OptFalse) \
1025 X(OptBool) \
1026 X(OptInt) \
1027 X(OptDbl) \
1028 X(OptNum) \
1029 X(OptSStr) \
1030 X(OptStr) \
1031 X(OptSArrE) \
1032 X(OptSArrN) \
1033 X(OptSArr) \
1034 X(OptArrE) \
1035 X(OptArrN) \
1036 X(OptArr) \
1037 X(OptObj) \
1038 X(OptRes) \
1039 X(OptFunc) \
1040 X(OptCls) \
1041 X(OptClsMeth) \
1042 X(OptRecord) \
1043 X(OptSVecE) \
1044 X(OptSVecN) \
1045 X(OptSVec) \
1046 X(OptVecE) \
1047 X(OptVecN) \
1048 X(OptVec) \
1049 X(OptSDictE) \
1050 X(OptSDictN) \
1051 X(OptSDict) \
1052 X(OptDictE) \
1053 X(OptDictN) \
1054 X(OptDict) \
1055 X(OptSKeysetE) \
1056 X(OptSKeysetN) \
1057 X(OptSKeyset) \
1058 X(OptKeysetE) \
1059 X(OptKeysetN) \
1060 X(OptKeyset) \
1061 X(OptSPArrE) \
1062 X(OptSPArrN) \
1063 X(OptSPArr) \
1064 X(OptPArrE) \
1065 X(OptPArrN) \
1066 X(OptPArr) \
1067 X(OptSVArrE) \
1068 X(OptSVArrN) \
1069 X(OptSVArr) \
1070 X(OptVArrE) \
1071 X(OptVArrN) \
1072 X(OptVArr) \
1073 X(OptSDArrE) \
1074 X(OptSDArrN) \
1075 X(OptSDArr) \
1076 X(OptDArrE) \
1077 X(OptDArrN) \
1078 X(OptDArr) \
1079 X(OptUncArrKey) \
1080 X(OptArrKey) \
1081 X(OptFuncOrCls) \
1082 X(OptUncStrLike) \
1083 X(OptStrLike) \
1084 X(OptPArrLikeSA) \
1085 X(OptPArrLike) \
1086 X(OptVArrLikeSA) \
1087 X(OptVArrLike) \
1088 X(OptVecLikeSA) \
1089 X(OptVecLike) \
1090 X(InitCell) \
1091 X(Cell) \
1092 X(Top)
1094 #define X(y) extern const Type T##y;
1095 TYPES(X)
1096 #undef X
1098 // These are treps that have B* names, but which are not "predefined"
1099 // types. They are only allowed in combination with the corresponding
1100 // S types.
1101 #define NON_TYPES(X) \
1102 X(CStr) \
1103 X(CPArrE) \
1104 X(CPArrN) \
1105 X(CVArrE) \
1106 X(CVArrN) \
1107 X(CDArrE) \
1108 X(CDArrN) \
1109 X(CArrE) \
1110 X(CArrN) \
1111 X(CVecE) \
1112 X(CVecN) \
1113 X(CDictE) \
1114 X(CDictN) \
1115 X(CKeysetE) \
1116 X(CKeysetN) \
1117 X(CPArr) \
1118 X(CVArr) \
1119 X(CDArr) \
1120 X(CArr) \
1121 X(CVec) \
1122 X(CDict) \
1123 X(CKeyset) \
1124 X(OptCStr) \
1125 X(OptCPArrE) \
1126 X(OptCPArrN) \
1127 X(OptCPArr) \
1128 X(OptCVArrE) \
1129 X(OptCVArrN) \
1130 X(OptCVArr) \
1131 X(OptCDArrE) \
1132 X(OptCDArrN) \
1133 X(OptCDArr) \
1134 X(OptCArrE) \
1135 X(OptCArrN) \
1136 X(OptCArr) \
1137 X(OptCVecE) \
1138 X(OptCVecN) \
1139 X(OptCVec) \
1140 X(OptCDictE) \
1141 X(OptCDictN) \
1142 X(OptCDict) \
1143 X(OptCKeysetE) \
1144 X(OptCKeysetN) \
1145 X(OptCKeyset)
1147 //////////////////////////////////////////////////////////////////////
1150 * Return WaitH<T> for a type t.
1152 Type wait_handle(const Index&, Type t);
1155 * Return T from a WaitH<T>.
1157 * Pre: is_specialized_handle(t);
1159 Type wait_handle_inner(const Type& t);
1162 * Create Types that represent constant values.
1164 Type sval(SString);
1165 Type ival(int64_t);
1166 Type dval(double);
1167 Type aval(SArray);
1168 Type vec_val(SArray);
1169 Type dict_val(SArray);
1170 Type keyset_val(SArray);
1171 Type sval_nonstatic(SString);
1174 * Create static empty array or string types.
1176 Type sempty();
1177 Type aempty();
1178 Type aempty_varray(ProvTag = ProvTag::Top);
1179 Type aempty_darray(ProvTag = ProvTag::Top);
1180 Type vec_empty(ProvTag = ProvTag::Top);
1181 Type dict_empty(ProvTag = ProvTag::Top);
1182 Type keyset_empty();
1185 * Create an any-countedness empty array/vec/dict type.
1187 Type some_aempty();
1188 Type some_aempty_darray(ProvTag = ProvTag::Top);
1189 Type some_vec_empty(ProvTag = ProvTag::Top);
1190 Type some_dict_empty(ProvTag = ProvTag::Top);
1191 Type some_keyset_empty();
1194 * Create types for objects or classes with some known constraint on
1195 * which res::Class is associated with them.
1197 Type subObj(res::Class);
1198 Type objExact(res::Class);
1199 Type subCls(res::Class);
1200 Type clsExact(res::Class);
1203 * Create types for records with some known constraint on an associated
1204 * res::Record.
1206 Type exactRecord(res::Record);
1207 Type subRecord(res::Record);
1210 * Packed array types with known size.
1212 * Pre: !v.empty()
1214 Type arr_packed(std::vector<Type> v);
1215 Type arr_packed_varray(std::vector<Type> v, ProvTag = ProvTag::Top);
1216 Type sarr_packed(std::vector<Type> v);
1219 * Packed array types of unknown size.
1221 * Note that these types imply the arrays are non-empty.
1223 Type arr_packedn(Type);
1224 Type sarr_packedn(Type);
1227 * Struct-like arrays.
1229 * Pre: !m.empty()
1231 Type arr_map(MapElems m, Type optKey = TBottom, Type optVal = TBottom);
1232 Type arr_map_darray(MapElems m, ProvTag = ProvTag::Top);
1233 Type sarr_map(MapElems m, Type optKey = TBottom, Type optVal = TBottom);
1236 * Map-like arrays.
1238 Type arr_mapn(Type k, Type v);
1239 Type sarr_mapn(Type k, Type v);
1242 * vec types with known size.
1244 * Pre: !v.empty()
1246 Type vec(std::vector<Type> v, ProvTag);
1247 Type svec(std::vector<Type> v, ProvTag);
1250 * Vec type of unknown size.
1252 Type vec_n(Type);
1253 Type svec_n(Type);
1256 * Struct-like dicts.
1258 * Pre: !m.empty()
1260 Type dict_map(MapElems m, ProvTag,
1261 Type optKey = TBottom,
1262 Type optVal = TBottom);
1265 * Dict with key/value types.
1267 Type dict_n(Type, Type, ProvTag);
1268 Type sdict_n(Type, Type, ProvTag);
1271 * Keyset with key (same as value) type.
1273 Type keyset_n(Type);
1274 Type ckeyset_n(Type);
1277 * Keyset from MapElems
1279 inline Type keyset_map(MapElems m) {
1280 return map_impl(BKeysetN, std::move(m), TBottom, TBottom, ProvTag::Top);
1284 * Create the optional version of the Type t.
1286 * Pre: there must be an optional version of the type t.
1288 Type opt(Type t);
1291 * Return the non-optional version of the Type t.
1293 * Pre: is_opt(t)
1295 Type unopt(Type t);
1298 * Returns whether a given type is a subtype of one of the predefined
1299 * optional types. (Note that this does not include types like
1300 * TInitUnc---it's only the TOpt* types.)
1302 bool is_opt(const Type& t);
1305 * Return t with BNull removed from its trep.
1307 * Pre: is_nullish(t)
1309 Type unnullish(Type t);
1312 * Returns whether a given type couldBe TNull, and would still be
1313 * predefined if BNull was removed from its trep.
1315 bool is_nullish(const Type& t);
1318 * Improves the type `t` given the current context. This returns the
1319 * intersection of the type `t` with the `context` if the `context` is a valid
1320 * class or object, and `t` is tagged as being the context. If `context` is
1321 * a class we will first convert it to an object. This returns an optional type
1322 * if `t` was optional.
1324 Type return_with_context(Type t, Type context);
1327 * If `to` is false. This is an identity operation. If `to` is true, and
1328 * `t` is a specialized object or class, this will return `t` tagged as a
1329 * context.
1331 Type setctx(Type t, bool to = true);
1334 * This removes any context tags in the type `t`, even if nested inside other
1335 * types.
1337 Type unctx(Type t);
1340 * Discards any data associated with `t` that isn't valid for the given trep
1342 * At the moment this will do nothing beyond removing empty ArrLikeDatas from
1343 * types that used to only have ArrE bits set but now have a ArrN bit set
1345 Type project_data(Type t, trep bits);
1348 * Returns true if the type can only be counted. We don't allow the
1349 * the usage of the counted side of the type lattice, so this checks
1350 * if the type is a definitely counted type (IE, object or resource),
1351 * or if it has an array specialization which contains such a type
1352 * recursively (an array which contains a definitely counted type must
1353 * itself by counted).
1355 bool must_be_counted(const Type&);
1358 * Refinedness equivalence checks.
1360 bool equivalently_refined(const Type&, const Type&);
1362 template<
1363 typename Iterable,
1364 typename = std::enable_if<
1365 std::is_same<typename Iterable::value_type, Type>::value
1368 bool equivalently_refined(const Iterable& a, const Iterable& b) {
1369 if (a.size() != b.size()) return false;
1370 for (auto ita = a.begin(), itb = b.begin(); ita != a.end(); ++ita, ++itb) {
1371 if (!equivalently_refined(*ita, *itb)) return false;
1373 return true;
1377 * Returns true if type 't' represents a "specialized" object, that is an
1378 * object of a known class, or an optional object of a known class.
1380 bool is_specialized_obj(const Type&);
1383 * Returns true if type 't' represents a "specialized" class---i.e. a class
1384 * with a DCls structure.
1386 bool is_specialized_cls(const Type&);
1389 * Returns whether `t' is a WaitH<T> or ?WaitH<T> for some T.
1391 * Note that this function returns false for Obj<=WaitHandle with no
1392 * tracked inner type.
1394 bool is_specialized_wait_handle(const Type& t);
1397 * Returns whether `t' is a one of the array like types, or
1398 * an optional version of one of those types. That is, with
1399 * either a constant value or some (maybe partially) known shape.
1401 bool is_specialized_array(const Type& t);
1402 bool is_specialized_vec(const Type& t);
1403 bool is_specialized_dict(const Type& t);
1404 bool is_specialized_keyset(const Type& t);
1407 * Returns the best known instantiation of a class type. Or returns the
1408 * provided object.
1410 * Pre: t.subypeOfAny(TObj, TCls)
1412 Type toobj(const Type& t);
1415 * Returns the best known TCls subtype for an object type. Otherwise return
1416 * the passed in type.
1418 Type objcls(const Type& t);
1421 * If the type t has a known constant value, return it as a TypedValue.
1422 * Otherwise return folly::none.
1424 * The returned TypedValue can only contain non-reference-counted types.
1426 folly::Optional<TypedValue> tv(const Type& t);
1429 * If the type t has a known constant value, return it as a TypedValue.
1430 * Otherwise return folly::none.
1432 * The returned TypedValue may contain reference-counted types.
1434 * You are responsible for any required ref-counting.
1436 folly::Optional<TypedValue> tvNonStatic(const Type& t);
1439 * If the type t has a known constant value, return true.
1440 * Otherwise return false.
1442 bool is_scalar(const Type& t);
1445 * Return the canonical scalar type for t - equivalent to
1446 * from_cell(*tv(t)).
1448 * This can be used to ensure that the arguments in a CallContext are
1449 * canonicalized, so that immaterial changes to them (eg TArrN ->
1450 * TSArrN or DArrLikeMap -> DArrLikeVal) don't affect which entry gets
1451 * looked up.
1453 * pre: is_scalar(t).
1455 Type scalarize(Type t);
1458 * If t represents an array, and we know its size, return it.
1460 folly::Optional<size_t> array_size(const Type& t);
1463 * Get the type in our typesystem that corresponds to an hhbc
1464 * IsTypeOp.
1466 * Pre: op != IsTypeOp::Scalar
1468 Type type_of_istype(IsTypeOp op);
1471 * Get the hhbc IsTypeOp that corresponds to the type in our typesystem.
1472 * Returns folly::none if no matching IsTypeOp is found.
1474 folly::Optional<IsTypeOp> type_to_istypeop(const Type& t);
1477 * Get the type in our typesystem that corresponds to type given by the
1478 * potentially unresolved type structure.
1479 * Returns folly::none if the type structure is unresolved or
1480 * no matching Type is found.
1483 folly::Optional<Type> type_of_type_structure(const Index&, Context, SArray ts);
1486 * Return the DObj structure for a strict subtype of TObj or TOptObj.
1488 * Pre: is_specialized_obj(t)
1490 DObj dobj_of(const Type& t);
1493 * Return the DCls structure for a strict subtype of TCls.
1495 * Pre: is_specialized_cls(t)
1497 DCls dcls_of(Type t);
1500 * Return the SString for a strict subtype of TStr.
1502 * Pre: is_specialized_string(t)
1504 SString sval_of(const Type& t);
1507 * Create a Type from a TypedValue.
1509 * Pre: the cell must contain a non-reference-counted type.
1510 * Post: returned type is a subtype of TUnc
1512 Type from_cell(TypedValue tv);
1515 * Create a Type from a DataType. KindOfString and KindOfPersistentString
1516 * are both treated as TStr.
1518 * Pre: dt is one of the DataTypes that actually represent php values
1519 * (or KindOfUninit).
1521 Type from_DataType(DataType dt);
1524 * Create a Type from a builtin type specification string.
1526 * This is used for HNI class properties. We assume that these are
1527 * accurate. `s' may be nullptr.
1529 Type from_hni_constraint(SString s);
1532 * Make a type that represents values from the intersection of the
1533 * supplied types.
1535 Type intersection_of(Type a, Type b);
1538 * Make a type that represents values from either of the supplied
1539 * types.
1541 * Importantly, note that there are infinitely long chains of array
1542 * types that continue to become less specialized, so chains of
1543 * union_of operations are not guaranteed to reach a stable point in
1544 * finite steps.
1546 Type union_of(Type a, Type b);
1549 * Widening union.
1551 * This operation returns a type T, such that a is a subtype of T, b
1552 * is a subtype of T, and union_of(a, b) is a subtype of T. The
1553 * widening union also has the property that every possible chain of
1554 * successive applications of the function eventually reaches a stable
1555 * point.
1557 * This is currently implemented by unioning the types, then applying
1558 * widen_type() to the result.
1560 * For portions of our analysis that rely on growing types reaching
1561 * stable points for termination, this function must occasionally be
1562 * used instead of union_of to guarantee termination. See details in
1563 * analyze.cpp.
1565 Type widening_union(const Type& a, const Type& b);
1568 * Widen a type to one which has a finite chain under the union operator. This
1569 * generally involves restricting the type's nesting depth to a fixed limit and
1570 * preventing a specialized array type from growing larger unbounded.
1572 Type widen_type(Type t);
1575 * A sort of union operation that also attempts to remove "emptyish" types from
1576 * union_of(a, b). This is useful for promoting emptyish types (sempty(),
1577 * false, and null) to stdClass or to arrays, in member instructions.
1579 * This function currently doesn't give specific guarantees about exactly when
1580 * the emptyish types will not be part of the return type (informally it only
1581 * happens in the "easy" cases right now), so you should not use it in
1582 * situations where union_of(a, b) would not also be correct.
1584 Type promote_emptyish(Type a, Type b);
1588 * Returns what we know about the emptiness of the type.
1590 Emptiness emptiness(const Type&);
1593 * Returns whether a Type could hold an object that has a custom
1594 * boolean conversion function.
1596 bool could_have_magic_bool_conversion(const Type&);
1599 * Returns the smallest type that `a' is a subtype of, from the
1600 * following set: TInitCell, TUninit.
1602 * Pre: `a' is a subtype of TCell.
1604 Type stack_flav(Type a);
1607 * Discard any countedness information about the type. Force any type
1608 * (recursively) which contains only static or counted variants to contain
1609 * both. Doesn't change the type otherwise.
1611 Type loosen_staticness(Type);
1614 * Discard any specific knowledge about whether the type is a d/varray. Force
1615 * any type which might contain any sub-types of PArr, VArr, or DArr to contain
1616 * Arr, while keeping the same staticness and emptiness information.
1618 Type loosen_dvarrayness(Type);
1621 * Discard any specific provenance tag on this type and any sub-arrays
1623 Type loosen_provenance(Type);
1626 * Force any type which might contain any sub-types of Arr, Vec, Dict, and
1627 * Keyset to contain Arr, Vec, Dict, and Keyset. This is needed for some
1628 * operations whose effects on arrays cannot be predicted. Doesn't change the
1629 * type otherwise.
1631 Type loosen_arrays(Type);
1634 * Drop any data from the type (except for object class information) and force
1635 * TTrue or TFalse to TBool. Doesn't change the type otherwise.
1637 Type loosen_values(Type t);
1640 * Discard any emptiness information about the type. Force any type which
1641 * contains only empty or non-empty variants to contain both. Doesn't change the
1642 * type otherwise.
1644 Type loosen_emptiness(Type t);
1647 * Force all TFunc and TCls types to TUncStrLike, and all TClsMeth to either
1648 * TVArrLike or TVecLike.
1650 Type loosen_likeness(Type t);
1653 * Loosens staticness, emptiness, and values from the type. This forces a type
1654 * to its most basic form (except for object class information).
1656 Type loosen_all(Type t);
1659 * If t contains TUninit, returns the best type we can that contains
1660 * at least everything t contains, but doesn't contain TUninit. Note
1661 * that this function will return TBottom for TUninit.
1663 Type remove_uninit(Type t);
1666 * If t is not a TCell, returns TInitCell. Otherwise, if t contains
1667 * TUninit, return union_of(remove_uninit(t), TInitCell).
1669 Type to_cell(Type t);
1672 * Add non-empty variants of the type to the type if not already
1673 * present. Doesn't change the type otherwise.
1675 Type add_nonemptiness(Type t);
1678 * Force `t` to only contain static types, including any specialized
1679 * data recursively. If `t` is definitely counted, TBottom will be
1680 * returned.
1682 Type remove_counted(Type t);
1685 * Produced the most refined type possible, given that
1686 * t passed/failed an emptiness check.
1688 Type assert_emptiness(Type);
1689 Type assert_nonemptiness(Type);
1692 * (array|vec|dict|keyset)_elem
1694 * Returns the best known type of an array inner element given a type
1695 * for the key. The returned type is always a subtype of TInitCell.
1697 * The returned type will be TBottom if the operation will always throw.
1698 * ThrowMode indicates what kind of failures may occur.
1700 * Pre: first arg is a subtype of TArr, TVec, TDict, TKeyset respectively.
1702 std::pair<Type,ThrowMode> array_elem(const Type& arr, const Type& key,
1703 const Type& defaultTy = TInitNull);
1704 std::pair<Type, ThrowMode> vec_elem(const Type& vec, const Type& key,
1705 const Type& defaultTy = TBottom);
1706 std::pair<Type, ThrowMode> dict_elem(const Type& dict, const Type& key,
1707 const Type& defaultTy = TBottom);
1708 std::pair<Type, ThrowMode> keyset_elem(const Type& keyset, const Type& key,
1709 const Type& defaultTy = TBottom);
1712 * (array|vec|dict|keyset)_set
1714 * Perform an array-like set on types. Returns a type that represents the
1715 * effects of arr[key] = val.
1717 * The returned type will be TBottom if the operation will always throw.
1718 * ThrowMode indicates what kind of failures may occur.
1720 * Pre: first arg is a subtype of TArr, TVec, TDict, TKeyset respectively.
1722 std::pair<Type, ThrowMode> array_set(Type arr, const Type& key,
1723 const Type& val, ProvTag src);
1724 std::pair<Type, ThrowMode> vec_set(Type vec, const Type& key, const Type& val,
1725 ProvTag src);
1726 std::pair<Type, ThrowMode> dict_set(Type dict, const Type& key,
1727 const Type& val, ProvTag src);
1728 std::pair<Type, ThrowMode> keyset_set(Type keyset, const Type& key,
1729 const Type& val);
1732 * (array|vec|dict|keyset)_newelem
1734 * Perform a newelem operation on an array-like type. Returns an
1735 * array that contains a new pushed-back element with the supplied
1736 * value, in the sense of arr[] = val, and the best known type of the
1737 * key that was added.
1739 * Pre: first arg is a subtype of TArr, TVec, TDict, TKeyset respectively.
1741 std::pair<Type,Type> array_newelem(Type arr, const Type& val, ProvTag src);
1742 std::pair<Type,Type> vec_newelem(Type vec, const Type& val, ProvTag src);
1743 std::pair<Type,Type> dict_newelem(Type dict, const Type& val, ProvTag src);
1744 std::pair<Type,Type> keyset_newelem(Type keyset, const Type& val);
1747 * Return the best known information for iteration of the supplied type. This is
1748 * only intended for non-mutable iteration, so the returned types are at worst
1749 * InitCell.
1751 struct IterTypes {
1752 Type key;
1753 Type value;
1754 // The number of elements we're iterating over:
1755 enum struct Count {
1756 Empty, // No elements
1757 Single, // Exactly one element
1758 ZeroOrOne, // Less than 2 elements
1759 NonEmpty, // Unknown upper bound, but non-empty
1760 Any // Nothing known
1762 Count count;
1763 // Can a IterInit[K] op throw on this iterator?
1764 bool mayThrowOnInit;
1765 // Can a IterNext[K] op throw on this iterator? Can only happen for object
1766 // types.
1767 bool mayThrowOnNext;
1769 IterTypes iter_types(const Type&);
1772 * Create a RepoAuthType for a Type.
1774 * RepoAuthTypes may contain things like RepoAuthType::Array*'s or
1775 * SStrings for class names. The emit code needs to handle making
1776 * sure these things are merged into the appropriate unit or repo.
1778 * Pre: !t.couldBe(BCls)
1779 * !t.subtypeOf(BBottom)
1781 RepoAuthType make_repo_type(ArrayTypeTable::Builder&, const Type& t);
1784 * Returns true iff an IsType testing for testTy/testOp on valTy might raise.
1786 bool is_type_might_raise(const Type& testTy, const Type& valTy);
1787 bool is_type_might_raise(IsTypeOp testOp, const Type& valTy);
1790 * Returns true iff a compare of two types might raise a HAC notice
1792 bool compare_might_raise(const Type& t1, const Type& t2);
1795 * Given a type, adjust the type for the given type-constraint. If there's no
1796 * type-constraint, or if property type-hints aren't being enforced, then return
1797 * the type as is. This might return TBottom if the type is not compatible with
1798 * the type-hint.
1800 Type adjust_type_for_prop(const Index& index,
1801 const php::Class& propCls,
1802 const TypeConstraint* tc,
1803 const Type& ty);
1805 //////////////////////////////////////////////////////////////////////
1809 #endif