Skip to content

Commit f2fa936

Browse files
phpstan-botclaude
andcommitted
Revert the ConstantArrayType::checkOurKeys() accepts() cache
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 523729f commit f2fa936

2 files changed

Lines changed: 17 additions & 57 deletions

File tree

‎src/Type/Constant/ConstantArrayType.php‎

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
use function pow;
9090
use function range;
9191
use function sort;
92-
use function spl_object_id;
9392
use function sprintf;
9493
use function str_contains;
9594
use function strtolower;
@@ -700,10 +699,6 @@ public function accepts(Type $type, bool $strictTypes): AcceptsResult
700699
private function checkOurKeys(Type $type, bool $strictTypes): AcceptsResult
701700
{
702701
$result = AcceptsResult::createYes();
703-
704-
// offsets sharing the same value types (e.g. a type alias used for many keys) are compared once
705-
/** @var array<string, array{Type, AcceptsResult}> $acceptsValueCache */
706-
$acceptsValueCache = [];
707702
foreach ($this->keyTypes as $i => $keyType) {
708703
$valueType = $this->valueTypes[$i];
709704
$hasOffsetValueType = $type->hasOffsetValueType($keyType);
@@ -723,29 +718,23 @@ private function checkOurKeys(Type $type, bool $strictTypes): AcceptsResult
723718

724719
$result = $result->and($hasOffset);
725720
$otherValueType = $type->getOffsetValueType($keyType);
726-
$acceptsValueCacheKey = spl_object_id($valueType) . '-' . spl_object_id($otherValueType);
727-
if (isset($acceptsValueCache[$acceptsValueCacheKey])) {
728-
$acceptsValue = $acceptsValueCache[$acceptsValueCacheKey][1];
729-
} else {
730-
$acceptsValue = $valueType->accepts($otherValueType, $strictTypes);
731-
// $otherValueType is kept alive so that its id is not reused
732-
$acceptsValueCache[$acceptsValueCacheKey] = [$otherValueType, $acceptsValue];
733-
}
734-
if ($acceptsValue->yes() && count($acceptsValue->reasons) === 0) {
735-
continue;
736-
}
721+
$verbosity = null;
722+
$acceptsValue = $valueType->accepts($otherValueType, $strictTypes)->decorateReasons(
723+
static function (string $reason) use ($keyType, $valueType, &$verbosity, $otherValueType) {
724+
$verbosity ??= VerbosityLevel::getRecommendedLevelByType($valueType, $otherValueType);
737725

738-
$verbosity = VerbosityLevel::getRecommendedLevelByType($valueType, $otherValueType);
739-
$acceptsValue = $acceptsValue->decorateReasons(
740-
static fn (string $reason) => sprintf(
741-
'Offset %s (%s) does not accept type %s: %s',
742-
$keyType->describe(VerbosityLevel::precise()),
743-
$valueType->describe($verbosity),
744-
$otherValueType->describe($verbosity),
745-
$reason,
746-
),
726+
return sprintf(
727+
'Offset %s (%s) does not accept type %s: %s',
728+
$keyType->describe(VerbosityLevel::precise()),
729+
$valueType->describe($verbosity),
730+
$otherValueType->describe($verbosity),
731+
$reason,
732+
);
733+
},
747734
);
748735
if (!$acceptsValue->yes() && count($acceptsValue->reasons) === 0 && $type->isConstantArray()->yes()) {
736+
$verbosity ??= VerbosityLevel::getRecommendedLevelByType($valueType, $otherValueType);
737+
749738
$acceptsValue = new AcceptsResult($acceptsValue->result, [
750739
sprintf(
751740
'Offset %s (%s) does not accept type %s.',

‎turbo-ext/src/ConstantArrayType.cpp‎

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,12 +1658,6 @@ class ConstantArrayType
16581658
zval *k = keyTypes();
16591659
zval *v = k != NULL ? valueTypes() : NULL;
16601660
if (UNEXPECTED(result.isUndef() || v == NULL)) return zv::Val();
1661-
/* $acceptsValueCache = [] — keyed by both object handles in one
1662-
* integer instead of the twin's 'id-id' string */
1663-
zval acceptsValueCacheZv;
1664-
array_init(&acceptsValueCacheZv);
1665-
zv::Val acceptsValueCacheHolder = zv::Val::adopt(acceptsValueCacheZv);
1666-
HashTable *acceptsValueCache = Z_ARRVAL(acceptsValueCacheZv);
16671661
for (zv::ArrayEntry entry : zv::ArrRef(k)) {
16681662
zend_long i = (zend_long) entry.indexKey();
16691663
zval *keyType = entry.value().deref().raw();
@@ -1708,34 +1702,11 @@ class ConstantArrayType
17081702
if (UNEXPECTED(result.isUndef())) return zv::Val();
17091703
zv::Val otherValueType = callType(Z_OBJ_P(type), PT_LC("getoffsetvaluetype"), 1, keyType);
17101704
if (UNEXPECTED(otherValueType.isUndef())) return zv::Val();
1711-
zend_ulong acceptsValueCacheKey = ((zend_ulong) Z_OBJ_HANDLE_P(valueType) << 32) | (zend_ulong) Z_OBJ_HANDLE_P(otherValueType.raw());
1712-
zv::Val acceptsValue;
1713-
zval *acceptsValueCached = zend_hash_index_find(acceptsValueCache, acceptsValueCacheKey);
1714-
if (acceptsValueCached != NULL) {
1715-
acceptsValue = zv::Val::copyOf(zv::Ref(zend_hash_index_find(Z_ARRVAL_P(acceptsValueCached), 1)));
1716-
} else {
1717-
zv::Args args{otherValueType.raw(), strictTypes};
1718-
acceptsValue = pt_type_op(Z_OBJ_P(valueType), PT_OP_ACCEPTS, 2, args);
1719-
if (UNEXPECTED(acceptsValue.isUndef())) return zv::Val();
1720-
/* $otherValueType is kept alive so that its id is not reused */
1721-
zval pair;
1722-
array_init_size(&pair, 2);
1723-
Z_TRY_ADDREF_P(otherValueType.raw());
1724-
add_next_index_zval(&pair, otherValueType.raw());
1725-
Z_TRY_ADDREF_P(acceptsValue.raw());
1726-
add_next_index_zval(&pair, acceptsValue.raw());
1727-
zend_hash_index_update(acceptsValueCache, acceptsValueCacheKey, &pair);
1728-
}
1729-
/* $acceptsValue->yes() && count($acceptsValue->reasons) === 0: continue */
1730-
zend_long acceptsValueBefore = pt_type_result_trinary(acceptsValue.raw());
1731-
if (UNEXPECTED(acceptsValueBefore < 0)) return zv::Val();
1732-
if (acceptsValueBefore == PT_TRI_YES) {
1733-
zv::Val acceptsValueReasons = resultReasons(acceptsValue.raw());
1734-
if (UNEXPECTED(acceptsValueReasons.isUndef())) return zv::Val();
1735-
if (arrayCount(acceptsValueReasons.raw()) == 0) continue;
1736-
}
17371705
zv::Val verbosity = pt_type_verbosity_recommended(valueType, otherValueType.raw());
17381706
if (UNEXPECTED(verbosity.isUndef())) return zv::Val();
1707+
zv::Args args{otherValueType.raw(), strictTypes};
1708+
zv::Val acceptsValue = pt_type_op(Z_OBJ_P(valueType), PT_OP_ACCEPTS, 2, args);
1709+
if (UNEXPECTED(acceptsValue.isUndef())) return zv::Val();
17391710
zv::Val captured = quadOf(keyType, valueType, verbosity.raw(), otherValueType.raw());
17401711
acceptsValue = decorateReasons(acceptsValue.raw(), offsetReasonCallback, captured.raw(), NULL);
17411712
if (UNEXPECTED(acceptsValue.isUndef())) return zv::Val();

0 commit comments

Comments
 (0)