Skip to content
Prev Previous commit
Next Next commit
Shadow ArrayType and the array accessory types natively
ArrayType (implements Type: key/item types, every array operation,
template inference) and the five array accessories NonEmptyArrayType,
AccessoryArrayListType, OversizedArrayType, HasOffsetType and
HasOffsetValueType (CompoundType + AccessoryType). Six more trait
registrars; a union-typed property builder; the closures the
twins hand to TypeTraverser::map() become an internal NativeCallback
holder running a C body. The type-family differential gains 44 subjects
(246k observations).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
  • Loading branch information
ondrejmirtes and claude committed Sep 21, 2026
commit 4a8441d1c3f311d30ca1f67d0f658056e5be6f7c
2 changes: 2 additions & 0 deletions src/Rules/Arrays/AllowedArrayKeysTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Rules\Arrays;

use PHPStan\Php\PhpVersion;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantBooleanType;
Expand All @@ -19,6 +20,7 @@
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;

#[ReferencedByTurboExtension(key: 'allowedArrayKeysTypes')]
final class AllowedArrayKeysTypes
{

Expand Down
4 changes: 2 additions & 2 deletions src/Type/Accessory/AccessoryArrayListType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
Expand All @@ -32,7 +32,7 @@

/** @api */
#[InstanceofDeprecated(insteadUse: 'Type::isList()')]
#[ReferencedByTurboExtension(key: 'accessoryArrayListType')]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/AccessoryArrayListType.cpp')]
class AccessoryArrayListType implements CompoundType, AccessoryType
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/HasOffsetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
Expand Down Expand Up @@ -43,6 +44,7 @@
use const CASE_UPPER;

#[InstanceofDeprecated(insteadUse: 'Type::hasOffsetValueType()')]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/HasOffsetType.cpp')]
class HasOffsetType implements CompoundType, AccessoryType
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/HasOffsetValueType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
Expand Down Expand Up @@ -45,6 +46,7 @@
use const CASE_LOWER;
use const CASE_UPPER;

#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/HasOffsetValueType.cpp')]
class HasOffsetValueType implements CompoundType, AccessoryType
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/NonEmptyArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
Expand All @@ -31,6 +32,7 @@
use PHPStan\Type\VerbosityLevel;

#[InstanceofDeprecated(insteadUse: 'Type::isIterableAtLeastOnce()')]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/NonEmptyArrayType.cpp')]
class NonEmptyArrayType implements CompoundType, AccessoryType
{

Expand Down
4 changes: 2 additions & 2 deletions src/Type/Accessory/OversizedArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
Expand All @@ -30,7 +30,7 @@
use PHPStan\Type\VerbosityLevel;

#[InstanceofDeprecated(insteadUse: 'Type::isOversizedArray()')]
#[ReferencedByTurboExtension(key: 'oversizedArrayType')]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/OversizedArrayType.cpp')]
class OversizedArrayType implements CompoundType, AccessoryType
{

Expand Down
4 changes: 2 additions & 2 deletions src/Type/ArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use PHPStan\Rules\Arrays\AllowedArrayKeysTypes;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\Accessory\AccessoryArrayListType;
use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
Expand Down Expand Up @@ -52,7 +52,7 @@

/** @api */
#[InstanceofDeprecated(insteadUse: 'Type::isArray() or Type::getArrays()')]
#[ReferencedByTurboExtension(key: 'arrayType')]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../turbo-ext/src/ArrayType.cpp')]
class ArrayType implements Type
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/Constant/ConstantArrayTypeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHPStan\DependencyInjection\BleedingEdgeToggle;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Type\Accessory\AccessoryArrayListType;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\Accessory\OversizedArrayType;
Expand All @@ -29,6 +30,7 @@
/**
* @api
*/
#[ReferencedByTurboExtension(key: 'constantArrayTypeBuilder')]
final class ConstantArrayTypeBuilder
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/Generic/TemplateStrictMixedType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

namespace PHPStan\Type\Generic;

use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\IsSuperTypeOfResult;
use PHPStan\Type\MixedType;
use PHPStan\Type\StrictMixedType;
use PHPStan\Type\Type;

/** @api */
#[ReferencedByTurboExtension(key: 'templateStrictMixedType')]
final class TemplateStrictMixedType extends StrictMixedType implements TemplateType
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/Traverser/UnsafeArrayStringKeyCastingTraverser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Type\Traverser;

use PHPStan\DependencyInjection\ReportUnsafeArrayStringKeyCastingToggle;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Type\Accessory\AccessoryDecimalIntegerStringType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\Type;
Expand All @@ -19,6 +20,7 @@
* array (cast key) against a constant-array shape (raw key) yields a spurious
* `Maybe`.
*/
#[ReferencedByTurboExtension(key: 'unsafeArrayStringKeyCastingTraverser')]
final class UnsafeArrayStringKeyCastingTraverser implements TypeTraverserCallable
{

Expand Down
2 changes: 2 additions & 0 deletions src/Type/TypeUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Type;

use PHPStan\Internal\CombinationsHelper;
use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Type\Accessory\AccessoryType;
use PHPStan\Type\Accessory\HasPropertyType;
use PHPStan\Type\Constant\ConstantIntegerType;
Expand All @@ -18,6 +19,7 @@
/**
* @api
*/
#[ReferencedByTurboExtension(key: 'typeUtils')]
final class TypeUtils
{

Expand Down
2 changes: 1 addition & 1 deletion turbo-ext/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ if (PHP_PHPSTAN_TURBO != "no") {
// directory by splitting on backslashes only — with forward slashes the
// objects compile flat while the link list expects the subpath
EXTENSION("phpstan_turbo",
"src\\main.cpp src\\support.cpp src\\AcceptsResult.cpp src\\ArenaCache.cpp src\\BooleanType.cpp src\\ClassStringType.cpp src\\CombinationsHelper.cpp src\\ConditionalExpressionHolder.cpp src\\ConstantBooleanType.cpp src\\ConstantFloatType.cpp src\\ConstantIntegerType.cpp src\\ConstantStringType.cpp src\\ExpressionResultStorage.cpp src\\ExpressionTypeHolder.cpp src\\FloatType.cpp src\\GenericClassStringType.cpp src\\GenericStaticType.cpp src\\IntegerRangeType.cpp src\\IntegerType.cpp src\\IsSuperTypeOfResult.cpp src\\MixedType.cpp src\\NeverType.cpp src\\NodeScanner.cpp src\\NodeTraverser.cpp src\\NonexistentParentClassType.cpp src\\NullType.cpp src\\ObjectShapeType.cpp src\\ObjectWithoutClassType.cpp src\\PharForkGuard.cpp src\\PhpFileCleaner.cpp src\\ScopeContext.cpp src\\ScopeOps.cpp src\\Shadow.cpp src\\StaticType.cpp src\\StrictMixedType.cpp src\\StringType.cpp src\\SymbolFinderInFiles.cpp src\\ThisType.cpp src\\TrinaryLogic.cpp src\\TrustedTypes.cpp src\\TypeCombinatorCache.cpp src\\TypeTraits.cpp src\\VoidType.cpp",
"src\\main.cpp src\\support.cpp src\\AcceptsResult.cpp src\\AccessoryArrayListType.cpp src\\ArenaCache.cpp src\\ArrayType.cpp src\\BooleanType.cpp src\\ClassStringType.cpp src\\CombinationsHelper.cpp src\\ConditionalExpressionHolder.cpp src\\ConstantBooleanType.cpp src\\ConstantFloatType.cpp src\\ConstantIntegerType.cpp src\\ConstantStringType.cpp src\\ExpressionResultStorage.cpp src\\ExpressionTypeHolder.cpp src\\FloatType.cpp src\\GenericClassStringType.cpp src\\GenericStaticType.cpp src\\HasOffsetType.cpp src\\HasOffsetValueType.cpp src\\IntegerRangeType.cpp src\\IntegerType.cpp src\\IsSuperTypeOfResult.cpp src\\MixedType.cpp src\\NeverType.cpp src\\NodeScanner.cpp src\\NodeTraverser.cpp src\\NonEmptyArrayType.cpp src\\NonexistentParentClassType.cpp src\\NullType.cpp src\\ObjectShapeType.cpp src\\ObjectWithoutClassType.cpp src\\OversizedArrayType.cpp src\\PharForkGuard.cpp src\\PhpFileCleaner.cpp src\\ScopeContext.cpp src\\ScopeOps.cpp src\\Shadow.cpp src\\StaticType.cpp src\\StrictMixedType.cpp src\\StringType.cpp src\\SymbolFinderInFiles.cpp src\\ThisType.cpp src\\TrinaryLogic.cpp src\\TrustedTypes.cpp src\\TypeCombinatorCache.cpp src\\TypeTraits.cpp src\\VoidType.cpp",
true,
flags);
ADD_SOURCES(configure_module_dirname + "/src/parser",
Expand Down
Loading