pub struct Type {
pub types: SmallVec<[Atomic; 2]>,
pub possibly_undefined: bool,
pub from_docblock: bool,
}Fields§
§types: SmallVec<[Atomic; 2]>§possibly_undefined: boolThe variable holding this type may not be initialized at this point.
from_docblock: boolThis type originated from a docblock annotation rather than inference.
Implementations§
Source§impl Type
impl Type
pub fn empty() -> Type
pub fn single(atomic: Atomic) -> Type
pub fn mixed() -> Type
pub fn void() -> Type
pub fn never() -> Type
pub fn null() -> Type
pub fn bool() -> Type
pub fn int() -> Type
pub fn float() -> Type
pub fn string() -> Type
Sourcepub fn array_key() -> Type
pub fn array_key() -> Type
int|string — the canonical PHP array-key type, used as the default
key type when a docblock/inferred array has no more specific key.
Sourcepub fn from_vec(atomics: Vec<Atomic>) -> Type
pub fn from_vec(atomics: Vec<Atomic>) -> Type
Build a union from multiple atomics, de-duplicating on the fly.
pub fn is_empty(&self) -> bool
pub fn is_single(&self) -> bool
pub fn is_nullable(&self) -> bool
Sourcepub fn is_array_key(&self) -> bool
pub fn is_array_key(&self) -> bool
True when this is exactly int|string — the array-key domain, which
is already the maximal set of legal PHP array keys and so should be
treated like a “default”/unconstrained key, same as mixed would be
for a non-key type parameter.
pub fn is_mixed(&self) -> bool
Sourcepub fn is_mixed_not_template(&self) -> bool
pub fn is_mixed_not_template(&self) -> bool
True only when the type contains TMixed atoms and no TTemplateParam atoms.
Unlike [is_mixed], this does not treat an unconstrained template parameter as
“mixed” — a T placeholder is an intentionally parameterised type that will be
instantiated at the call site, so it must not trigger MixedAssignment warnings.
pub fn is_never(&self) -> bool
Sourcepub fn clone_validity(&self) -> CloneValidity
pub fn clone_validity(&self) -> CloneValidity
Classify this type for clone validity. Recurses into template-param
bounds (like Type::is_mixed). Callers handle mixed separately.
pub fn is_void(&self) -> bool
pub fn can_be_falsy(&self) -> bool
pub fn can_be_truthy(&self) -> bool
pub fn contains<F>(&self, f: F) -> bool
pub fn has_named_object(&self, fqcn: &str) -> bool
Sourcepub fn add_type(&mut self, atomic: Atomic)
pub fn add_type(&mut self, atomic: Atomic)
Add an atomic to this union, skipping duplicates. Subsumption rules: anything ⊆ TMixed; TLiteralInt ⊆ TInt; etc.
Sourcepub fn remove_null(&self) -> Type
pub fn remove_null(&self) -> Type
Remove null from the union (e.g. after a null check).
Sourcepub fn remove_false(&self) -> Type
pub fn remove_false(&self) -> Type
Remove false from the union.
TFalse is dropped; TBool becomes TTrue since bool - false = true.
Sourcepub fn core_type(&self) -> Type
pub fn core_type(&self) -> Type
Remove both null and false from the union (core type without nullable/falsy variants).
Sourcepub fn narrow_to_truthy(&self) -> Type
pub fn narrow_to_truthy(&self) -> Type
Keep only truthy atomics (e.g. after if ($x)).
Sourcepub fn narrow_to_falsy(&self) -> Type
pub fn narrow_to_falsy(&self) -> Type
Keep only falsy atomics (e.g. after if (!$x)).
Sourcepub fn narrow_instanceof(&self, class: &str) -> Type
pub fn narrow_instanceof(&self, class: &str) -> Type
Narrow this type as if $x instanceof ClassName is true.
The instanceof check guarantees the value IS an instance of class, so we
replace any object / mixed constituents with the specific named object. Scalar
constituents are dropped (they can never satisfy instanceof).
Sourcepub fn narrow_to_string(&self) -> Type
pub fn narrow_to_string(&self) -> Type
Narrow as if is_string($x) is true. mixed/scalar become a concrete
string (rather than staying mixed) so downstream string-only
operations see a usable type instead of reporting Mixed*.
Sourcepub fn narrow_to_int(&self) -> Type
pub fn narrow_to_int(&self) -> Type
Narrow as if is_int($x) is true.
Sourcepub fn narrow_to_float(&self) -> Type
pub fn narrow_to_float(&self) -> Type
Narrow as if is_float($x) is true.
Sourcepub fn narrow_to_bool(&self) -> Type
pub fn narrow_to_bool(&self) -> Type
Narrow as if is_bool($x) is true.
Sourcepub fn narrow_to_null(&self) -> Type
pub fn narrow_to_null(&self) -> Type
Narrow as if is_null($x) is true.
Sourcepub fn narrow_to_array(&self) -> Type
pub fn narrow_to_array(&self) -> Type
Narrow as if is_array($x) is true.
Sourcepub fn narrow_to_non_empty_collection(&self) -> Type
pub fn narrow_to_non_empty_collection(&self) -> Type
Narrow array/list types to their non-empty variants (for count() > 0 etc.).
Sourcepub fn narrow_to_empty_collection(&self) -> Type
pub fn narrow_to_empty_collection(&self) -> Type
Narrow array/list types when proven empty (e.g. array_key_first($x) === null).
Drops the non-empty variants outright — they can never be empty — but
otherwise leaves atoms unchanged, since there’s no atomic “provably
empty array” type to narrow a plain array/list down to.
Sourcepub fn narrow_to_list(&self) -> Type
pub fn narrow_to_list(&self) -> Type
Narrow as if array_is_list($x) is true.
Lists have sequential integer keys starting from 0, so:
list<T>/non-empty-list<T>are kept unchanged.array<int, T>is narrowed tolist<T>(could be sequential).non-empty-array<int, T>is narrowed tonon-empty-list<T>.mixedbecomeslist<mixed>(array_is_list implies array).- All other types (string-keyed arrays, non-arrays) are dropped.
Sourcepub fn narrow_to_object(&self) -> Type
pub fn narrow_to_object(&self) -> Type
Narrow as if is_object($x) is true. A mixed becomes a concrete bare
object (rather than staying mixed) so downstream object-only
operations — clone, instanceof, method calls — see an object type
instead of reporting Mixed*.
Sourcepub fn narrow_to_callable(&self) -> Type
pub fn narrow_to_callable(&self) -> Type
Narrow as if is_callable($x) is true.
PHP accepts closures, TCallable, strings (function names), arrays ([‘Class’, ‘method’] or [$obj, ‘method’]), and objects with __invoke. Keep all of these; only drop atoms that are definitely not callable (scalars, null, bool, etc.).
Sourcepub fn narrow_to_scalar(&self) -> Type
pub fn narrow_to_scalar(&self) -> Type
Narrow as if is_scalar($x) is true (int | string | float | bool).
Sourcepub fn narrow_to_iterable(&self) -> Type
pub fn narrow_to_iterable(&self) -> Type
Narrow as if is_iterable($x) is true (array | Traversable).
For simplicity, this narrows to arrays or objects (can’t easily verify interfaces).
Sourcepub fn narrow_to_countable(&self) -> Type
pub fn narrow_to_countable(&self) -> Type
Narrow as if is_countable($x) is true (array | Countable).
For simplicity, this narrows to arrays or objects (can’t easily verify Countable interface).
Sourcepub fn narrow_to_resource(&self) -> Type
pub fn narrow_to_resource(&self) -> Type
Narrow as if is_resource($x) is true.
Note: No TResource atomic type exists in the type system; this is a no-op.
Resources are declining in modern PHP and not actively tracked.
Sourcepub fn narrow_to_class_string(&self) -> Type
pub fn narrow_to_class_string(&self) -> Type
Narrow as if class_exists($x) returned true for a string variable.
String atoms become class-string; existing class-string atoms pass through;
mixed/scalar becomes class-string. Non-string atoms are dropped (returning
empty so the caller can mark the branch as diverging).
Sourcepub fn narrow_to_interface_string(&self) -> Type
pub fn narrow_to_interface_string(&self) -> Type
Narrow as if interface_exists($x) returned true for a string variable.
String atoms become interface-string; existing interface-string atoms pass
through; mixed/scalar becomes interface-string. Non-string atoms are dropped
(returning empty so the caller can mark the branch as diverging).
Sourcepub fn merge(a: &Type, b: &Type) -> Type
pub fn merge(a: &Type, b: &Type) -> Type
Merge two unions at a branch join point (e.g. after if/else). The result is the union of all types in both.
Sourcepub fn merge_with(&mut self, other: &Type)
pub fn merge_with(&mut self, other: &Type)
Merge other into self in-place (avoids cloning self).
Sourcepub fn intersect_with(&self, other: &Type) -> Type
pub fn intersect_with(&self, other: &Type) -> Type
Intersect with another union: keep only types present in other, widening
where self contains mixed (which is compatible with everything).
Used for match-arm subject narrowing.
Sourcepub fn substitute_templates(
&self,
bindings: &HashMap<Name, Type, FxBuildHasher>,
) -> Type
pub fn substitute_templates( &self, bindings: &HashMap<Name, Type, FxBuildHasher>, ) -> Type
Replace template param references with their resolved types.
Sourcepub fn resolve_conditional_returns<F>(self, lookup: F) -> Type
pub fn resolve_conditional_returns<F>(self, lookup: F) -> Type
Resolves TConditional atoms whose discriminator is known at the call site.
lookup(param_name) returns the call-site argument type for the named parameter,
or None if the argument is not available. Handles is null, is string, and
is array conditions; other condition types pass through unchanged.
Sourcepub fn is_subtype_structural(&self, other: &Type) -> bool
pub fn is_subtype_structural(&self, other: &Type) -> bool
Returns true if every atomic in self is a subtype of some atomic in other,
using only structural rules — no extends / implements walk.
Two distinct user-defined classes are never related here, even when one
extends the other. Within mir-analyzer, when a db is in scope,
prefer crate::subtype::is_subtype(db, sub, sup) which layers
inheritance resolution on top of this check.
Sourcepub fn accepts_atomic_structural(&self, sub: &Atomic) -> bool
pub fn accepts_atomic_structural(&self, sub: &Atomic) -> bool
sub <: self, structurally, for a single atomic — equivalent to
Type::single(sub.clone()).is_subtype_structural(self) without the
clone and the temporary single-atomic union.
Sourcepub fn possibly_undefined(self) -> Type
pub fn possibly_undefined(self) -> Type
Mark this union as possibly-undefined and return it.
Sourcepub fn from_docblock(self) -> Type
pub fn from_docblock(self) -> Type
Mark this union as coming from a docblock annotation.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Type
impl<'de> Deserialize<'de> for Type
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Type, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Type, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for Type
Source§impl Serialize for Type
impl Serialize for Type
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for Type
Auto Trait Implementations§
impl Freeze for Type
impl RefUnwindSafe for Type
impl Send for Type
impl Sync for Type
impl Unpin for Type
impl UnsafeUnpin for Type
impl UnwindSafe for Type
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.