Enable silent index builds
[hiphop-php.git] / hphp / hhbbc / type-system.h
blob8e21fbffc5e749f045c1540750fb8bb8a6796246
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 * +-----+ InitGen := Gen - Uninit
50 * | | InitCell := Cell - Uninit
51 * Cls Gen---+ ?X := X + InitNull
52 * | | |
53 * Cls<=c Cell Ref
54 * | |
55 * Cls=c +-------------+--------+-------+-------+-----+
56 * | | | | | |
57 * Unc | | Obj Res Record
58 * | \ | | / \
59 * | \ | | Obj<=c Obj<=WaitHandle
60 * Prim \ | | | |
61 * / | InitUnc | | Obj=c WaitH<T>
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, // ClassMethod
226 BObj = 1ULL << 22,
227 BRes = 1ULL << 23,
228 BCls = 1ULL << 24,
229 BRef = 1ULL << 25,
231 BSVecE = 1ULL << 26, // static empty vec
232 BCVecE = 1ULL << 27, // counted empty vec
233 BSVecN = 1ULL << 28, // static non-empty vec
234 BCVecN = 1ULL << 29, // counted non-empty vec
235 BSDictE = 1ULL << 30, // static empty dict
236 BCDictE = 1ULL << 31, // counted empty dict
237 BSDictN = 1ULL << 32, // static non-empty dict
238 BCDictN = 1ULL << 33, // counted non-empty dict
239 BSKeysetE = 1ULL << 34, // static empty keyset
240 BCKeysetE = 1ULL << 35, // counted empty keyset
241 BSKeysetN = 1ULL << 36, // static non-empty keyset
242 BCKeysetN = 1ULL << 37, // counted non-empty keyset
244 BRecord = 1ULL << 38,
246 BSPArr = BSPArrE | BSPArrN,
247 BCPArr = BCPArrE | BCPArrN,
248 BPArrE = BSPArrE | BCPArrE,
249 BPArrN = BSPArrN | BCPArrN,
250 BPArr = BPArrE | BPArrN,
252 BSVArr = BSVArrE | BSVArrN,
253 BCVArr = BCVArrE | BCVArrN,
254 BVArrE = BSVArrE | BCVArrE,
255 BVArrN = BSVArrN | BCVArrN,
256 BVArr = BVArrE | BVArrN,
258 BSDArr = BSDArrE | BSDArrN,
259 BCDArr = BCDArrE | BCDArrN,
260 BDArrE = BSDArrE | BCDArrE,
261 BDArrN = BSDArrN | BCDArrN,
262 BDArr = BDArrE | BDArrN,
264 BSArrE = BSPArrE | BSVArrE | BSDArrE,
265 BCArrE = BCPArrE | BCVArrE | BCDArrE,
266 BSArrN = BSPArrN | BSVArrN | BSDArrN,
267 BCArrN = BCPArrN | BCVArrN | BCDArrN,
269 BNull = BUninit | BInitNull,
270 BBool = BFalse | BTrue,
271 BNum = BInt | BDbl,
272 BStr = BSStr | BCStr,
273 BSArr = BSArrE | BSArrN,
274 BCArr = BCArrE | BCArrN,
275 BArrE = BSArrE | BCArrE,
276 BArrN = BSArrN | BCArrN, // may have value / data
277 BArr = BArrE | BArrN,
278 BSVec = BSVecE | BSVecN,
279 BCVec = BCVecE | BCVecN,
280 BVecE = BSVecE | BCVecE,
281 BVecN = BSVecN | BCVecN,
282 BVec = BVecE | BVecN,
283 BSDict = BSDictE | BSDictN,
284 BCDict = BCDictE | BCDictN,
285 BDictE = BSDictE | BCDictE,
286 BDictN = BSDictN | BCDictN,
287 BDict = BDictE | BDictN,
288 BSKeyset = BSKeysetE | BSKeysetN,
289 BCKeyset = BCKeysetE | BCKeysetN,
290 BKeysetE = BSKeysetE | BCKeysetE,
291 BKeysetN = BSKeysetN | BCKeysetN,
292 BKeyset = BKeysetE | BKeysetN,
294 // Nullable types.
295 BOptTrue = BInitNull | BTrue,
296 BOptFalse = BInitNull | BFalse,
297 BOptBool = BInitNull | BBool,
298 BOptInt = BInitNull | BInt, // may have value
299 BOptDbl = BInitNull | BDbl, // may have value
300 BOptNum = BInitNull | BNum,
301 BOptSStr = BInitNull | BSStr, // may have value
302 BOptCStr = BInitNull | BCStr,
303 BOptStr = BInitNull | BStr,
304 BOptSArrE = BInitNull | BSArrE,
305 BOptCArrE = BInitNull | BCArrE,
306 BOptSArrN = BInitNull | BSArrN, // may have value / data
307 BOptCArrN = BInitNull | BCArrN, // may have value / data
308 BOptSArr = BInitNull | BSArr, // may have value / data
309 BOptCArr = BInitNull | BCArr, // may have value / data
310 BOptArrE = BInitNull | BArrE, // may have value / data
311 BOptArrN = BInitNull | BArrN, // may have value / data
312 BOptArr = BInitNull | BArr, // may have value / data
313 BOptObj = BInitNull | BObj, // may have data
314 BOptRes = BInitNull | BRes,
315 BOptFunc = BInitNull | BFunc,
316 BOptCls = BInitNull | BCls,
317 BOptClsMeth = BInitNull | BClsMeth,
318 BOptSVecE = BInitNull | BSVecE,
319 BOptCVecE = BInitNull | BCVecE,
320 BOptSVecN = BInitNull | BSVecN,
321 BOptCVecN = BInitNull | BCVecN,
322 BOptSVec = BInitNull | BSVec,
323 BOptCVec = BInitNull | BCVec,
324 BOptVecE = BInitNull | BVecE,
325 BOptVecN = BInitNull | BVecN,
326 BOptVec = BInitNull | BVec,
327 BOptSDictE = BInitNull | BSDictE,
328 BOptCDictE = BInitNull | BCDictE,
329 BOptSDictN = BInitNull | BSDictN,
330 BOptCDictN = BInitNull | BCDictN,
331 BOptSDict = BInitNull | BSDict,
332 BOptCDict = BInitNull | BCDict,
333 BOptDictE = BInitNull | BDictE,
334 BOptDictN = BInitNull | BDictN,
335 BOptDict = BInitNull | BDict,
336 BOptSKeysetE = BInitNull | BSKeysetE,
337 BOptCKeysetE = BInitNull | BCKeysetE,
338 BOptSKeysetN = BInitNull | BSKeysetN,
339 BOptCKeysetN = BInitNull | BCKeysetN,
340 BOptSKeyset = BInitNull | BSKeyset,
341 BOptCKeyset = BInitNull | BCKeyset,
342 BOptKeysetE = BInitNull | BKeysetE,
343 BOptKeysetN = BInitNull | BKeysetN,
344 BOptKeyset = BInitNull | BKeyset,
345 BOptRecord = BInitNull | BRecord,
347 BOptSPArrE = BInitNull | BSPArrE,
348 BOptCPArrE = BInitNull | BCPArrE,
349 BOptSPArrN = BInitNull | BSPArrN,
350 BOptCPArrN = BInitNull | BCPArrN,
351 BOptSPArr = BInitNull | BSPArr,
352 BOptCPArr = BInitNull | BCPArr,
353 BOptPArrE = BInitNull | BPArrE,
354 BOptPArrN = BInitNull | BPArrN,
355 BOptPArr = BInitNull | BPArr,
357 BOptSVArrE = BInitNull | BSVArrE,
358 BOptCVArrE = BInitNull | BCVArrE,
359 BOptSVArrN = BInitNull | BSVArrN,
360 BOptCVArrN = BInitNull | BCVArrN,
361 BOptSVArr = BInitNull | BSVArr,
362 BOptCVArr = BInitNull | BCVArr,
363 BOptVArrE = BInitNull | BVArrE,
364 BOptVArrN = BInitNull | BVArrN,
365 BOptVArr = BInitNull | BVArr,
367 BOptSDArrE = BInitNull | BSDArrE,
368 BOptCDArrE = BInitNull | BCDArrE,
369 BOptSDArrN = BInitNull | BSDArrN,
370 BOptCDArrN = BInitNull | BCDArrN,
371 BOptSDArr = BInitNull | BSDArr,
372 BOptCDArr = BInitNull | BCDArr,
373 BOptDArrE = BInitNull | BDArrE,
374 BOptDArrN = BInitNull | BDArrN,
375 BOptDArr = BInitNull | BDArr,
377 BUncArrKey = BInt | BSStr,
378 BArrKey = BUncArrKey | BCStr,
379 BOptUncArrKey = BInitNull | BUncArrKey,
380 BOptArrKey = BInitNull | BArrKey,
382 BStrLike = BFunc | BStr | BCls,
383 BUncStrLike = BFunc | BSStr | BCls,
385 BOptStrLike = BInitNull | BStrLike,
386 BOptUncStrLike = BInitNull | BUncStrLike,
388 BInitPrim = BInitNull | BBool | BNum | BFunc | BCls |
389 (use_lowptr ? BClsMeth : 0),
391 BPrim = BInitPrim | BUninit,
392 BInitUnc = BInitPrim | BSStr | BSArr | BSVec | BSDict | BSKeyset,
393 BUnc = BInitUnc | BUninit,
394 BInitCell = BInitNull | BBool | BInt | BDbl | BStr | BArr | BObj | BRes |
395 BVec | BDict | BKeyset | BFunc | BCls | BClsMeth | BRecord,
396 BCell = BUninit | BInitCell,
397 BInitGen = BInitCell | BRef,
398 BGen = BUninit | BInitGen,
400 BTop = static_cast<uint64_t>(-1),
403 constexpr trep operator~(trep a) {
404 return static_cast<trep>(~static_cast<int64_t>(a));
407 constexpr trep operator&(trep a, trep b) {
408 return static_cast<trep>(static_cast<int64_t>(a) & b);
411 constexpr trep operator|(trep a, trep b) {
412 return static_cast<trep>(static_cast<int64_t>(a) | b);
415 constexpr const trep& operator&=(trep&a, trep b) {
416 a = a & b;
417 return a;
420 constexpr const trep& operator|=(trep&a, trep b) {
421 a = a | b;
422 return a;
425 // Useful constants. Don't put them in the enum itself, because they
426 // can't actually occur, but are convenient masks.
427 constexpr auto BArrLikeE = BArrE | BVecE | BDictE | BKeysetE;
428 constexpr auto BArrLikeN = BArrN | BVecN | BDictN | BKeysetN;
429 constexpr auto BArrLike = BArrLikeE | BArrLikeN;
430 constexpr auto BSArrLike = BSArr | BSVec | BSDict | BSKeyset;
432 #define DATATAGS \
433 DT(Str, SString, sval) \
434 DT(Int, int64_t, ival) \
435 DT(Dbl, double, dval) \
436 DT(ArrLikeVal, SArray, aval) \
437 DT(Obj, DObj, dobj) \
438 DT(Cls, DCls, dcls) \
439 DT(RefInner, copy_ptr<Type>, inner) \
440 DT(ArrLikePacked, copy_ptr<DArrLikePacked>, packed) \
441 DT(ArrLikePackedN, copy_ptr<DArrLikePackedN>, packedn) \
442 DT(ArrLikeMap, copy_ptr<DArrLikeMap>, map) \
443 DT(ArrLikeMapN, copy_ptr<DArrLikeMapN>, mapn)
445 // Tag for what kind of specialized data a Type object has.
446 enum class DataTag : uint8_t {
447 None,
448 #define DT(name,...) name,
449 DATATAGS
450 #undef DT
453 //////////////////////////////////////////////////////////////////////
456 * Information about a class type. The class is either exact or a
457 * subtype of the supplied class.
459 struct DCls {
460 enum Tag : uint16_t { Exact, Sub };
462 DCls(Tag type, res::Class cls)
463 : type(type)
464 , cls(cls)
467 Tag type;
468 bool isCtx = false;
469 res::Class cls;
473 * Information about a specific object type. The class is either
474 * exact or a subtype of the supplied class.
476 * If the class is WaitHandle, we can also carry a type that joining
477 * the wait handle will produce.
479 struct DObj {
480 enum Tag : uint16_t { Exact, Sub };
482 DObj(Tag type, res::Class cls)
483 : type(type)
484 , cls(cls)
487 Tag type;
488 bool isCtx = false;
489 res::Class cls;
490 copy_ptr<Type> whType;
493 struct DArrLikePacked;
494 struct DArrLikePackedN;
495 struct DArrLikeMap;
496 struct DArrLikeMapN;
497 using MapElems = ArrayLikeMap<Cell>;
498 struct ArrKey;
499 struct IterTypes;
502 * A provenance tag as tracked on a DArrLike{Packed,Map}. (and, at runtime, on
503 * dicts and vecs.) The provenance tag on an array contains a file and line
504 * nubmer where that array is 'from' (ideally, where the array was
505 * allocated--for static arrays the srcloc where the array is first referenced)
507 * This is tracked here in hhbbc both because we manipulate and create new
508 * static arrays.
510 * If the runtime option EvalArrayProvenance is not set, all ProvTags should be
511 * equal to the top of the lattice (folly::none)
513 * The absence of a value here (folly::none) means the array type could have a
514 * provenance tag from anywhere, or no tag at all. (i.e. its provenance is
515 * unknown completely).
517 * This information forms a sublattice like:
519 * top (folly::none)
520 * ____/|\___________
521 * / | \
522 * t_1 t_2 ... t_n (specific arrprov::Tag's)
523 * \____ | ___________/
524 * \|/
525 * bottom (unrepresentable)
527 * If we would produce a 'bottom' provenance tag, (i.e. in intersectProvTag)
528 * we widen the result to 'top'
530 using ProvTag = folly::Optional<arrprov::Tag>;
532 enum class Emptiness {
533 Empty,
534 NonEmpty,
535 Maybe
538 enum class ThrowMode {
539 None,
540 MaybeMissingElement,
541 MaybeBadKey,
542 MissingElement,
543 BadOperation,
546 //////////////////////////////////////////////////////////////////////
548 struct Type {
549 Type() : m_bits(BTop) {
550 assert(checkInvariants());
552 explicit Type(trep t) : m_bits(t) {
553 assert(checkInvariants());
556 Type(const Type&) noexcept;
557 Type(Type&&) noexcept;
558 Type& operator=(const Type&) noexcept;
559 Type& operator=(Type&&) noexcept;
560 ~Type() noexcept;
563 * Exact equality or inequality of types, and hashing.
565 bool operator==(const Type& o) const;
566 bool operator!=(const Type& o) const { return !(*this == o); }
567 size_t hash() const;
569 const Type& operator |= (const Type& other);
570 const Type& operator |= (Type&& other);
571 const Type& operator &= (const Type& other);
572 const Type& operator &= (Type&& other);
575 * Returns true if this type is equivalently refined, more refined or strictly
576 * more refined than `o`. This is similar to the `==` and subtype operations
577 * defined below, except they take into account if a type is tagged as a
578 * context.
580 bool equivalentlyRefined(const Type& o) const;
581 bool moreRefined(const Type& o) const;
582 bool strictlyMoreRefined(const Type& o) const;
585 * Returns true if this type is definitely going to be a subtype or a strict
586 * subtype of `o' at runtime. If this function returns false, this may
587 * still be a subtype of `o' at runtime, it just may not be known.
589 bool subtypeOf(const Type& o) const;
590 bool strictSubtypeOf(const Type& o) const;
593 * Similar, but only check the trep (same as subtypeOf(Type{bits}),
594 * but cheaper).
596 bool subtypeOf(trep bits) const { return (m_bits & bits) == m_bits; }
597 bool subtypeOrNull(trep bits) const { return subtypeOf(bits | BNull); }
600 * Subtype of any of the list of types.
602 template<class... Types>
603 bool subtypeOfAny(const Type& t, Types... ts) const {
604 return subtypeOf(t) || subtypeOfAny(ts...);
606 bool subtypeOfAny() const { return false; }
608 template<bool contextSensitive>
609 bool equivImpl(const Type& o) const;
610 template<bool contextSensitive>
611 bool subtypeOfImpl(const Type& o) const;
614 * Returns whether there are any values of this type that are also
615 * values of the type `o'.
616 * When this function returns false, it is known that this type
617 * must not be in any subtype relationship with the argument Type 'o'.
618 * When true is returned the two types may still be unrelated but it is
619 * not possible to tell.
620 * Essentially this function can conservatively return true but must be
621 * precise when returning false.
623 bool couldBe(const Type& o) const;
624 bool couldBe(trep bits) const { return m_bits & bits; }
627 * Could-be any of the list of types.
629 template<class... Types>
630 bool couldBeAny(const Type& t, Types... ts) const {
631 return couldBe(t) || couldBeAny(ts...);
633 bool couldBeAny() const { return false; }
635 struct ArrayCat {
636 enum { None, Empty, Packed, Struct, Mixed } cat;
637 bool hasValue;
640 private:
641 friend folly::Optional<int64_t> arr_size(const Type& t);
642 friend ArrayCat categorize_array(const Type& t);
643 friend CompactVector<LSString> get_string_keys(const Type& t);
644 friend Type wait_handle(const Index&, Type);
645 friend bool is_specialized_wait_handle(const Type&);
646 friend bool is_specialized_array_like(const Type& t);
647 friend bool is_specialized_obj(const Type&);
648 friend bool is_specialized_cls(const Type&);
649 friend bool is_ref_with_inner(const Type&);
650 friend bool is_specialized_string(const Type&);
651 friend Type wait_handle_inner(const Type&);
652 friend Type sval(SString);
653 friend Type sval_nonstatic(SString);
654 friend Type ival(int64_t);
655 friend Type dval(double);
656 friend Type aval(SArray);
657 friend Type subObj(res::Class);
658 friend Type objExact(res::Class);
659 friend Type subCls(res::Class);
660 friend Type clsExact(res::Class);
661 friend Type ref_to(Type);
662 friend Type rname(SString);
663 friend Type packed_impl(trep, std::vector<Type>, ProvTag);
664 friend Type packedn_impl(trep, Type);
665 friend Type map_impl(trep, MapElems, ProvTag);
666 friend Type mapn_impl(trep bits, Type k, Type v, ProvTag);
667 friend Type mapn_impl_from_map(trep bits, Type k, Type v, ProvTag);
668 friend DObj dobj_of(const Type&);
669 friend DCls dcls_of(Type);
670 friend SString sval_of(const Type&);
671 friend Type union_of(Type, Type);
672 friend Type intersection_of(Type, Type);
673 friend void widen_type_impl(Type&, uint32_t);
674 friend Type widen_type(Type);
675 friend Type widening_union(const Type&, const Type&);
676 friend Type promote_emptyish(Type, Type);
677 friend Emptiness emptiness(const Type&);
678 friend Type opt(Type);
679 friend Type unopt(Type);
680 friend Type unnullish(Type);
681 friend bool is_opt(const Type&);
682 friend bool is_nullish(const Type&);
683 template<typename R, bool>
684 friend R tvImpl(const Type&);
685 friend Type scalarize(Type t);
686 friend folly::Optional<size_t> array_size(const Type& t);
687 friend folly::Optional<std::pair<Type,Type>>
688 array_get_by_index(const Type& t, ssize_t index);
690 friend Type return_with_context(Type, Type);
691 friend Type setctx(Type, bool);
692 friend Type unctx(Type);
693 friend std::string show(const Type&);
694 friend ArrKey disect_array_key(const Type&);
695 friend std::pair<Type,bool> arr_val_elem(const Type& aval, const ArrKey& key);
696 friend std::pair<Type,bool> arr_map_elem(const Type& map, const ArrKey& key);
697 friend std::pair<Type,bool> arr_packed_elem(const Type& pack,
698 const ArrKey& key);
699 friend std::pair<Type,bool> arr_packedn_elem(const Type& pack,
700 const ArrKey& key);
701 friend std::pair<Type,ThrowMode> array_like_elem(const Type& arr,
702 const ArrKey& key,
703 const Type& defaultTy);
704 friend std::pair<Type,ThrowMode> array_like_set(Type arr,
705 const ArrKey& key,
706 const Type& val,
707 ProvTag src);
708 friend std::pair<Type,Type> array_like_newelem(Type arr, const Type& val,
709 ProvTag src);
710 friend bool arr_map_set(Type& map, const ArrKey& key,
711 const Type& val, ProvTag src);
712 friend bool arr_packed_set(Type& pack, const ArrKey& key,
713 const Type& val,
714 ProvTag src);
715 friend bool arr_packedn_set(Type& pack, const ArrKey& key,
716 const Type& val, bool maybeEmpty);
717 friend bool arr_mapn_set(Type& map, const ArrKey& key, const Type& val);
718 friend Type arr_map_newelem(Type& map, const Type& val, ProvTag src);
719 friend IterTypes iter_types(const Type&);
720 friend RepoAuthType make_repo_type_arr(ArrayTypeTable::Builder&,
721 const Type&);
723 friend struct ArrKey disect_vec_key(const Type&);
724 friend struct ArrKey disect_strict_key(const Type&);
726 friend Type spec_array_like_union(Type&, Type&, trep, trep);
727 friend Type vec_val(SArray);
728 friend Type vec_empty();
729 friend Type some_vec_empty();
730 friend Type dict_val(SArray);
731 friend Type dict_empty();
732 friend Type some_dict_empty();
733 friend Type keyset_val(SArray);
734 friend bool could_contain_objects(const Type&);
735 friend bool could_copy_on_write(const Type&);
736 friend Type loosen_staticness(Type);
737 friend Type loosen_dvarrayness(Type);
738 friend Type loosen_provenance(Type);
739 friend Type loosen_values(Type);
740 friend Type loosen_emptiness(Type);
741 friend Type add_nonemptiness(Type);
742 friend Type assert_emptiness(Type);
743 friend Type assert_nonemptiness(Type);
744 friend Type set_trep(Type&, trep);
745 friend Type remove_uninit(Type t);
746 friend Type to_cell(Type t);
747 friend bool inner_types_might_raise(const Type& t1, const Type& t2);
748 private:
749 union Data {
750 Data() {}
751 ~Data() {}
753 #define DT(tag_name,type,name) type name;
754 DATATAGS
755 #undef DT
758 template<class Ret, class T, class Function>
759 struct DDHelperFn;
761 private:
762 static Type unctxHelper(Type, bool&);
763 static Type unionArrLike(Type a, Type b);
764 template<class Ret, class T, class Function>
765 DDHelperFn<Ret,T,Function> ddbind(const Function& f, const T& t) const;
766 template<class Ret, class T, class Function>
767 Ret dd2nd(const Type&, DDHelperFn<Ret,T,Function>) const;
768 template<class Function> typename Function::result_type
769 dualDispatchDataFn(const Type&, Function) const;
770 bool hasData() const;
771 template<bool contextSensitive>
772 bool equivData(const Type&) const;
773 template<bool contextSensitive>
774 bool subtypeData(const Type&) const;
775 bool couldBeData(const Type&) const;
776 bool checkInvariants() const;
778 private:
779 trep m_bits;
780 DataTag m_dataTag = DataTag::None;
781 Data m_data;
784 //////////////////////////////////////////////////////////////////////
786 struct ArrKey {
787 folly::Optional<int64_t> i;
788 folly::Optional<SString> s;
789 Type type;
790 bool mayThrow = false;
792 folly::Optional<Cell> tv() const {
793 assert(!i || !s);
794 if (i) {
795 return make_tv<KindOfInt64>(*i);
797 if (s) {
798 return make_tv<KindOfPersistentString>(*s);
800 return folly::none;
804 struct DArrLikePacked {
805 explicit DArrLikePacked(std::vector<Type> elems, ProvTag tag)
806 : elems(std::move(elems))
807 , provenance(tag)
810 std::vector<Type> elems;
811 ProvTag provenance;
814 struct DArrLikePackedN {
815 explicit DArrLikePackedN(Type t) : type(std::move(t)) {}
816 Type type;
819 struct DArrLikeMap {
820 DArrLikeMap() {}
821 explicit DArrLikeMap(MapElems map, ProvTag tag)
822 : map(std::move(map))
823 , provenance(tag)
825 MapElems map;
826 ProvTag provenance;
829 struct DArrLikeMapN {
830 explicit DArrLikeMapN(Type key, Type val)
831 : key(std::move(key))
832 , val(std::move(val))
834 Type key;
835 Type val;
838 //////////////////////////////////////////////////////////////////////
840 #define TYPES(X) \
841 X(Bottom) \
842 X(Uninit) \
843 X(InitNull) \
844 X(False) \
845 X(True) \
846 X(Int) \
847 X(Dbl) \
848 X(SStr) \
849 X(SArrE) \
850 X(SArrN) \
851 X(Obj) \
852 X(Res) \
853 X(Cls) \
854 X(Ref) \
855 X(Func) \
856 X(ClsMeth) \
857 X(Record) \
858 X(SVecE) \
859 X(SVecN) \
860 X(SDictE) \
861 X(SDictN) \
862 X(SKeysetE) \
863 X(SKeysetN) \
864 X(Null) \
865 X(Bool) \
866 X(Num) \
867 X(Str) \
868 X(SArr) \
869 X(ArrE) \
870 X(ArrN) \
871 X(Arr) \
872 X(SVec) \
873 X(VecE) \
874 X(VecN) \
875 X(Vec) \
876 X(SDict) \
877 X(DictE) \
878 X(DictN) \
879 X(Dict) \
880 X(SKeyset) \
881 X(KeysetE) \
882 X(KeysetN) \
883 X(Keyset) \
884 X(SPArrE) \
885 X(SPArrN) \
886 X(SPArr) \
887 X(PArrE) \
888 X(PArrN) \
889 X(PArr) \
890 X(SVArrE) \
891 X(SVArrN) \
892 X(SVArr) \
893 X(VArrE) \
894 X(VArrN) \
895 X(VArr) \
896 X(SDArrE) \
897 X(SDArrN) \
898 X(SDArr) \
899 X(DArrE) \
900 X(DArrN) \
901 X(DArr) \
902 X(UncArrKey) \
903 X(ArrKey) \
904 X(UncStrLike) \
905 X(StrLike) \
906 X(InitPrim) \
907 X(Prim) \
908 X(InitUnc) \
909 X(Unc) \
910 X(OptTrue) \
911 X(OptFalse) \
912 X(OptBool) \
913 X(OptInt) \
914 X(OptDbl) \
915 X(OptNum) \
916 X(OptSStr) \
917 X(OptStr) \
918 X(OptSArrE) \
919 X(OptSArrN) \
920 X(OptSArr) \
921 X(OptArrE) \
922 X(OptArrN) \
923 X(OptArr) \
924 X(OptObj) \
925 X(OptRes) \
926 X(OptFunc) \
927 X(OptCls) \
928 X(OptClsMeth) \
929 X(OptRecord) \
930 X(OptSVecE) \
931 X(OptSVecN) \
932 X(OptSVec) \
933 X(OptVecE) \
934 X(OptVecN) \
935 X(OptVec) \
936 X(OptSDictE) \
937 X(OptSDictN) \
938 X(OptSDict) \
939 X(OptDictE) \
940 X(OptDictN) \
941 X(OptDict) \
942 X(OptSKeysetE) \
943 X(OptSKeysetN) \
944 X(OptSKeyset) \
945 X(OptKeysetE) \
946 X(OptKeysetN) \
947 X(OptKeyset) \
948 X(OptSPArrE) \
949 X(OptSPArrN) \
950 X(OptSPArr) \
951 X(OptPArrE) \
952 X(OptPArrN) \
953 X(OptPArr) \
954 X(OptSVArrE) \
955 X(OptSVArrN) \
956 X(OptSVArr) \
957 X(OptVArrE) \
958 X(OptVArrN) \
959 X(OptVArr) \
960 X(OptSDArrE) \
961 X(OptSDArrN) \
962 X(OptSDArr) \
963 X(OptDArrE) \
964 X(OptDArrN) \
965 X(OptDArr) \
966 X(OptUncArrKey) \
967 X(OptArrKey) \
968 X(OptUncStrLike) \
969 X(OptStrLike) \
970 X(InitCell) \
971 X(Cell) \
972 X(InitGen) \
973 X(Gen) \
974 X(Top)
976 #define X(y) extern const Type T##y;
977 TYPES(X)
978 #undef X
980 // These are treps that have B* names, but which are not "predefined"
981 // types. They are only allowed in combination with the corresponding
982 // S types.
983 #define NON_TYPES(X) \
984 X(CStr) \
985 X(CPArrE) \
986 X(CPArrN) \
987 X(CVArrE) \
988 X(CVArrN) \
989 X(CDArrE) \
990 X(CDArrN) \
991 X(CArrE) \
992 X(CArrN) \
993 X(CVecE) \
994 X(CVecN) \
995 X(CDictE) \
996 X(CDictN) \
997 X(CKeysetE) \
998 X(CKeysetN) \
999 X(CPArr) \
1000 X(CVArr) \
1001 X(CDArr) \
1002 X(CArr) \
1003 X(CVec) \
1004 X(CDict) \
1005 X(CKeyset) \
1006 X(OptCStr) \
1007 X(OptCPArrE) \
1008 X(OptCPArrN) \
1009 X(OptCPArr) \
1010 X(OptCVArrE) \
1011 X(OptCVArrN) \
1012 X(OptCVArr) \
1013 X(OptCDArrE) \
1014 X(OptCDArrN) \
1015 X(OptCDArr) \
1016 X(OptCArrE) \
1017 X(OptCArrN) \
1018 X(OptCArr) \
1019 X(OptCVecE) \
1020 X(OptCVecN) \
1021 X(OptCVec) \
1022 X(OptCDictE) \
1023 X(OptCDictN) \
1024 X(OptCDict) \
1025 X(OptCKeysetE) \
1026 X(OptCKeysetN) \
1027 X(OptCKeyset)
1029 //////////////////////////////////////////////////////////////////////
1032 * Return WaitH<T> for a type t.
1034 Type wait_handle(const Index&, Type t);
1037 * Return T from a WaitH<T>.
1039 * Pre: is_specialized_handle(t);
1041 Type wait_handle_inner(const Type& t);
1044 * Create Types that represent constant values.
1046 Type sval(SString);
1047 Type ival(int64_t);
1048 Type dval(double);
1049 Type aval(SArray);
1050 Type vec_val(SArray);
1051 Type dict_val(SArray);
1052 Type keyset_val(SArray);
1053 Type sval_nonstatic(SString);
1056 * Create static empty array or string types.
1058 Type sempty();
1059 Type aempty();
1060 Type aempty_varray();
1061 Type aempty_darray();
1062 Type vec_empty();
1063 Type dict_empty();
1064 Type keyset_empty();
1067 * Create an any-countedness empty array/vec/dict type.
1069 Type some_aempty();
1070 Type some_aempty_darray();
1071 Type some_vec_empty();
1072 Type some_dict_empty();
1073 Type some_keyset_empty();
1076 * Create types for objects or classes with some known constraint on
1077 * which res::Class is associated with them.
1079 Type subObj(res::Class);
1080 Type objExact(res::Class);
1081 Type subCls(res::Class);
1082 Type clsExact(res::Class);
1085 * Packed array types with known size.
1087 * Pre: !v.empty()
1089 Type arr_packed(std::vector<Type> v);
1090 Type arr_packed_varray(std::vector<Type> v);
1091 Type sarr_packed(std::vector<Type> v);
1094 * Packed array types of unknown size.
1096 * Note that these types imply the arrays are non-empty.
1098 Type arr_packedn(Type);
1099 Type sarr_packedn(Type);
1102 * Struct-like arrays.
1104 * Pre: !m.empty()
1106 Type arr_map(MapElems m);
1107 Type arr_map_darray(MapElems m);
1108 Type sarr_map(MapElems m);
1111 * Map-like arrays.
1113 Type arr_mapn(Type k, Type v);
1114 Type sarr_mapn(Type k, Type v);
1117 * vec types with known size.
1119 * Pre: !v.empty()
1121 Type vec(std::vector<Type> v, ProvTag);
1122 Type svec(std::vector<Type> v, ProvTag);
1125 * Vec type of unknown size.
1127 Type vec_n(Type);
1128 Type svec_n(Type);
1131 * Struct-like dicts.
1133 * Pre: !m.empty()
1135 Type dict_map(MapElems m, ProvTag);
1138 * Dict with key/value types.
1140 Type dict_n(Type, Type, ProvTag);
1141 Type sdict_n(Type, Type, ProvTag);
1144 * Keyset with key (same as value) type.
1146 Type keyset_n(Type);
1147 Type ckeyset_n(Type);
1150 * Keyset from MapElems
1152 inline Type keyset_map(MapElems m) {
1153 return map_impl(BKeysetN, std::move(m), folly::none);
1157 * Create the optional version of the Type t.
1159 * Pre: there must be an optional version of the type t.
1161 Type opt(Type t);
1164 * Return the non-optional version of the Type t.
1166 * Pre: is_opt(t)
1168 Type unopt(Type t);
1171 * Returns whether a given type is a subtype of one of the predefined
1172 * optional types. (Note that this does not include types like
1173 * TInitUnc---it's only the TOpt* types.)
1175 bool is_opt(const Type& t);
1178 * Return t with BNull removed from its trep.
1180 * Pre: is_nullish(t)
1182 Type unnullish(Type t);
1185 * Returns whether a given type couldBe TNull, and would still be
1186 * predefined if BNull was removed from its trep.
1188 bool is_nullish(const Type& t);
1191 * Improves the type `t` given the current context. This returns the
1192 * intersection of the type `t` with the `context` if the `context` is a valid
1193 * class or object, and `t` is tagged as being the context. If `context` is
1194 * a class we will first convert it to an object. This returns an optional type
1195 * if `t` was optional.
1197 Type return_with_context(Type t, Type context);
1200 * If `to` is false. This is an identity operation. If `to` is true, and
1201 * `t` is a specialized object or class, this will return `t` tagged as a
1202 * context.
1204 Type setctx(Type t, bool to = true);
1207 * This removes any context tags in the type `t`, even if nested inside other
1208 * types.
1210 Type unctx(Type t);
1213 * Refinedness equivalence checks.
1215 bool equivalently_refined(const Type&, const Type&);
1217 template<
1218 typename Iterable,
1219 typename = std::enable_if<
1220 std::is_same<typename Iterable::value_type, Type>::value
1223 bool equivalently_refined(const Iterable& a, const Iterable& b) {
1224 if (a.size() != b.size()) return false;
1225 for (auto ita = a.begin(), itb = b.begin(); ita != a.end(); ++ita, ++itb) {
1226 if (!equivalently_refined(*ita, *itb)) return false;
1228 return true;
1232 * Returns true if type 't' represents a "specialized" object, that is an
1233 * object of a known class, or an optional object of a known class.
1235 bool is_specialized_obj(const Type&);
1238 * Returns true if type 't' represents a "specialized" class---i.e. a class
1239 * with a DCls structure.
1241 bool is_specialized_cls(const Type&);
1244 * Returns whether `t' is a WaitH<T> or ?WaitH<T> for some T.
1246 * Note that this function returns false for Obj<=WaitHandle with no
1247 * tracked inner type.
1249 bool is_specialized_wait_handle(const Type& t);
1252 * Returns whether `t' is a one of the array like types, or
1253 * an optional version of one of those types. That is, with
1254 * either a constant value or some (maybe partially) known shape.
1256 bool is_specialized_array(const Type& t);
1257 bool is_specialized_vec(const Type& t);
1258 bool is_specialized_dict(const Type& t);
1259 bool is_specialized_keyset(const Type& t);
1262 * Returns the best known instantiation of a class type. Or returns the
1263 * provided object.
1265 * Pre: t.subypeOfAny(TObj, TCls)
1267 Type toobj(const Type& t);
1270 * Returns the best known TCls subtype for an object type. Otherwise return
1271 * the passed in type.
1273 Type objcls(const Type& t);
1276 * If the type t has a known constant value, return it as a Cell.
1277 * Otherwise return folly::none.
1279 * The returned Cell can only contain non-reference-counted types.
1281 folly::Optional<Cell> tv(const Type& t);
1284 * If the type t has a known constant value, return it as a Cell.
1285 * Otherwise return folly::none.
1287 * The returned Cell may contain reference-counted types.
1289 * You are responsible for any required ref-counting.
1291 folly::Optional<Cell> tvNonStatic(const Type& t);
1294 * If the type t has a known constant value, return true.
1295 * Otherwise return false.
1297 bool is_scalar(const Type& t);
1300 * Return the canonical scalar type for t - equivalent to
1301 * from_cell(*tv(t)).
1303 * This can be used to ensure that the arguments in a CallContext are
1304 * canonicalized, so that immaterial changes to them (eg TArrN ->
1305 * TSArrN or DArrLikeMap -> DArrLikeVal) don't affect which entry gets
1306 * looked up.
1308 * pre: is_scalar(t).
1310 Type scalarize(Type t);
1313 * If t represents an array, and we know its size, return it.
1315 folly::Optional<size_t> array_size(const Type& t);
1318 * If t represents an array, and we know the index'th element (by
1319 * iteration order), return the key/value pair.
1321 * Negative values of index work backwards from the last element.
1323 folly::Optional<std::pair<Type,Type>>
1324 array_get_by_index(const Type& t, ssize_t index);
1327 * Get the type in our typesystem that corresponds to an hhbc
1328 * IsTypeOp.
1330 * Pre: op != IsTypeOp::Scalar
1332 Type type_of_istype(IsTypeOp op);
1335 * Get the hhbc IsTypeOp that corresponds to the type in our typesystem.
1336 * Returns folly::none if no matching IsTypeOp is found.
1338 folly::Optional<IsTypeOp> type_to_istypeop(const Type& t);
1341 * Get the type in our typesystem that corresponds to type given by the
1342 * potentially unresolved type structure.
1343 * Returns folly::none if the type structure is unresolved or
1344 * no matching Type is found.
1347 folly::Optional<Type> type_of_type_structure(SArray ts);
1350 * Return the DObj structure for a strict subtype of TObj or TOptObj.
1352 * Pre: is_specialized_obj(t)
1354 DObj dobj_of(const Type& t);
1357 * Return the DCls structure for a strict subtype of TCls.
1359 * Pre: is_specialized_cls(t)
1361 DCls dcls_of(Type t);
1364 * Return the SString for a strict subtype of TStr.
1366 * Pre: is_specialized_string(t)
1368 SString sval_of(const Type& t);
1371 * Create a Type from a Cell.
1373 * Pre: the cell must contain a non-reference-counted type.
1374 * Post: returned type is a subtype of TUnc
1376 Type from_cell(Cell tv);
1379 * Create a Type from a DataType. KindOfString and KindOfPersistentString
1380 * are both treated as TStr.
1382 * Pre: dt is one of the DataTypes that actually represent php values
1383 * (or KindOfUninit).
1385 Type from_DataType(DataType dt);
1388 * Create a Type from a builtin type specification string.
1390 * This is used for HNI class properties. We assume that these are
1391 * accurate. `s' may be nullptr.
1393 Type from_hni_constraint(SString s);
1396 * Make a type that represents values from the intersection of the
1397 * supplied types.
1399 Type intersection_of(Type a, Type b);
1402 * Make a type that represents values from either of the supplied
1403 * types.
1405 * Importantly, note that there are infinitely long chains of array
1406 * types that continue to become less specialized, so chains of
1407 * union_of operations are not guaranteed to reach a stable point in
1408 * finite steps.
1410 Type union_of(Type a, Type b);
1413 * Widening union.
1415 * This operation returns a type T, such that a is a subtype of T, b
1416 * is a subtype of T, and union_of(a, b) is a subtype of T. The
1417 * widening union also has the property that every possible chain of
1418 * successive applications of the function eventually reaches a stable
1419 * point.
1421 * This is currently implemented by unioning the types, then applying
1422 * widen_type() to the result.
1424 * For portions of our analysis that rely on growing types reaching
1425 * stable points for termination, this function must occasionally be
1426 * used instead of union_of to guarantee termination. See details in
1427 * analyze.cpp.
1429 Type widening_union(const Type& a, const Type& b);
1432 * Widen a type to one which has a finite chain under the union operator. This
1433 * generally involves restricting the type's nesting depth to a fixed limit and
1434 * preventing a specialized array type from growing larger unbounded.
1436 Type widen_type(Type t);
1439 * A sort of union operation that also attempts to remove "emptyish" types from
1440 * union_of(a, b). This is useful for promoting emptyish types (sempty(),
1441 * false, and null) to stdClass or to arrays, in member instructions.
1443 * This function currently doesn't give specific guarantees about exactly when
1444 * the emptyish types will not be part of the return type (informally it only
1445 * happens in the "easy" cases right now), so you should not use it in
1446 * situations where union_of(a, b) would not also be correct.
1448 Type promote_emptyish(Type a, Type b);
1452 * Returns what we know about the emptiness of the type.
1454 Emptiness emptiness(const Type&);
1457 * Returns whether a Type could hold an object that has a custom
1458 * boolean conversion function.
1460 bool could_have_magic_bool_conversion(const Type&);
1463 * Returns the smallest type that `a' is a subtype of, from the
1464 * following set: TGen, TInitCell, TRef, TUninit, TCls.
1466 * Pre: `a' is a subtype of TGen, or TCls.
1468 Type stack_flav(Type a);
1471 * Discard any countedness information about the type. Force any type
1472 * (recursively) which contains only static or counted variants to contain
1473 * both. Doesn't change the type otherwise.
1475 Type loosen_staticness(Type);
1478 * Discard any specific knowledge about whether the type is a d/varray. Force
1479 * any type which might contain any sub-types of PArr, VArr, or DArr to contain
1480 * Arr, while keeping the same staticness and emptiness information.
1482 Type loosen_dvarrayness(Type);
1485 * Discard any specific provenance tag on this type and any sub-arrays
1487 Type loosen_provenance(Type);
1490 * Force any type which might contain any sub-types of Arr, Vec, Dict, and
1491 * Keyset to contain Arr, Vec, Dict, and Keyset. This is needed for some
1492 * operations whose effects on arrays cannot be predicted. Doesn't change the
1493 * type otherwise.
1495 Type loosen_arrays(Type);
1498 * Drop any data from the type (except for object class information) and force
1499 * TTrue or TFalse to TBool. Doesn't change the type otherwise.
1501 Type loosen_values(Type t);
1504 * Discard any emptiness information about the type. Force any type which
1505 * contains only empty or non-empty variants to contain both. Doesn't change the
1506 * type otherwise.
1508 Type loosen_emptiness(Type t);
1511 * Loosens staticness, emptiness, and values from the type. This forces a type
1512 * to its most basic form (except for object class information).
1514 Type loosen_all(Type t);
1517 * If t contains TUninit, returns the best type we can that contains
1518 * at least everything t contains, but doesn't contain TUninit. Note
1519 * that this function will return TBottom for TUninit.
1521 Type remove_uninit(Type t);
1524 * If t is not a TCell, returns TInitCell. Otherwise, if t contains
1525 * TUninit, return union_of(remove_uninit(t), TInitCell).
1527 Type to_cell(Type t);
1530 * Add non-empty variants of the type to the type if not already
1531 * present. Doesn't change the type otherwise.
1533 Type add_nonemptiness(Type t);
1536 * Produced the most refined type possible, given that
1537 * t passed/failed an emptiness check.
1539 Type assert_emptiness(Type);
1540 Type assert_nonemptiness(Type);
1543 * (array|vec|dict|keyset)_elem
1545 * Returns the best known type of an array inner element given a type
1546 * for the key. The returned type is always a subtype of TInitCell.
1548 * The returned type will be TBottom if the operation will always throw.
1549 * ThrowMode indicates what kind of failures may occur.
1551 * Pre: first arg is a subtype of TArr, TVec, TDict, TKeyset respectively.
1553 std::pair<Type,ThrowMode> array_elem(const Type& arr, const Type& key,
1554 const Type& defaultTy = TInitNull);
1555 std::pair<Type, ThrowMode> vec_elem(const Type& vec, const Type& key,
1556 const Type& defaultTy = TBottom);
1557 std::pair<Type, ThrowMode> dict_elem(const Type& dict, const Type& key,
1558 const Type& defaultTy = TBottom);
1559 std::pair<Type, ThrowMode> keyset_elem(const Type& keyset, const Type& key,
1560 const Type& defaultTy = TBottom);
1563 * (array|vec|dict|keyset)_set
1565 * Perform an array-like set on types. Returns a type that represents the
1566 * effects of arr[key] = val.
1568 * The returned type will be TBottom if the operation will always throw.
1569 * ThrowMode indicates what kind of failures may occur.
1571 * Pre: first arg is a subtype of TArr, TVec, TDict, TKeyset respectively.
1573 std::pair<Type, ThrowMode> array_set(Type arr, const Type& key,
1574 const Type& val, ProvTag src);
1575 std::pair<Type, ThrowMode> vec_set(Type vec, const Type& key, const Type& val,
1576 ProvTag src);
1577 std::pair<Type, ThrowMode> dict_set(Type dict, const Type& key,
1578 const Type& val, ProvTag src);
1579 std::pair<Type, ThrowMode> keyset_set(Type keyset, const Type& key,
1580 const Type& val);
1583 * (array|vec|dict|keyset)_newelem
1585 * Perform a newelem operation on an array-like type. Returns an
1586 * array that contains a new pushed-back element with the supplied
1587 * value, in the sense of arr[] = val, and the best known type of the
1588 * key that was added.
1590 * Pre: first arg is a subtype of TArr, TVec, TDict, TKeyset respectively.
1592 std::pair<Type,Type> array_newelem(Type arr, const Type& val, ProvTag src);
1593 std::pair<Type,Type> vec_newelem(Type vec, const Type& val, ProvTag src);
1594 std::pair<Type,Type> dict_newelem(Type dict, const Type& val, ProvTag src);
1595 std::pair<Type,Type> keyset_newelem(Type keyset, const Type& val);
1598 * Return the best known information for iteration of the supplied type. This is
1599 * only intended for non-mutable iteration, so the returned types are at worst
1600 * InitCell.
1602 struct IterTypes {
1603 Type key;
1604 Type value;
1605 // The number of elements we're iterating over:
1606 enum struct Count {
1607 Empty, // No elements
1608 Single, // Exactly one element
1609 ZeroOrOne, // Less than 2 elements
1610 NonEmpty, // Unknown upper bound, but non-empty
1611 Any // Nothing known
1613 Count count;
1614 // Can a IterInit[K] op throw on this iterator?
1615 bool mayThrowOnInit;
1616 // Can a IterNext[K] op throw on this iterator? Can only happen for object
1617 // types.
1618 bool mayThrowOnNext;
1620 IterTypes iter_types(const Type&);
1623 * Create a RepoAuthType for a Type.
1625 * RepoAuthTypes may contain things like RepoAuthType::Array*'s or
1626 * SStrings for class names. The emit code needs to handle making
1627 * sure these things are merged into the appropriate unit or repo.
1629 * Pre: !t.couldBe(BCls)
1630 * !t.subtypeOf(BBottom)
1632 RepoAuthType make_repo_type(ArrayTypeTable::Builder&, const Type& t);
1635 * Returns true iff an IsType testing for testTy/testOp on valTy might raise.
1637 bool is_type_might_raise(const Type& testTy, const Type& valTy);
1638 bool is_type_might_raise(IsTypeOp testOp, const Type& valTy);
1641 * Returns true iff a compare of two types might raise a HAC notice
1643 bool compare_might_raise(const Type& t1, const Type& t2);
1646 * Given a type, adjust the type for the given type-constraint. If there's no
1647 * type-constraint, or if property type-hints aren't being enforced, then return
1648 * the type as is. This might return TBottom if the type is not compatible with
1649 * the type-hint.
1651 Type adjust_type_for_prop(const Index& index,
1652 const php::Class& propCls,
1653 const TypeConstraint* tc,
1654 const Type& ty);
1656 //////////////////////////////////////////////////////////////////////
1660 #endif