Releases: phpstan/phpstan
2.2.2
Improvements 🔧
- Narrow
preg_match/preg_match_allsubject string type when match is truthy (#5777), #14710, thanks @staabm and @VincentLanglet! - Resolve per-element callback return types in array_map for closure and arrow function callbacks (#5716), #14649, #11656, thanks @VincentLanglet and @staabm!
- Support union types in str_repeat() (#5784), thanks @staabm!
- Report impossible class_exists/interface_exists/trait_exists/enum_exists (#5754), #14683, thanks @janedbal!
- Narrow variadic parameter array key integer type to
int<0, max>(#5791), #14744, thanks @staabm and @VincentLanglet! - Build an (unsealed) array shape in ArrayType::intersectKeyArray() when the other operand has known sealedness (#5792), #14747
- Resolve
WithoutImpurePointspurity transitively through calls to other effect-free callables (#5798), #14759 - ctype_digit() narrows to decimal-int-string (#5311), thanks @staabm!
- Infer
decimal-int-string/non-decimal-int-stringfor regex capturing groups matching (non-)digits (#5793), #14750, thanks @staabm, @VincentLanglet and @mvorisek! - Infer
decimal-int-stringwhen castingint/int<a, b>tostring(#5794), #14753, thanks @staabm and @VincentLanglet!
Bugfixes 🐛
- Create cross-kind conditional expression holders in
BooleanAnd/BooleanOrtype specifier with truthy fallback forisset()(#5760), #10644, #11918, #3385, #6202, #14455, thanks @VincentLanglet and @staabm! - Fix file path of trait errors reported directly in the trait (#5780), #14718, thanks @janedbal!
- PHPStan should not crash on startup when projects' composer.json is invalid (#5779), #14724, thanks @staabm!
- Narrow array key type when removing
HasOffsetTypeviaArrayType::tryRemove(#5756), #9461, thanks @VincentLanglet and @staabm! - Narrow value type instead of unsetting key in
ConstantArrayType::tryRemoveforHasOffsetValueType(#5776), #14711, thanks @VincentLanglet and @staabm! - Allow reinitialization of a readonly property in __clone since PHP8.3 (#5731), #11495, thanks @grizzm0!
- Omit key type from unsealed ConstantArrayType description when the unsealed extra type is
array-key(phpstan/phpstan-src@49074ec), #14732 - Revert "Return
list<mixed>fromPDOStatement::fetchAll()(#5643)" (#5795), thanks @staabm! - Treat declarations with a non-void
@throwsas not effect-free in theCallTo*StatementWithoutImpurePointsRulefamily (#5802), #14767
Function signature fixes 🤖
- Correct xdebug filename/trace function return types in functionMap to include
false/null(#5788), #14736
Internals 🔍
- Cleanup
instanceof ConstantStringType(#5783), thanks @staabm! - Cleanup
instanceof ConstantScalarType(#5785), thanks @staabm! - Simplify use of
getConstantScalarTypes()togetConstantScalarValues()(#5786), thanks @staabm! - PHPBench: use custom report format (#5789), thanks @staabm!
- Add missing
return(phpstan/phpstan-src@1643f14) - Add regression test (#5797), #14758, thanks @staabm!
2.2.1
Improvements 🔧
- Do not require specifying unsealed extra value type after
...on level 6+ (phpstan/phpstan-src@6ae7aa2)
Bugfixes 🐛
- Do not unpack unsealed array when expanding arguments in FunctionCallParametersCheck (phpstan/phpstan-src@7da57c9), #14715
- Fix constants allowed in parameters for multi-variant functions (phpstan/phpstan-src@4a57953), #14719
Function signature fixes 🤖
- Allow
FILTER_VALIDATE_BOOLas a valid constant forfilter_varandfilter_input(#5778), thanks @aprat84! - Add RoundingMode enum cases as valid constants of
round()(phpstan/phpstan-src@53fe519), #14716 - Fix Collator::setAttribute() allowed constants (phpstan/phpstan-src@f1a3110), #14720
2.2.0
Dive into details about this release on PHPStan's blog: PHPStan 2.2: Unsealed Array Shapes, Safer Array Keys, and More!. It explains all the changes and the motivation behind them.
Major new features 🚀
- Unsealed array shapes (#5501), #13565, #8438, #11494, #12110, #14032
- New types:
decimal-int-stringandnon-decimal-int-string(#5279) - New config parameter:
reportUnsafeArrayStringKeyCasting - Check constants in parameters (#5256), #12850
- New error identifiers:
- Detect named arguments whose parameters are renamed in subtypes (phpstan/phpstan-src@4c1a2b9), #7434, #5279
- New error identifier
argument.parameterRenamedInSubtype
- New error identifier
Bleeding edge 🔪
- Sealed array shapes are truly sealed
- Array shape like
array{a: int, b: string}does not allow for extra keys and does not accept general arrays
- Array shape like
If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:
includes:
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more
Improvements 🔧
- Allow custom rules to emit collector data for CollectedDataNode with CollectedDataEmitter (#5261)
- Reduced false positives about constant conditions in traits (#5309), #13023, #7599, #13474, #13687, #12798, #11949, #12267, #9515, #4570, #4121, #8060, #10353
Bugfixes 🐛
- Narrow division to int when modulo is known to be zero (#5757), #9724, thanks @VincentLanglet and @staabm!
- Do not normalize union types in tryRemove to preserve finite type combinations (#5744), #10128, #11453, thanks @VincentLanglet and @staabm!
- Prevent infinite recursion in
AttributeReflectionFactorywhen an attribute references itself on its constructor (#5773), #14707
Internals 🔍
2.1.56
This is the final send-off for PHPStan 2.1.x series! 👋 This release fixes 31 issues 🎉
PHPStan 2.2.0 will be released this Thursday.
Bleeding edge 🔪
If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:
includes:
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more
Improvements 🔧
- Simulate loop analysis for goto-label pairs (#5701), #14641, #920, #14638, #4674, #7711, #7734, #9904, #11731, #12167
- Add non-ignorable goto-to-undefined-label rule on level 0 (#5701)
- Configuration defined type validation: Improve error message (#5700), thanks @staabm!
- Report abstract method overriding non-abstract method in
OverridingMethodRuleandOverridingPropertyRule(#5730), #14457
Bugfixes 🐛
- Preserve
TemplateTypeinArrayTypeandIntersectionTypearray-mutating methods (#5698), #14633, thanks @staabm and @VincentLanglet! - Do not treat
method_exists()as always true for@method-annotated methods (#5664), #6211, thanks @VincentLanglet and @staabm! - Add implicit throw point for dynamic instantiation of non-final classes without constructors (#5683), #6574, thanks @VincentLanglet and @staabm!
- Do not let conditional expression undo explicit type narrowing (#5710), #14645
- Narrow types after strlen() (#5703), #13688, thanks @staabm and @VincentLanglet!
- Do not use callable parameter types as native types for closure and arrow function parameters (#5632), #11014, #5271, thanks @VincentLanglet and @staabm!
- Handle
gotoandLabelin top-level file statements processed byprocessNodes(#5721), #14660 - Suppress undefined static property error when
property_exists()guard is present (#5544), #2861, thanks @VincentLanglet and @staabm! - Do not create conditional expression when holder and guard have the same type and guard overlaps with other branch (#5724), #14469, thanks @VincentLanglet!
- Retain
class_existsexpression types in closure (#5746), thanks @staabm! - Do not report function_exists as always-true conditions (#5739), #8980, thanks @staabm!
- Code around enum_exists() does not complain about nonexistent classes (#5751), thanks @staabm!
- Check all interfaces instead of only immediate ones for constructor enforcement in
NewStaticRule(#5740), #10274, thanks @VincentLanglet and @staabm! - Process reordered named arguments in call-site order in
processArgs(#5725), #9392, thanks @VincentLanglet and @staabm! - Project
IssetExprcertainty narrowing through ternary-assigned variables via conditional expressions (#5742), #10090, thanks @VincentLanglet and @staabm! - Use similar behavior for always returning never method and sometimes ones (#5747), #7799, thanks @VincentLanglet!
- Only suppress implicit throw point for Throwable-returning calls inside
throwexpressions (#5741), #9826, thanks @VincentLanglet and @staabm! - Recognize promoted property variable usage in constructor body as property usage (phpstan/phpstan-src@1b1b65c), #14703
Performance 🏎️
- Bail to MixedType in deep dim fetch writes on oversized arrays (#5681), #14624, thanks @staabm and @VincentLanglet!
- Prevent nested foreach unrolling to fix exponential blowup (#5732), #14674, thanks @staabm!
Function signature fixes 🤖
- More precise
dirname()return type (#5708), thanks @staabm! - array_count_values accepts only arrays of ints and strings (phpstan/phpstan-src@5521aff)
- Fix PHPRedis hSet/Nx function signatures (#5735), thanks @DKhalil!
- Add precise return types for
RedisArraymethods in function signature map (#5743), #9748, thanks @VincentLanglet and @staabm!
Internals 🔍
- Reflection Golden Tests: Report changes via GitHub Actions annotation (#5697), thanks @staabm!
- Move list-contradiction
NeverTypeout ofunsetOffsetintotryRemove(#5707) - Extract
Type::truncateListToSize()fromTypeSpecifier(#5713) - Improve variable name (#5736), thanks @staabm!
- Cleanup ClassExistsFunctionTypeSpecifyingExtension (#5748), thanks @staabm!
- Test array_key_exists() on subtracted enum (#5749), thanks @staabm!
- Added regression test (#5750), thanks @staabm!
- Cleanup
instanceof ConstantStringTypecalls (#5752, #5753), thanks @staabm!
2.1.55
This release fixes 55 issues! 🎉
Bleeding edge 🔪
- Report invalid
DateIntervalconstructor arguments at analysis time (#5587), #14442, thanks @staabm and @VincentLanglet! - Report impure method overriding pure parent method in
MethodSignatureRule(#5584), #14563, thanks @VincentLanglet and @staabm! - Validate
define()andconstvalues against explicit types indynamicConstantNames(#5648), #14600, thanks @staabm and @VincentLanglet!
If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:
includes:
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more
Improvements 🔧
- Don't report "no value type specified in iterable type array&callable" (#5565), thanks @staabm!
- Resolve method reflection for dynamic static calls (
$var::method()) to enable purity and side-effect checking (#5572), #14557, #5020, thanks @VincentLanglet and @staabm! - Track more expressions (#5596), #12517, #6486, #9155, thanks @VincentLanglet!
- Detect private promoted properties whose only reads are self-writes via
new self()(#5599), #14573 - Report wrong types being passed to
array&callabletype (#5573), #14549, thanks @VincentLanglet and @staabm! - Infer
numeric-stringforDateInterval::format('%a')when interval comes fromdiff()(#5674), #1452, thanks @VincentLanglet and @staabm!
Bugfixes 🐛
- Recurse into parent expression in
IssetCheckandMutatingScope::issetCheckwhen property has propagated error (#5569), #14555 - Fix oversized-array self-rejection in
optimizeConstantArrays(phpstan/phpstan-src@9743346) - Update jetbrains/phpstorm-stubs (#5576), #14559, thanks @bitwise-operators!
- Track
$arr[$key]existence acrossarray_search/array_find_keyvia conditional expression holders (#5552), #14537, thanks @staabm and @VincentLanglet! - Do not narrow array to empty when
array_find_key()returns null (#5693), #14630 - Fix implode losing non-empty-string when ConstantArrayType has all-optional keys (#5578), #14558, thanks @VincentLanglet and @staabm!
- Narrow
DateInterval->daysafterDateTimeInterface->diff()(#5588), #14428, thanks @staabm! - Treat
*as assignment suppression insscanf/fscanfplaceholder counting (#5586), #10260, thanks @staabm and @VincentLanglet! - Do not prefix anything in resources/ when building phpstan.phar (phpstan/phpstan-src@5c28048)
- Walk ancestors for stub method PHPDoc on built-in classes without their own stub entries (#5695), #14632, thanks @staabm!
- Isolate alternation branches in
RegexGroupParser::walkGroupAst()to prevent non-empty/non-falsy state bleeding (#5602), #14575, thanks @staabm and @VincentLanglet! - Widen empty
ConstantArrayTypetoarraywhen resolving dynamic constant types (#5606), #8526, thanks @VincentLanglet and @staabm! - Fix counting
*scanf()format string placeholders (#5594), #14567, thanks @hakre! - Do not report
maybeinRandomIntParametersRulewhen either argument is an unboundedIntegerRangeType(#5622), #14468, thanks @staabm and @VincentLanglet! - Assign proper types for
$argcand$argvinglobalstatements (#5623), #12392, thanks @staabm and @VincentLanglet! - Do not propagate
isAlwaysTerminatingfrom immediately-invoked callable arguments to the outer call (#5604), #14582, thanks @VincentLanglet! - Resolve
ConditionalTypewhen subject-target relationship is deterministic despite containing template types (#5631), #11894, #8048, thanks @VincentLanglet and @staabm! - Return
nullfromArgumentsNormalizer::reorderArgs()when positional args after named args create holes beyond parameter count (#5637), #14596, thanks @staabm and @VincentLanglet! - Collect all remaining callable parameter types for variadic closure parameters instead of using only the matching index (#5634), #9240, thanks @VincentLanglet and @staabm!
- Switch HasMethodType/HasPropertyType from ObjectTypeTrait to MaybeObjectTypeTrait (#5605), #8217, thanks @VincentLanglet and @staabm!
- Augment
BooleanAndfalsey andBooleanOrtruthy type narrowing when left and right conditions narrow different expression keys (#5595), #14566, #13061, #7259, thanks @VincentLanglet! - callable-array intersection type is a constant array (#5647)
- Fix infinite recursion in specifyTypesForCountFuncCall with mixed TypeSpecifierContext (#5653), #14605
- Do not report
non-falsy-string == 0as always false inAccessoryNonFalsyStringType::looseCompare()(#5654), #14606, thanks @VincentLanglet and @staabm! - Prevent creation of IntersectionType with just HasOffsetValueType accessories (phpstan/phpstan-src@fa4e7d2), #14604
- Prevent issue with accessory-only IntersectionType (phpstan/phpstan-src@f2af15b)
- Re-check scalar types after integer range expansion in
TypeCombinator::union(#5660), #14610, thanks @staabm and @VincentLanglet! - Respect
@throws voidongetIterator()when determining foreach Traversable throw points (#5666), #6833, thanks @staabm and @VincentLanglet! - Check inner union types before delegating to
isSubTypeOfforLateResolvableTypeinUnionType::isSuperTypeOf()(#5645), #10942, thanks @staabm and @VincentLanglet! - Use pre-args scope for value types in array_push/array_unshift (#5579), #13510, thanks @predictor2718!
- Use before-scope for evaluating
array_spliceargument types (#5682), #13510, thanks @VincentLanglet and @staabm! - Fix: property.notFound in chained isset() with checkDynamicProperties (#5562), #13539, thanks @predictor2718!
- Invalidate property types after dynamic method calls (#5679), #3831, thanks @VincentLanglet and @staabm!
- Skip class name case check for type hints using explicit
use ... asaliases (#5671), #14617, thanks @VincentLanglet and @staabm! - Skip non-discriminating guards in
createConditionalExpressionseven when target is not tracked in the other scope (#5676), #14595, thanks @staabm and @VincentLanglet! - Preserve
TemplateTypeinIntersectionType::shuffleArray()when intersection is already a list (#5694), #14631 - Fix another shuffle() variant (#5696), thanks @staabm!
Performance 🏎️
- Lazily initialize AggregateSourceLocator to speedup bootstrapping (#5577), thanks @staabm!
- PhpFileCleaner: Use strcspn instead of regex for fast-skip in clean() (#5600), thanks @staabm!
- Cap cumulative unroll factor when nesting unrolled constant-array foreach (#5614), #14590
- DateFunctionReturnTypeHelper: prevent unnecessary
TypeCombinator::union()(#5629), thanks @staabm! - Memoize
ArrayType::isList()(#5680), thanks @staabm!
Function signature fixes 🤖
- Fix #14499: Mark Lua::__construct $lua_script_file parameter as optional (#5571), #14499, thanks @predictor2718!
- More concrete return type for
opcache_get_configuration([#5424](https:...
2.1.54
Improvements 🔧
- Improve DateInterval inference (#5486), #14479, thanks @VincentLanglet!
- Next autoindexes can be empty and setOffsetValueType with null offsetType returns ErrorType (phpstan/phpstan-src@5e793f7)
Bugfixes 🐛
- Process unrolled foreach iteration body in original context to let nested loops stabilize (#5559), #9332, #14543
- Preserve conditional expressions in
invalidateExpressionwhenrequireMoreCharactersis true (#5560), #14545 - Recognize
[$obj, $method]as callable whenis_callable($obj, $method)is known true in scope (#5547), #4510, thanks @VincentLanglet and @staabm! - Replace instead of union when writing to optional keys via union offset in
ConstantArrayTypeBuilder(#5566), #14551 - Check
isFirstClassCallable()before callinggetArgs()on nestedFuncCallnodes (#5564), #14550, thanks @staabm and @VincentLanglet! - Preserve non-empty array guarantee in
ConstantArrayType::setOffsetValueTypewhen union key expansion produces all-optional keys (#5567), #14552, #14553
Performance 🏎️
- Cache methods in IntersectionType (phpstan/phpstan-src@c161e9f)
2.1.53
2.1.52
This release fixes 45 issues! 🎉
Improvements 🔧
- Emit virtual
Assignnode forList_destructuring inforeachvalue position (#5504), #8075 - Narrow array key type after type-checking the key variable inside a
foreachloop (#5505), #7076 - Support for
static::SOME_CONSTin PHPDoc (#5510), #13828, thanks @VincentLanglet! - Allow GMP in increment/decrement operations (#5530), thanks @Firehed!
Bugfixes 🐛
- Various array fixes (#5523), #7893, #2294, #14448, #11146, #11533, #13699, #13623, #13304, #12653, #3795, #14336, #11820, #13000, #13643, #13272, #13663, #10349, #8648
- Preserve constant array when assigning a union of scalars
- Preserve tracked nested ArrayDimFetch types through chained assignments
- More precise analysis for foreach iterating over constant array
- Resolve
ConditionalTypeForParameterchildren before converting toConditionalTypeto prevent infinite traversal (#5507), #13872 - Merge scope after
?->method call to account for argument short-circuiting (#5456), #10729, thanks @VincentLanglet and @staabm! - Track PHPDoc and modifier flags on
ExportedParameterNodefor result cache invalidation (#5518), #14520 - Autoloading should not be invoked for any string (#5519), #14514, #14511, thanks @staabm!
- More precise tracking
$valuein foreach (#5526) - Correctly mark all unpacked constant array items as optional in
array_merge/array_replace(#5525), #14526 - Fix: False positive: Conditional return type takes the wrong branch (#5362), #11565, thanks @VincentLanglet and @staabm!
- Fix: Allow readonly property init in child classes on PHP 8.4+ (#5513), #12871, thanks @predictor2718!
- Project narrowings through stored booleans for more expression kinds (#5528), #9455, #5207
- Track array_walk by-ref closure parameter modifications on array type (#5527), #14525
- Merge conditional-expression holders for the same target (#5529), #12677
- Project stored-boolean narrowings through
||truthy, Track destructure relationships across tagged-union foreach (#5531), #9519 - Fix: Template of imported type breaks imported type (#5360), #11314, #7152, #13332, thanks @VincentLanglet and @staabm!
- Track
$arr[$key]existence acrossarray_key_first/last+!== null(#5537) - Preserve TemplateArrayType across offset writes and traversal (#5553), #10749
- Two-stage collapse for oversized constant arrays (#5555), #8636
- Fix callable array intersection type offset narrowing (#5548), #3842, thanks @VincentLanglet and @staabm!
Performance 🏎️
- Cache class constant fetch type (phpstan/phpstan-src@a8704ac)
Function signature fixes 🤖
- Make bcround pure (#5499), thanks @still-dreaming-1!
- Make bcfloor, bcceil pure (#5509), thanks @staabm!
- Declare multiple apcu_ functions as impure (#5516), #14519, thanks @madmajestro!
- Declare Memcached methods as impure (#5536), #13444, #14534, thanks @VincentLanglet!
Internals 🔍
- BenchCase - enable Bleeding Edge (phpstan/phpstan-src@99c018e)
- Revert fix (#5520), thanks @staabm!
- Fix PHPUnit warnings (#5522), thanks @staabm!
- Add non regression test (#5540), #2940, thanks @VincentLanglet!
- Add non regression test (#5545), #4352, thanks @VincentLanglet!
2.1.51
Improvements 🔧
Bugfixes 🐛
- Fix ReflectionGetAttributesMethodReturnTypeExtension for UnionTypes (#5463), #14466, thanks @VincentLanglet and @staabm!
- Fix ErrorType leaking from array_key_exists with union key types in loops (#5487), #14489, thanks @VincentLanglet and @staabm!
- Fix infinite loop on recursive trait (#5488), thanks @samsonasik!
- Do not re-wrap
NeverTypeasTemplateMixedTypeinTemplateUnionType::filterTypes()(#5500), #14504 - Read class-constant
@vartype without triggering@extendsresolution (#5502), #14501
Internals 🔍
- Improve
UnionType::accepts()(phpstan/phpstan-src@5cfa80a)
2.1.50
Bugfixes 🐛
- Fix broken type narrowing with larger union types (phpstan/phpstan-src@77a3244), #14484
Function signature fixes 🤖
- Declare multiple mysqli_ functions as impure (#5481), #14473, thanks @VincentLanglet and @staabm!