Releases: phpstan/phpstan
2.1.47
Major new features 🚀
bisectcommand (#5431), #14443- Find the first PHPStan commit that introduced a regression
- This command performs a binary search over PHPStan releases, similar to
git bisect - Learn more »
Improvements 🔧
- Detect more AI agents (#5375), thanks @staabm!
- Add hint in VarTagTypeRuleHelper (#5400), thanks @VincentLanglet!
- Implement GMP operator type specifying extension (#5223), #14288, thanks @Firehed!
- Respect sys_temp_dir from the parent process (#5390), #14093, thanks @theodorejb!
- Update Symfony polyfills (phpstan/phpstan-src@9c3b62d)
Bugfixes 🐛
- Fix: !in_array with enum values incorrectly narrows to NEVER (#5365), #14407, #13421, #8864, thanks @VincentLanglet and @staabm!
- Fix: PHPStan assumes string conversions cannot throw exceptions (#5391), #13806, thanks @VincentLanglet and @staabm!
- Fix ObjectType::equals (#5399), #3028, #14429, #5298, thanks @VincentLanglet!
- Fix: Two unbounded generics in conditional return are assumed to be always the same (#5336), #11430, thanks @VincentLanglet and @staabm!
- Fix: \settype() is not handled properly (#5404), #3250, thanks @VincentLanglet and @staabm!
- Fix: Call to function is_callable() with array{...} will always evaluate to true (#5409), #12063, #4608, thanks @VincentLanglet and @staabm!
- Fix: Allow throwing exceptions from __toString() not detected since level 4 (#5405), #5952, thanks @VincentLanglet and @staabm!
- Fix: Adding elements to empty array in
whileloop does not result in array being recognized as potentially non-empty forin_array(#5419), #13705, thanks @VincentLanglet and @staabm! - Fix: Ordering of Intersections matters for method calls, first matching wins (#5408), #11978, thanks @VincentLanglet and @staabm!
- Fix: Nullsafe operator chaining (#5407), #11073, thanks @VincentLanglet and @staabm!
- exit function is not internal, change isInternal method to return 'No' (#5420), thanks @spaze!
- Fix infinite recursion in ConstantArrayType::isCallable() via RecursionGuard (#5423), thanks @MizouziE!
- Fix infinite loop (#5426), #14439, #4957, thanks @staabm and @VincentLanglet!
- Preload polyfills in the PHAR (#5436), #14432
- Update BetterReflection to 6.70.0 (phpstan/phpstan-src#5429)
- Fixes: Readonly property modification through clone() is not reported outside allowed scope (#5432), #14063, thanks @VincentLanglet and @staabm!
- Support for covariant templates in interface properties in 8.4 (#5415), #12964, thanks @VincentLanglet and @staabm!
- Fix incorrect type-narrowing when using strict rules (#5435), #14446, thanks @VincentLanglet and @staabm!
- Do not report generic covariant issue without strict check (#5437), thanks @VincentLanglet!
- Fix: Conditional argument type not properly narrowing type (#5386), #10055, #13591, #12597, #10422, #6663, #4090, #11218, thanks @VincentLanglet and @staabm!
Performance 🏎️
- TypeCombinator::union optimization in case of many
*NEVER*(#5374), thanks @SanderMuller! - Do fast check first (#5396), thanks @VincentLanglet!
- List the most-often-analysed trait files in
-vvv(#5395), #14073, thanks @VincentLanglet and @staabm! - Fix performance degradation introduced in 2.1.41 (#5441), #14452, thanks @VincentLanglet!
Internals 🔍
- TypeCombinator: Remove always true condition (#5383), thanks @staabm!
- Prevent duplicate argument re-normalizing (#5393), thanks @staabm!
- Add authors section in composer.json (#5389), thanks @VincentLanglet!
- Added regression test (#5425), #8835, thanks @staabm!
- Upgrade Dead Code Detector to 1.0.0 (#5430), thanks @janedbal!
- Add non regression test (#5442), thanks @VincentLanglet!
- Fix non regression test (#5444), thanks @VincentLanglet!
- Remove wrong specification (#5445), thanks @VincentLanglet!
- bisect: advertise gzip,deflate encoding when supported (#5434), thanks @staabm!
2.1.46
Improvements 🔧
- Properly union HasOffsetValueType in huge intersections describing the same offsets (phpstan/phpstan-src@429723d)
Bugfixes 🐛
- Fix sealed class-string match exhaustiveness for ::class comparisons (#5305), #12241, thanks @mhert!
- Fix sealed class-string match exhaustiveness for generic sealed hierarchies (#5369), #14412
- Fix incorrect type narrowing with dependent types (#5373), #14411, #11328, #10085, #14211, thanks @VincentLanglet and @staabm!
- Fix false positive contravariant parameter with nested trait (#5244), #14320
- Properly preserve TemplateConstantArrayType (phpstan/phpstan-src@c71be49), #12355, #9828
Performance 🏎️
TypeCombinator::unionoptimizations (#5325), thanks @SanderMuller!
2.1.45
This release fixes 29 issues!
In other news, we refreshed the on-line playground! You can now set many previously-unavailable config parameters:
This helps you testing out various PHPStan features, and also reproduce issues for bug reports when something goes wrong with these parameters set to their non-default values.
Also, there's a couple of new blogposts on the website:
Improvements 🔧
- More rules about PHPDoc tags declarations now validate stub files (phpstan/phpstan-src@610537a)
Bugfixes 🐛
- Fix: errors for argument array template types no longer reported (argument.type) (#5300), #14138, thanks @VincentLanglet and @staabm!
- Fix: Result of
function_exists()can't be "cached" (#5303), #14384, thanks @staabm and @VincentLanglet! - Fix: Optional templated args not provided cause unbound template errors (#5175), #2572, #7704, #9360, thanks @staabm and @VincentLanglet!
- Resolve generic parameter defaults that reference other template parameters (#5304), thanks @JanTvrdik!
- Fix: array_filter with assert-if-true callable marks all keys optional (#5097), #11730, thanks @staabm and @VincentLanglet!
- Fix: assign.readOnlyProperty (#5061), #12253, thanks @VincentLanglet and @staabm!
- Fix: Bogus write-only error when appending to an array-like object in private class property (#5102), #6777, thanks @VincentLanglet and @staabm!
- Fix: Cannot use "T is never" in conditional return (#5082), #9634, #10938, thanks @VincentLanglet and @staabm!
- Fix: [NAN] === mixed is always evaluated as false (#5321), #11054, thanks @staabm and @VincentLanglet!
- Fix: Parameter #2 $callback of function uasort expects callable(Foo, Foo): int, 'strnatcasecmp' given. (#5171), #11619, thanks @VincentLanglet and @staabm!
- Fix: Does not warn about non-nullable class-property (#5327), #14393, #4846, thanks @VincentLanglet and @staabm!
- Fix: Incorrect inference of instance variable modified from callback (#5347), #8926, #11417, #10903, thanks @staabm and @VincentLanglet!
- TypeSpecifier: resolve purity/impurity for CallableParametersAcceptor (#5348), #12686, #3770, #6822, thanks @staabm and @VincentLanglet!
- filter_var: Fix throw on failure with require/force array (#5349), thanks @VincentLanglet!
- Fix: FILTER_FLAG_GLOBAL_RANGE constant not "known" on PHP 8.3, 8.4 (#5334), #14397, thanks @VincentLanglet and @staabm!
- Fix: Narrowed template on an interface is ignored when generics is not specified (#5339), #9045, #7185, #13204, thanks @VincentLanglet and @staabm!
- Fix: Consequent scope with the same condition (#5056), #4173, #12992, #14227, thanks @VincentLanglet and @staabm!
Performance 🏎️
- Flatten deep BooleanOr chains in TypeSpecifier to avoid O(n^2) recursion (#5324), thanks @SanderMuller!
Internals 🔍
- More named arguments (phpstan/phpstan-src@38036bf)
- Simplify StubValidator rule list, introduce
#[ValidatesStubFiles]attribute (phpstan/phpstan-src@b9839ac) - StubValidator - call StubFilesProvider on the original DIC, not on the stubValidator one (phpstan/phpstan-src@47f36d8)
- Added regression test (#5306), #10924, thanks @staabm!
- Added regression test (#5313), #4918, thanks @staabm!
2.1.44
Bugfixes 🐛
- Docker images builds are working again (2.1.41 – 2.1.43 are missing, sorry)
- Docker images are now built for PHP 8.5 too
- Display the correct number of processes used, when using
--debug(#5294), #14342, thanks @esthezia! - Fix: Intersection loses
__invoke()return type (#5291), #14362, thanks @VincentLanglet and @staabm! - Fix: Null coalescing assignment operator combined with throwing (#5297), #14369, thanks @VincentLanglet and @staabm!
- Fix method call on unioned class type analysis is broken (#5225), #11687, #12562, #14203, thanks @VincentLanglet!
2.1.43
Another week, 37 issues crushed!
Improvements 🔧
- Call operator type specifying extensions for bitwise and arithmetic operators (#5226), thanks @Firehed!
- Introduce UnaryOperatorTypeSpecifyingExtension interface (#5284), thanks @Firehed!
- Report
trait.duplicateMethod(#5181), #14250, thanks @VincentLanglet and @staabm! - Cannot re-assign superglobal variable in parameters (#5153), #14241, thanks @VincentLanglet and @staabm!
- Prevent PHP error "Fatal error: Cannot re-assign $this" with a new rule (#5276), #14349
- Implement more missing errors arround use of
$this(#5278), #14351, thanks @staabm! - Infer
non-empty-list/arrayafterisset($arr[$i])(#4441), #13674, #12482, #13675, thanks @staabm! - Support call_user_func_array (#5286), #5942, #5934, thanks @VincentLanglet!
Bugfixes 🐛
- Fix: Offset 0 should not be optional on non empty list (#5236), #14308, thanks @VincentLanglet and @staabm!
- Narrow
DOMDocument::createElement()return type and throw type for valid constant names (#5192), #13792, thanks @janedbal! - Fix: Parameter
#2of array_key_exists expects array, non-empty-array given (#5237), #14312, thanks @staabm and @VincentLanglet! - Fix: Failed Determine type in match operator (#5066), #9601, thanks @VincentLanglet and @staabm!
- Fix: Throw point are not properly recognized (#5166), #9349, thanks @VincentLanglet and @staabm!
- Fix: Anonymous class causes "variable might not be defined" issue (#5205), #13920, thanks @VincentLanglet and @staabm!
- Fix: False positive variable might not be defined (#5240), #14318, thanks @VincentLanglet and @staabm!
- Fix: "Cannot use [] for reading." false positives (#5059), #5290, thanks @VincentLanglet and @staabm!
- Fix: Weird variable might not be defined behavior (#5245), #14323, thanks @VincentLanglet and @staabm!
- Fix: Foreach on constant array with closures reaching 32 entries causes crash (#5246), #14324, thanks @staabm and @VincentLanglet!
- Fix fatal error when
pathhas array value in ignoreErrors (#5183), #14231, thanks @janedbal! - Fix: Unreachable statement information gets lost (#5253), #14328, thanks @VincentLanglet and @staabm!
- Fix: Variable passed by reference are not updated (#5217), #14275, #8056, thanks @VincentLanglet and @staabm!
- Fix incorrect narrowing of nested array after assignment (#5258), #13857, #10089, thanks @staabm!
- Fix: incorrect type-narrowing to
*NEVER*inside array row (#5263), #13786, thanks @staabm and @VincentLanglet! - array_column should not extract non-public properties from objects (#5210), #13573, thanks @janedbal!
- Fix "Parameter X of array_values is already a list, call has no effect"-false positive (#5271), #13629, thanks @staabm!
- Fix: strange behavior on regex capture groups (#5239), #14314, thanks @VincentLanglet!
- Fix: Enum case outside of enum should be reported (#5188), #14252, thanks @staabm and @VincentLanglet!
- Fix identifier being red (phpstan/phpstan-src@7859ab8)
- Fix: TemplateIntersectionType is lost inside TypeCombinator::intersect (#5275), #14348, #9961, #13577, thanks @staabm and @VincentLanglet!
- Fix: Setting an array key doesn't update a reference (#5257), #14333, thanks @VincentLanglet and @staabm!
- Fix infinite loop in recursive generics (#5288), #13801, thanks @staabm!
Performance 🏎️
- IntersectionType: Prevent duplicate work in isOffsetAccessible() (#5243), #14319, thanks @staabm!
- Fix: PHPStan takes extremely long analyzing if-offset checks on
array|object(#5242), #14319, thanks @staabm and @VincentLanglet!
Function signature fixes 🤖
Internals 🔍
- Makefile: added phpbench target (#5250), thanks @staabm!
- Simplify PHPBench make-target (#5251), thanks @staabm!
- Add non regression test (#5252), thanks @VincentLanglet!
- Added non-regression test (#5260), thanks @staabm!
- Remove unnecessary negation (#5262), thanks @staabm!
- PHPBench: force ansi colors in github actions (#5274), thanks @staabm!
- Simplify AccessoryNumericStringType (phpstan/phpstan-src@0183699)
- InvalidVariableAssignRule: test null coalesce assign (#5277), thanks @staabm!
2.1.42
Fix #14305: Internal error crash report (phpstan/phpstan-src#5231), thanks @staabm and @VincentLanglet!
2.1.41
Just three weeks after PHPStan 2.1.40, this release fixes whopping 87 issues! 🎉
Major new features 🚀
- Main documentation page on phpstan.org is now a dashboard linking the most common problem-solving pages
- All error identifiers reported by PHPStan now have comprehensive documentation.
- Each page shows a code example reporting the error
- Followed by an explanation why is it reported
- And showing one or more ways how to fix it
- Several awesome examples:
ternary.resultUnused,property.onlyRead,return.void
- Documentation about custom extensions now documents all previously-undocumented extension types
Improvements 🔧
- Add option
reportIgnoresWithoutCommentsto report ignores without comments (#5032), #11340, thanks @calebdw!- This disables
@phpstan-ignorewithout comments in parentheses - It also disables
@phpstan-ignore-lineand@phpstan-ignore-next-linecompletely - See: https://phpstan.org/config-reference#reportignoreswithoutcomments
- This disables
- Tuned how many CPU cores PHPStan uses by default:
- Diminishing returns beyond 8 CPU cores (phpstan/phpstan-src@23928d9)
- Different method to compute CPU cores to use (phpstan/phpstan-src@89f1382), #11410, #7479
- See docs: https://phpstan.org/config-reference#parallel-processing
- Solve various HTTP proxy and custom root CA errors when downloading PHPStan Pro
- Use plain old Guzzle and system CA (phpstan/phpstan-src@a3af1cd), #12486, #11244
- Report invalid printf placeholder (#4478), #1889, #8547, thanks @VincentLanglet!
- Respect rule level in ParameterCastableToNumberRule (#4873), thanks @VincentLanglet!
- Report non existent offset on non empty array (#4399), #7143, thanks @VincentLanglet!
- TableErrorFormatter - always show identifier, even if non-ignorable (phpstan/phpstan-src@d64ce37)
- Show instructions to coding agent about how to handle errors (phpstan/phpstan-src@bb42c9f)
- Tip about adding
@phpstan-impurewhere applicable (#5031), #14183 - Report error when trying to instantiate a trait with new (#5182)
Bugfixes 🐛
- Fix createConditionalExpressions (phpstan/phpstan-src@3993c52), #14191
- Differentiate signaturePrototype and inheritancePrototype (#4945), #11067, #12830, #12272, thanks @VincentLanglet!
- Avoid false error on is_subclass_of (#4472), #13713, thanks @VincentLanglet!
- Fix execution branch confusion (#5058), #5051, #9647, thanks @staabm and @VincentLanglet!
- Fix spurious error in specific combination of namespace blocks and function declaration with phpdoc type annotation (#5077), #13831, thanks @VincentLanglet!
- Fix SimplXmlElement and GMP casts (#5020), #14136, thanks @VincentLanglet!
- Fix: False match.unhandled on array with multiple booleans (#5107), #13029, thanks @VincentLanglet and @staabm!
- Fix seemingly same type reports as invalid/incompatible. (#5094), #13440, #12688, thanks @VincentLanglet!
- Fix:
$this(Type~Subtracted)does not work on conditional return type asType~Subtracted(#5104), #12244, thanks @staabm and @VincentLanglet! - Fix: False positive with array_key_exists and union types (#5114), #13526, thanks @staabm!
- Fix: Nonexistent offset detection on lists
if ($index < count($array))(#5090), #13770, thanks @VincentLanglet and @staabm! - Fix: Defining Array Constants in PHP Traits Causes Errors When Using Class Constants as Keys or Values (#5115), #11351, #11088, thanks @VincentLanglet!
- Fix: Generator suspension points should be treated as infinite loop break points (#5057), #6189, #10054, thanks @VincentLanglet and @staabm!
- Fix: BenevolentUnionType with generics produce confusing errors (#5070), #9732, thanks @staabm and @VincentLanglet!
- Fix while-true-if-break: Variable might not be defined (#5118), #11545, #10245, #11984, #5477, #5919, #9023, thanks @VincentLanglet!
- Fix: False positive staticMethod.impossibleType (#5121), #13566, #10337, thanks @staabm and @VincentLanglet!
- Fix: Variable $ in empty() always exists and is not falsy. (#5124), #14223, thanks @VincentLanglet and @staabm!
- Fix: Incorrect 'Variable $value might not be defined.' (#5125), #14117, #8430, #10657, thanks @VincentLanglet and @staabm!
- Fix: Assignment inside match statement no longer recognized (#5120), #13981, thanks @staabm!
- Fix: Incorrect: Class referenced with incorrect case, (#5064), #14205, thanks @staabm and @VincentLanglet!
- Fix offset might not exist false-positives (#5137), #14234, #14215, thanks @VincentLanglet!
- Consider ArrayAccess side effects for dead catch analysis (#5117), #11427, thanks @VincentLanglet!
- Fix: false positive on
in_array(...)check with impure second argument (#5141), #13799, thanks @VincentLanglet and @staabm! - Fix: Spreading an associative array into a generic function/method call may restrict optional arguments to their default values. (#5079), #12363, #8257, #7369, thanks @VincentLanglet and @staabm!
- Fix:
array_spliceresets int keys of the input array (#5139), #14037, thanks @staabm and @VincentLanglet! - Fix:
iterableis equal toarray|Traversable(#5144), #13247, thanks @staabm and @VincentLanglet! - Fix: Reassignment of $this is not an error (#5146), #3585, thanks @staabm!
- Fix spurious error nullCoalesce.offset (#5145), #13921, thanks @staabm!
- Support
chop()function as an alias ofrtrim()(#5157), thanks @zonuexe! - Fix: Assignment in a key of array destructuring is ignored (#5164), #14019, thanks @staabm and @VincentLanglet!
- Support sizeof() alias in addition to count() (#5179), thanks @staabm!
- TableErrorFormatter: Limit number of errors (#5136), thanks @staabm!
- Fix: list lost after overwriting last element (#5169), #14245, thanks @VincentLanglet and @staabm!
- Improve intersection of ConstantArray and AccessoryIsList (#5067), thanks @VincentLanglet!
- Fix list description with offset required (#5212), thanks @VincentLanglet!
- Fix: crash on first class callable as conditional do while (#5194), #12246, thanks @staabm and @VincentLanglet!
- Fix maybe-undefined variable regression in loops with unrelated assignments (#5208), #14269, #4284
- Fix regression: regex matches after checking non-empty array (#5209), #14270, #12397, thanks @staabm!
- Propagate
@phpstan-assert-*annotations to First-class callables (Closures) and string callables (#5201), #14249, thanks @staabm! - Fix: non-negative-int evaluated to int (#5176), #12163, thanks @staabm and @VincentLanglet!
- Fix: Error „should return static(Test) but returns Test“ (#5190), #4860, thanks @VincentLanglet!
- Fix: PHPDoc types from overridden function are not included in trait typeinfo when aliased (#5204), #9733, thanks @VincentLanglet!
- Fix: Index for loop inference should only work in lists ([#521...
1.12.33
Suggest to coding agents that PHPStan 2.x is available to upgrade to from 1.12.x (phpstan/phpstan-src@8c66d82)
2.1.40
This release fixes 71 issues! 🎉
It's only been 12 days since the last release, but both @staabm and @VincentLanglet have been hard at work. For the first time ever, PHPStan has more people with merge rights aside from @ondrejmirtes, and the increase in productivity is awesome!
Improvements 🔧
- Introduce
rawMessageskey in ignoreErrors (#4929), thanks @VincentLanglet! - Infer non-empty-ness after
count($a) == count($b)(#4470), thanks @staabm! - Report class.nameCase error when the wrong case is just in return type (#4890), #11470
- Allow ternary type narrowing in assert and truthy contexts (#4915), #14100
- Add
ClassConstantReflection::isFinalByKeyword()method (#5022), #14171, thanks @samsonasik!
Bugfixes 🐛
- Fix
GMP::toNumber(#4867), #12123, #13775, thanks @VincentLanglet! - Respect original variable type when using extract on optional keys (#4450), #12364, thanks @VincentLanglet!
- Fix: Switch statement does not narrow down types based on branch conditions (#4879), #13211
- Fix: Possible type loss when binding variables with 'use' in anonymous function (#4882), #12875
- Fix: Calling ReflectionClass::isSubclassOf() multiple times doesn't narrow types correctly in 8.4 (#4883), #13783
- Fix: False positive error for 'match' operator (#4888), #5191
- Fix: Variadic arrow function argument triggers "Cannot access offset 0 on mixed" and related errors (#4887), #10671
- Fix: Existing function used in Closure::bind leads to "Call to an undefined method" error (#4886), #4865
- Fix: Loadable classes not recognized since 2.1.34 release (#4891), #14036, #14099, thanks @staabm!
- Fix invokable objects incorrectly labeled as instances of
Closure(#4797), #13975, thanks @HypeMC! - Fix: match.unhandled on multiple booleans (#4881), #13303, #11903, #7008, thanks @staabm!
- Preserve HasOffsetValueType for constant array spreads in degraded array literals (#4897), #13805
- Don't invalidate private property expressions of different classes (#4896), #13736, #6623
- Fix match exhaustiveness for class-string with union of final classes (#4894), #9534, #12998
- Allow passing return values of by-reference functions/methods as by-ref args (#4895), #757, #13711
- Downgrade $this to static when calling methods on static type (#4902), #5946
- Fix
@phpstan-assertnot working with union types (#4900), #11441, #13358, thanks @staabm! - Fix: Unnecessary nullsafe operator reported on nullable array index(#4889), #12222
- Revert "Respect sys_get_temp_dir() from the parent process" (phpstan/phpstan-src@dd0ab39), #14093
- Fix incorrect type with spread of array with optional named keys (#4908), #14097
- Fix array_count_values key type for general string input (#4909), #13996, thanks @VincentLanglet!
- Fix
@phpstan-assertnot working correctly with union types (#4920), #14108, thanks @staabm! - Fix
list<mixed>becomesarray<int<0, max>, mixed>without array keys being modified (#4933), #13809, #1311, #13851, #14083, #14084 - Fix: Reassigning to
array<string, list<T>>out parameter does not see thelist<T>property during assignment (#5006), #14124, thanks @staabm! - Improve count on list with greater/smaller-than (#4507), #13747, thanks @staabm!
- Fix array + array inference (#4944), #13561, thanks @VincentLanglet!
- Fix BcMath\Number increment/decrement (#4957), thanks @mpesari!
- Fix: Method call phpstan error is reported on wrong line (#4967), #9820, thanks @staabm and @VincentLanglet!
- Fix error reported on the wrong line (#4991), #14150, thanks @VincentLanglet!
- Fix TypeError dead catch when assigning mixed to int in property (#4981), #9146, thanks @staabm!
- Filter less expression types (#4937), #13984, thanks @VincentLanglet!
- Fix false positive dead catch for ReflectionMethod::invoke/invokeArgs (#4985), #7719, #9267, thanks @staabm!
- Filter unsupported OpenSSL cipher methods on PHP 8.0-8.4 (#4982), #13692, thanks @VincentLanglet!
- Fix: Erroneous Offset might not exist (#4988), #12574, #10040, #11102, #11870, #6991, #7716, thanks @staabm!
- Use "Ignored error" instead of "Ignored error pattern" when rawMessage is used (#4990), thanks @janedbal!
- Fix isset() falsey branch not narrowing array type for dim fetches (#4983), #9908, #10544, #8724, #5128, #12401, thanks @VincentLanglet!
- More precise array_key_first/array_key_last inference (#4994), thanks @staabm!
- Specify conditional types for all falsey scalars (#4995), #6120, #10482, #13709, thanks @staabm!
- Add similar behavior for all Assign nodes (#4996), #12250, #4525, thanks @VincentLanglet!
- Fix: Using phpstan-import-type between classes makes alias unresolvable (#4997), #11463, thanks @staabm!
- Remove callable.nonNativeMethod (#5004), #13596, thanks @VincentLanglet!
- Fix: False Positive on Match Arm Comparison with Incremented Bounded Integer (#5003), #11310, thanks @VincentLanglet!
- Fix scope for MatchExpressionNode (phpstan/phpstan-src@7b850e4)
- Fix match regressions (phpstan/phpstan-src@87004e7, phpstan/phpstan-src@4628ff9)
- Fix conditional expression holder chain resolution regression (#5025), #14178
- Fix
get_classreturn type (#4456), #4890, thanks @VincentLanglet! - Unsetting optional offset might still give a list (#5029), #14177, thanks @VincentLanglet!
Performance 🏎️
- Faster NetteContainer (#4921), thanks @staabm!
- MutatingScope: prevent unnecessary work in removeTypeFromExpression() (#4922), thanks @staabm!
- Don't invalidate container cache on user-interactions in the shell (#4924), thanks @staabm!
- Prevent duplicate path normalization (#4931), thanks @staabm!
- DependencyResolver: Reduce duplicate work (#4923), thanks @staabm!
- speed up TrinaryLogic (#4833), thanks @kaja47!
- ClassNameCheck: Retrieve extensions just once (#4926, #5027), thanks @staabm!
- IsSuperTypeOfResult: cache YES/NO/MAYBE (#5011), thanks @staabm!
- Faster
IntersectionTypeMethodReflection->getVariants()(#5012), thanks @staabm! - ArgumentsNormalizer: remove duplicated work (#5010), thanks @staabm!
- Faster AcceptsResult, IsSuperTypeOfResult (#5013), thanks @staabm!
- TypeSpecifier: Prevent duplicate expression printing (#5018), thanks @staabm!
- Faster Ternary analysis (#5015), thanks @staabm!
Function signature fixes 🤖
2.1.39
Bleeding edge 🔪
- Require generics for Iterator, IteratorAggregate, Generator (#4209), thanks @Flyingmana!
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 🔧
- New rule for
filter_var(PHP 8.5+) (#4553), thanks @canvural! - Introduce
reportNonIntStringArrayKeyparameter (#4012), #7864, #7884, #12589, thanks @VincentLanglet! - Introduce
@phpstan-all-methods-(im)pure(#4422), thanks @VincentLanglet! - Introduce
__stringnotstringable(#4457) (#4457), #6560, thanks @VincentLanglet! - FileFinder - sort files before returning (phpstan/phpstan-src@c33cfea)
- Respect
sys_get_temp_dir()from the parent process (#4699), #13929, thanks @dktapps! - Add ArrayCombineFunctionThrowTypeExtension (#4414) (#4414), #13642, thanks @VincentLanglet!
- Do not degrade closures in array shapes (#4823), #14012, thanks @staabm!
- Do not degrade array-shapes in PHPDocs (#4864), thanks @staabm!
- Don't lose known offset-types in
array_replace()(#4826), thanks @staabm!
Bugfixes 🐛
- Resolve bitwise-not on constant integer (#4437), thanks @VincentLanglet!
- Support int range in bitwise operations (#4435) (#4435), #7912, #9384, thanks @VincentLanglet!
- Add exceptional case for DateInterval::format return type inference (#4442), #13693, thanks @adamturcsan!
- Comparison with strtolower() etc. leads lower/upper-case-string (#4857) (#4857), #14047, thanks @staabm!
- Resolve template with value of BackedEnum (#4548), #12219, #13282, #13638, #13782, thanks @VincentLanglet!
- SplObjectStorage iterates over objects (#4789) (#4789), #13985, #14046, thanks @staabm!
- Remove extra
dba_fetchvariant in PHP 8.3 functionMap (phpstan/phpstan-src@55d0fd7) - Constant's
isDeprecated()depends onScope::getPhpVersion()(#4630), thanks @staabm! - Add default value for getAttribute call in ContinueBreakInLoopRule (#4552), #13790, thanks @canvural!
- Infer non-empty-array after array_key_first/last() (#4536) (#4536), #13546, thanks @staabm!
- Fix strtr inferences (#4466) (#4466), #13708, thanks @VincentLanglet!
- Fix ignore comment handling for multiple traits in a single file (#4804), #13945, thanks @takaram!
- Do not report do-while-false pseudo-loops that are interrupted by a break statement (#4551), thanks @claudepache!
- Defer invalidating expressions after all args are processed (phpstan/phpstan-src@2a92c7b)
- Defer by-ref closure scope modifications after all args are processed (#4865)
Performance 🏎️
- NodeScopeResolver: faster produceArrayDimFetchAssignValueToWrite() (#4842), thanks @staabm!
- NodeScopeResolver: Prevent repetitive union of static types (#4841, #4843), thanks @staabm!
- Prevent repetitive calls to
ParametersAcceptorSelector::selectFromArgs()(#4855) (#4855), thanks @staabm! - MutatingScope: prevent unnecessary scope re-creation after openssl* calls (#4854) (#4854), thanks @staabm!
- Made closures php-src cachable (#4724), thanks @staabm!
- VoidToNullTraverser: Intersections cannot contain void (#4868), thanks @staabm!
- Prevent unnecessary type-traversal (#4868), thanks @staabm!
Function signature fixes 🤖
- mb_str_pad has side effects (#4849), thanks @longwave!
- More precise
microtime()return type (#4347), thanks @takaram! - Change return type of apcu_inc and apcu_dec function (#4419), thanks @LordSimal!
- Add missing parameters to RedisCluster signatures (#4430), thanks @RobiNN1!
- Fix return type of pcntl_signal_get_handler (#4544), thanks @marc-mabe!
- More precise
hrtime()return type (#4353) (#4353), thanks @takaram! - Fix
get_defined_vars()return type (#4632) (#4632), #13881, thanks @VincentLanglet! - Narrow string type when
ctype_*functions return true (#4570), #13089, thanks @takaram! - Fix get_object_vars() return type (#4629), thanks @Triplkrypl!
- Restrict chr param for PHP 8.5+ (#4673), #13930, thanks @VincentLanglet!
Internals 🔍
- Parallelize RunCommand in issue-bot (#4840)
- Add "consts" to typos dictionary (#4851)
- Rename GITHUB_TOKEN env var because it conflicts with
ghCLI tool (phpstan/phpstan-src@d56d189) - Regression test for #14041 (#4845), thanks @longwave!
- Refactor ComposerPhpVersionFactory (#4635), thanks @staabm!
- Refactor InitializerExprTypeResolver (#4861) (#4861), thanks @staabm!
- Added
make infectioncommand to run it locally (#4524) (#4524), thanks @staabm! - Add PHPDoc documentation to Type, Scope, and Reflection interfaces (#4866)
- PHPDoc tag
@api-do-not-implementinstead of list in BcUncoveredInterface (phpstan/phpstan-src@43d5026), #14054 - Use named arguments for unreadable calls (#4869)