Releases: phpstan/phpstan
Releases · phpstan/phpstan
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!
2.1.49
Bugfixes 🐛
- Use declared property type instead of scope-narrowed type when inferring generic
newexpression types (#5467), #11844, thanks @VincentLanglet and @staabm!
Performance 🏎️
- Use pairwise
TypeCombinator::intersectfolding for conditional expression holders to avoid exponential union distribution (#5482), #14475 - Fix more cases (#5482), #14475
- More pair-wise intersect (#5482), #14475
- Avoid 2^N
getAllArrays()expansion inimplode()return type extension (#5482), #14475 - Avoid 2^N
getAllArrays()expansion inConstantArrayType::getFiniteTypes()(#5482), #14475 - Bail early in
TypeUtils::flattenTypes()to avoid 2^NgetAllArrays()expansion (#5482), #14475 - Batch
unionWithinspecifyTypesForFlattenedBooleanOrfalsey path to avoid O(N²) (phpstan/phpstan-src@7eab3d2) - Add flattening optimization for deep
BooleanAndchains in truthy context (phpstan/phpstan-src@3f5f2de) - Use hash map for O(1) key lookup in
ConstantArrayType(phpstan/phpstan-src@8019f65) - Fix infinite hang when analysing
src/wp-includes/user.phpin wordpress-develop (#5485)
Function signature fixes 🤖
Internals 🔍
- Fix PHPUnit warning (#5484), thanks @VincentLanglet!
2.1.48
Improvements 🔧
- Report promoted properties with
readonlyor hooks as always unitialized (cannot be unset) (#5452), #14459
Bugfixes 🐛
- Preserve list type in
ConstantArrayType::spliceArraywhen all keys are integers (#5480), #14472, thanks @VincentLanglet and @staabm! - Generalize
dynamicConstantNamesconstants to PHPDoc type if present (#5457), #9218, thanks @VincentLanglet and @staabm! - Use position-specific
getOffsetValueType()instead ofgetIterableValueType()when intersecting twoConstantArrayTypes (#5468), #11234, thanks @VincentLanglet and @staabm!
Performance 🏎️
- Fix for performance issue (phpstan/phpstan-src@6586de9), #14462
Internals 🔍
- Add regression test for
@varannotation beforeforeachnot defining the expression variable (#5458), #6688, thanks @VincentLanglet and @staabm!
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...