Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Shadow ArrayDimFetchHandler and VariableWriteOffset natively
The offset fetch handler with its `$arr[]` and offset type callbacks and both
specify-types callbacks as native closures, registered as the class's handler entry;
the ArrayAccess offsetGet throw points and return type (MethodThrowPointHelper,
MethodCallReturnTypeHelper) and the offset-read variable flow run natively.
AssignHandler's composeResult() site uses the new
pt_array_dim_fetch_handler_compose_result entry. VariableWriteOffset::fromType() is
native too (pt_variable_write_offset_from_type, with a smoke differential), and
VariableFlowBuilder calls it directly. Class-map key removed: variableWriteOffset.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3SmhnNkB3pEeVRTxqbdbu
  • Loading branch information
ondrejmirtes and claude committed Sep 22, 2026
commit 2034557eb0bef6a6db7648dd9b35ae80621c9280
2 changes: 2 additions & 0 deletions src/Analyser/ExprHandler/ArrayDimFetchHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use PHPStan\DependencyInjection\AutowiredService;
use PHPStan\Node\Expr\TypeExpr;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\ErrorType;
use PHPStan\Type\NeverType;
use PHPStan\Type\ObjectType;
Expand All @@ -41,6 +42,7 @@
* @implements ExprHandler<ArrayDimFetch>
*/
#[AutowiredService]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../../turbo-ext/src/ArrayDimFetchHandler.cpp')]
final class ArrayDimFetchHandler implements ExprHandler
{

Expand Down
4 changes: 2 additions & 2 deletions src/Analyser/VariableWriteOffset.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace PHPStan\Analyser;

use PHPStan\Turbo\ReferencedByTurboExtension;
use PHPStan\Turbo\ShadowedByTurboExtension;
use PHPStan\Type\Type;
use function count;
use function is_int;
Expand All @@ -13,7 +13,7 @@
*
* @internal
*/
#[ReferencedByTurboExtension(key: 'variableWriteOffset')]
#[ShadowedByTurboExtension(implementation: __DIR__ . '/../../turbo-ext/src/VariableWriteOffset.cpp')]
final class VariableWriteOffset
{

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\\AbsorbedTemplateArgumentType.cpp src\\AcceptsResult.cpp src\\AccessoryArrayListType.cpp src\\AccessoryDecimalIntegerStringType.cpp src\\AccessoryLiteralStringType.cpp src\\AccessoryLowercaseStringType.cpp src\\AccessoryNonEmptyStringType.cpp src\\AccessoryNonFalsyStringType.cpp src\\AccessoryNumericStringType.cpp src\\AccessoryUppercaseStringType.cpp src\\ArenaCache.cpp src\\ArgsResult.cpp src\\ArgumentsHandler.cpp src\\ArgumentsNormalizer.cpp src\\ArrayFilterArgVisitor.cpp src\\ArrayFindArgVisitor.cpp src\\ArrayMapArgVisitor.cpp src\\ArrayOffsetNormalizingVisitor.cpp src\\ArrayType.cpp src\\ArrayWalkArgVisitor.cpp src\\ArrowFunctionArgVisitor.cpp src\\AssignHandler.cpp src\\AssignOpHandler.cpp src\\AssignTargetWalkMode.cpp src\\BenevolentUnionType.cpp src\\BlockHandler.cpp src\\BooleanNarrowingHelper.cpp src\\BooleanType.cpp src\\CallableType.cpp src\\CallableTypeHelper.cpp src\\CallbackUnresolvedMethodPrototypeReflection.cpp src\\CallbackUnresolvedPropertyPrototypeReflection.cpp src\\CalledOnTypeUnresolvedMethodPrototypeReflection.cpp src\\CalledOnTypeUnresolvedPropertyPrototypeReflection.cpp src\\ChangedTypeMethodReflection.cpp src\\CircularTypeAliasErrorType.cpp src\\ClassConstantAccessType.cpp src\\ClassLikeHandler.cpp src\\ClassMethodHandler.cpp src\\ClassReflection.cpp src\\ClassStatementsGatherer.cpp src\\ClassStringType.cpp src\\ClosureArgVisitor.cpp src\\ClosureBindArgVisitor.cpp src\\ClosureBindToVarVisitor.cpp src\\ClosureType.cpp src\\CombinationsHelper.cpp src\\ConditionalExpressionHolder.cpp src\\ConditionalExpressionHolderHelper.cpp src\\ConditionalExpressionHolderRecipe.cpp src\\ConditionalType.cpp src\\ConditionalTypeForParameter.cpp src\\ConstantArrayType.cpp src\\ConstantArrayTypeBuilder.cpp src\\ConstantBooleanType.cpp src\\ConstantFloatType.cpp src\\ConstantIntegerType.cpp src\\ConstantStringType.cpp src\\ConstantTypeHelper.cpp src\\CurlSetOptArgVisitor.cpp src\\CurlSetOptArrayArgVisitor.cpp src\\DeclarePositionVisitor.cpp src\\DefaultNarrowingHelper.cpp src\\DisjunctionBranchUnionAugment.cpp src\\DisjunctionHolderProjectionAugment.cpp src\\DummyParameter.cpp src\\DynamicReturnTypeStoragePrimer.cpp src\\EarlyTerminatingCallHelper.cpp src\\EchoHandler.cpp src\\EndStatementResult.cpp src\\Engine.cpp src\\EnumCaseObjectType.cpp src\\ErrorType.cpp src\\ExpressionContext.cpp src\\ExpressionHandler.cpp src\\ExpressionResult.cpp src\\ExpressionResultStorage.cpp src\\ExpressionResultStorageStack.cpp src\\ExpressionTypeHolder.cpp src\\ExprHandlerRegistry.cpp src\\ExprPrinter.cpp src\\ExtendedDummyParameter.cpp src\\FiniteTypeSet.cpp src\\FloatType.cpp src\\FuncCallHandler.cpp src\\FuncCallScopeEffectsHelper.cpp src\\FunctionHandler.cpp src\\FunctionReflectionAccess.cpp src\\GenericClassStringType.cpp src\\GenericObjectType.cpp src\\GenericStaticType.cpp src\\GetTemplateTypeType.cpp src\\HasMethodType.cpp src\\HasOffsetType.cpp src\\HasOffsetValueType.cpp src\\HasPropertyType.cpp src\\IdenticalNarrowingHelper.cpp src\\IfHandler.cpp src\\ImmediatelyInvokedClosureVisitor.cpp src\\ImplodeArgVisitor.cpp src\\ImpurePoint.cpp src\\IntegerRangeType.cpp src\\IntegerType.cpp src\\InternalEndStatementResult.cpp src\\InternalStatementExitPoint.cpp src\\InternalStatementResult.cpp src\\InternalThrowPoint.cpp src\\IntersectionType.cpp src\\IssetabilityDescriptor.cpp src\\IsSuperTypeOfResult.cpp src\\IterableType.cpp src\\KeyOfType.cpp src\\LateResolvableArrayShapeType.cpp src\\LruCache.cpp src\\MagicConstantParamDefaultVisitor.cpp src\\MethodCallHandler.cpp src\\MethodCallReturnTypeHelper.cpp src\\MethodThrowPointHelper.cpp src\\MixedType.cpp src\\MutatingScope.cpp src\\NativeParameterReflection.cpp src\\NeverType.cpp src\\NewAssignedToPropertyVisitor.cpp src\\NewHandler.cpp src\\NewObjectType.cpp src\\NodeScanner.cpp src\\NodeScopeResolver.cpp src\\NodeTraverser.cpp src\\NonAcceptingNeverType.cpp src\\NonEmptyArrayType.cpp src\\NonexistentParentClassType.cpp src\\NonNullabilityHelper.cpp src\\NopHandler.cpp src\\NullsafePropertyFetchHandler.cpp src\\NullType.cpp src\\ObjectShapeType.cpp src\\ObjectType.cpp src\\ObjectWithoutClassType.cpp src\\OffsetAccessType.cpp src\\OutputBufferHelper.cpp src\\OversizedArrayType.cpp src\\ParametersAcceptorSelector.cpp src\\ParentStmtTypesVisitor.cpp src\\PassedByReference.cpp src\\PharForkGuard.cpp src\\PhpClassReflectionExtension.cpp src\\PhpFileCleaner.cpp src\\PreparedAssignTarget.cpp src\\PropertyFetchHandler.cpp src\\PropertyHookThrowPointsResolver.cpp src\\RecordingNodeCallback.cpp src\\RecursionGuard.cpp src\\ReflectionAccess.cpp src\\ResolvedMethodReflection.cpp src\\ResourceType.cpp src\\ReturnHandler.cpp src\\ScalarHandler.cpp src\\ScopeContext.cpp src\\ScopeOps.cpp src\\Shadow.cpp src\\SimpleImpurePoint.cpp src\\SpecifiedTypes.cpp src\\StatementContext.cpp src\\StatementExitPoint.cpp src\\StatementListWalkState.cpp src\\StatementResult.cpp src\\StatementsHandler.cpp src\\StaticCallHandler.cpp src\\StaticPropertyFetchHandler.cpp src\\StaticType.cpp src\\StaticTypeFactory.cpp src\\StmtHandlerRegistry.cpp src\\StrictMixedType.cpp src\\StringAlwaysAcceptingObjectWithToStringType.cpp src\\StringNeverAcceptingObjectWithToStringType.cpp src\\StringType.cpp src\\SymbolFinderInFiles.cpp src\\TemplateArgumentFrame.cpp src\\TemplateArrayType.cpp src\\TemplateBenevolentUnionType.cpp src\\TemplateBooleanType.cpp src\\TemplateConstantArrayType.cpp src\\TemplateConstantIntegerType.cpp src\\TemplateConstantStringType.cpp src\\TemplateFloatType.cpp src\\TemplateGenericObjectType.cpp src\\TemplateIntegerType.cpp src\\TemplateIntersectionType.cpp src\\TemplateIterableType.cpp src\\TemplateKeyOfType.cpp src\\TemplateMixedType.cpp src\\TemplateNullType.cpp src\\TemplateObjectShapeType.cpp src\\TemplateObjectType.cpp src\\TemplateObjectWithoutClassType.cpp src\\TemplateStrictMixedType.cpp src\\TemplateStringType.cpp src\\TemplateTypeArgumentStrategy.cpp src\\TemplateTypeFactory.cpp src\\TemplateTypeHelper.cpp src\\TemplateTypeMap.cpp src\\TemplateTypeParameterStrategy.cpp src\\TemplateTypeReference.cpp src\\TemplateTypeScope.cpp src\\TemplateTypeVariance.cpp src\\TemplateTypeVarianceMap.cpp src\\TemplateUnionType.cpp src\\ThisType.cpp src\\ThrowPoint.cpp src\\TraitCollectingVisitor.cpp src\\TrinaryLogic.cpp src\\TrustedTypes.cpp src\\TryCatchTypeVisitor.cpp src\\TypeCombinator.cpp src\\TypeCombinatorCache.cpp src\\TypehintHelper.cpp src\\TypeOps.cpp src\\TypeProjectionHelper.cpp src\\TypeResult.cpp src\\TypeSpecifier.cpp src\\TypeSpecifierContext.cpp src\\TypeTraits.cpp src\\TypeTraverser.cpp src\\TypeTraverserInstanceofVisitor.cpp src\\TypeUtils.cpp src\\UnionType.cpp src\\UnionTypeHelper.cpp src\\UnresolvableTypeHelper.cpp src\\UnresolvedTemplateArgumentType.cpp src\\ValueOfType.cpp src\\VarAnnotationProcessor.cpp src\\VariableAccessFlow.cpp src\\VariableControlFlow.cpp src\\VariableFlow.cpp src\\VariableFlowBuilder.cpp src\\VariableHandler.cpp src\\VariableInputFlow.cpp src\\VariableLivenessResolver.cpp src\\VariableSequenceFlow.cpp src\\VerbosityLevel.cpp src\\VoidType.cpp src\\VolatileExpressionHelper.cpp",
"src\\main.cpp src\\support.cpp src\\AbsorbedTemplateArgumentType.cpp src\\AcceptsResult.cpp src\\AccessoryArrayListType.cpp src\\AccessoryDecimalIntegerStringType.cpp src\\AccessoryLiteralStringType.cpp src\\AccessoryLowercaseStringType.cpp src\\AccessoryNonEmptyStringType.cpp src\\AccessoryNonFalsyStringType.cpp src\\AccessoryNumericStringType.cpp src\\AccessoryUppercaseStringType.cpp src\\ArenaCache.cpp src\\ArgsResult.cpp src\\ArgumentsHandler.cpp src\\ArgumentsNormalizer.cpp src\\ArrayDimFetchHandler.cpp src\\ArrayFilterArgVisitor.cpp src\\ArrayFindArgVisitor.cpp src\\ArrayMapArgVisitor.cpp src\\ArrayOffsetNormalizingVisitor.cpp src\\ArrayType.cpp src\\ArrayWalkArgVisitor.cpp src\\ArrowFunctionArgVisitor.cpp src\\AssignHandler.cpp src\\AssignOpHandler.cpp src\\AssignTargetWalkMode.cpp src\\BenevolentUnionType.cpp src\\BlockHandler.cpp src\\BooleanNarrowingHelper.cpp src\\BooleanType.cpp src\\CallableType.cpp src\\CallableTypeHelper.cpp src\\CallbackUnresolvedMethodPrototypeReflection.cpp src\\CallbackUnresolvedPropertyPrototypeReflection.cpp src\\CalledOnTypeUnresolvedMethodPrototypeReflection.cpp src\\CalledOnTypeUnresolvedPropertyPrototypeReflection.cpp src\\ChangedTypeMethodReflection.cpp src\\CircularTypeAliasErrorType.cpp src\\ClassConstantAccessType.cpp src\\ClassLikeHandler.cpp src\\ClassMethodHandler.cpp src\\ClassReflection.cpp src\\ClassStatementsGatherer.cpp src\\ClassStringType.cpp src\\ClosureArgVisitor.cpp src\\ClosureBindArgVisitor.cpp src\\ClosureBindToVarVisitor.cpp src\\ClosureType.cpp src\\CombinationsHelper.cpp src\\ConditionalExpressionHolder.cpp src\\ConditionalExpressionHolderHelper.cpp src\\ConditionalExpressionHolderRecipe.cpp src\\ConditionalType.cpp src\\ConditionalTypeForParameter.cpp src\\ConstantArrayType.cpp src\\ConstantArrayTypeBuilder.cpp src\\ConstantBooleanType.cpp src\\ConstantFloatType.cpp src\\ConstantIntegerType.cpp src\\ConstantStringType.cpp src\\ConstantTypeHelper.cpp src\\CurlSetOptArgVisitor.cpp src\\CurlSetOptArrayArgVisitor.cpp src\\DeclarePositionVisitor.cpp src\\DefaultNarrowingHelper.cpp src\\DisjunctionBranchUnionAugment.cpp src\\DisjunctionHolderProjectionAugment.cpp src\\DummyParameter.cpp src\\DynamicReturnTypeStoragePrimer.cpp src\\EarlyTerminatingCallHelper.cpp src\\EchoHandler.cpp src\\EndStatementResult.cpp src\\Engine.cpp src\\EnumCaseObjectType.cpp src\\ErrorType.cpp src\\ExpressionContext.cpp src\\ExpressionHandler.cpp src\\ExpressionResult.cpp src\\ExpressionResultStorage.cpp src\\ExpressionResultStorageStack.cpp src\\ExpressionTypeHolder.cpp src\\ExprHandlerRegistry.cpp src\\ExprPrinter.cpp src\\ExtendedDummyParameter.cpp src\\FiniteTypeSet.cpp src\\FloatType.cpp src\\FuncCallHandler.cpp src\\FuncCallScopeEffectsHelper.cpp src\\FunctionHandler.cpp src\\FunctionReflectionAccess.cpp src\\GenericClassStringType.cpp src\\GenericObjectType.cpp src\\GenericStaticType.cpp src\\GetTemplateTypeType.cpp src\\HasMethodType.cpp src\\HasOffsetType.cpp src\\HasOffsetValueType.cpp src\\HasPropertyType.cpp src\\IdenticalNarrowingHelper.cpp src\\IfHandler.cpp src\\ImmediatelyInvokedClosureVisitor.cpp src\\ImplodeArgVisitor.cpp src\\ImpurePoint.cpp src\\IntegerRangeType.cpp src\\IntegerType.cpp src\\InternalEndStatementResult.cpp src\\InternalStatementExitPoint.cpp src\\InternalStatementResult.cpp src\\InternalThrowPoint.cpp src\\IntersectionType.cpp src\\IssetabilityDescriptor.cpp src\\IsSuperTypeOfResult.cpp src\\IterableType.cpp src\\KeyOfType.cpp src\\LateResolvableArrayShapeType.cpp src\\LruCache.cpp src\\MagicConstantParamDefaultVisitor.cpp src\\MethodCallHandler.cpp src\\MethodCallReturnTypeHelper.cpp src\\MethodThrowPointHelper.cpp src\\MixedType.cpp src\\MutatingScope.cpp src\\NativeParameterReflection.cpp src\\NeverType.cpp src\\NewAssignedToPropertyVisitor.cpp src\\NewHandler.cpp src\\NewObjectType.cpp src\\NodeScanner.cpp src\\NodeScopeResolver.cpp src\\NodeTraverser.cpp src\\NonAcceptingNeverType.cpp src\\NonEmptyArrayType.cpp src\\NonexistentParentClassType.cpp src\\NonNullabilityHelper.cpp src\\NopHandler.cpp src\\NullsafePropertyFetchHandler.cpp src\\NullType.cpp src\\ObjectShapeType.cpp src\\ObjectType.cpp src\\ObjectWithoutClassType.cpp src\\OffsetAccessType.cpp src\\OutputBufferHelper.cpp src\\OversizedArrayType.cpp src\\ParametersAcceptorSelector.cpp src\\ParentStmtTypesVisitor.cpp src\\PassedByReference.cpp src\\PharForkGuard.cpp src\\PhpClassReflectionExtension.cpp src\\PhpFileCleaner.cpp src\\PreparedAssignTarget.cpp src\\PropertyFetchHandler.cpp src\\PropertyHookThrowPointsResolver.cpp src\\RecordingNodeCallback.cpp src\\RecursionGuard.cpp src\\ReflectionAccess.cpp src\\ResolvedMethodReflection.cpp src\\ResourceType.cpp src\\ReturnHandler.cpp src\\ScalarHandler.cpp src\\ScopeContext.cpp src\\ScopeOps.cpp src\\Shadow.cpp src\\SimpleImpurePoint.cpp src\\SpecifiedTypes.cpp src\\StatementContext.cpp src\\StatementExitPoint.cpp src\\StatementListWalkState.cpp src\\StatementResult.cpp src\\StatementsHandler.cpp src\\StaticCallHandler.cpp src\\StaticPropertyFetchHandler.cpp src\\StaticType.cpp src\\StaticTypeFactory.cpp src\\StmtHandlerRegistry.cpp src\\StrictMixedType.cpp src\\StringAlwaysAcceptingObjectWithToStringType.cpp src\\StringNeverAcceptingObjectWithToStringType.cpp src\\StringType.cpp src\\SymbolFinderInFiles.cpp src\\TemplateArgumentFrame.cpp src\\TemplateArrayType.cpp src\\TemplateBenevolentUnionType.cpp src\\TemplateBooleanType.cpp src\\TemplateConstantArrayType.cpp src\\TemplateConstantIntegerType.cpp src\\TemplateConstantStringType.cpp src\\TemplateFloatType.cpp src\\TemplateGenericObjectType.cpp src\\TemplateIntegerType.cpp src\\TemplateIntersectionType.cpp src\\TemplateIterableType.cpp src\\TemplateKeyOfType.cpp src\\TemplateMixedType.cpp src\\TemplateNullType.cpp src\\TemplateObjectShapeType.cpp src\\TemplateObjectType.cpp src\\TemplateObjectWithoutClassType.cpp src\\TemplateStrictMixedType.cpp src\\TemplateStringType.cpp src\\TemplateTypeArgumentStrategy.cpp src\\TemplateTypeFactory.cpp src\\TemplateTypeHelper.cpp src\\TemplateTypeMap.cpp src\\TemplateTypeParameterStrategy.cpp src\\TemplateTypeReference.cpp src\\TemplateTypeScope.cpp src\\TemplateTypeVariance.cpp src\\TemplateTypeVarianceMap.cpp src\\TemplateUnionType.cpp src\\ThisType.cpp src\\ThrowPoint.cpp src\\TraitCollectingVisitor.cpp src\\TrinaryLogic.cpp src\\TrustedTypes.cpp src\\TryCatchTypeVisitor.cpp src\\TypeCombinator.cpp src\\TypeCombinatorCache.cpp src\\TypehintHelper.cpp src\\TypeOps.cpp src\\TypeProjectionHelper.cpp src\\TypeResult.cpp src\\TypeSpecifier.cpp src\\TypeSpecifierContext.cpp src\\TypeTraits.cpp src\\TypeTraverser.cpp src\\TypeTraverserInstanceofVisitor.cpp src\\TypeUtils.cpp src\\UnionType.cpp src\\UnionTypeHelper.cpp src\\UnresolvableTypeHelper.cpp src\\UnresolvedTemplateArgumentType.cpp src\\ValueOfType.cpp src\\VarAnnotationProcessor.cpp src\\VariableAccessFlow.cpp src\\VariableControlFlow.cpp src\\VariableFlow.cpp src\\VariableFlowBuilder.cpp src\\VariableHandler.cpp src\\VariableInputFlow.cpp src\\VariableLivenessResolver.cpp src\\VariableSequenceFlow.cpp src\\VariableWriteOffset.cpp src\\VerbosityLevel.cpp src\\VoidType.cpp src\\VolatileExpressionHelper.cpp",
true,
flags);
ADD_SOURCES(configure_module_dirname + "/src/parser",
Expand Down
Loading