public function isSubTypeOf(PhpType $type)
 {
     if (parent::isSubTypeOf($type)) {
         return true;
     }
     if ($type->isCallableType()) {
         return true;
     }
     return false;
 }
 public function isSubTypeOf(PhpType $that)
 {
     if (parent::isSubTypeOf($that)) {
         return true;
     }
     if ($that->isArrayType()) {
         // Every Array type is a subtype of the generic Array type.
         if ($that === $this->registry->getNativeType('array')) {
             return true;
         }
         // Key and Element Types must be subtypes.
         if (!$this->keyType->isSubTypeOf($that->keyType)) {
             return false;
         }
         if (!$this->elementType->isSubTypeOf($that->elementType) || $this->registry->getNativeType('generic_array_value') === $this->elementType && !$that->elementType->equals($this->registry->getNativeType('all'))) {
             return false;
         }
         // If the other array has no item types, this is a sub-type of the other array.
         if (empty($that->itemTypes)) {
             return true;
         }
         // If that is the case, we also need to ensure that this type has at least all the items
         // of the other types, and that their respective types are also sub-types.
         foreach ($that->itemTypes as $name => $itemType) {
             if (!isset($this->itemTypes[$name])) {
                 return false;
             }
             if (!$this->itemTypes[$name]->isSubtypeOf($itemType)) {
                 return false;
             }
         }
         return true;
     }
     if ($that->isCallableType()) {
         return true;
     }
     return false;
 }
 public function getLeastSupertype(PhpType $that)
 {
     if (!$that->isUnknownType() && !$that->isUnknownType()) {
         foreach ($this->alternates as $alternate) {
             if (!$alternate->isUnknownType() && $that->isSubTypeOf($alternate)) {
                 return $this;
             }
         }
     }
     return $this->equals($that) ? $this : $this->registry->createUnionType(array($this, $that));
 }