All Versions
Latest Version
Avg Release Cycle
8 days
Latest Release
793 days ago

Changelog History
Page 2

  • v3.18.2 Changes

    October 20, 2020

    πŸš€ Last night's release added a regression in how variables set in try statements are treated, ticketed here: #4368

  • v3.18.0 Changes

    October 19, 2020

    Language server works again

    πŸ‘€ This fixes an issue that prevented the language server from seeing recent changes to files (caused, almost inexplicably, by removing a @param docblock).

    πŸ›  Other bugfixes

    • πŸ›  Fix an issue with remapped template params (#4326)
    • πŸ‘Œ Improve handling of try statements without catches (#4333, #4366)
    • Deal with a few more combinatorial expansion issues gracefully (#4347)
    • πŸ‘Œ Improve Psalter replacements (#4350, #4349)
    • πŸ›  @pascalheidmann fixed an error when creating a report in a non-existent directory (#4353)
    • πŸ‘Œ Improve handling of assignments on the RHS of || if conditionals (#4354)
  • v3.17.2 Changes

    October 15, 2020
    • πŸ›  Fix #4327 - make sure loop always returns
    • πŸ›  Fix #4315 - prevent crash when setting unknown property in finally
  • v3.17.1 Changes

    October 13, 2020

    πŸ›  3.17.0 added a potentially-erroneous return type when a non-zero $flags param is passed to preg_split. This fixes things.

  • v3.17.0 Changes

    October 12, 2020

    πŸ”‹ Features

    • πŸ”§ @mr-feek added support for configurable universal objects (#3948)
    • πŸ‘Œ Improved error messages and reporting for ParadoxicalCondition (example) – thanks to @dkarlovi, @jbafford and @ro0NL for their input

    πŸ›  Bugfixes

    πŸ›  Fixed XML generation

    πŸ›  3.16 broke XML output, this is now fixed (#4252).

    πŸ›  Other bugfixes

    • πŸ‘ @DanielBadura added a stub for random_int, providing better inference (#4199)
    • Improved signatures for preg_match_all (#4202) and @orklah helped improve preg_split
    • Treat func_num_args as pure (#4215)
    • πŸ›  Fix __invoke declaration crash (#4210)
    • πŸ‘ Allow hinting arrow function return types (#4209)
    • βž• Add checks for if ((bool) $foo) (#4206)
    • πŸ›  Fix crash with some class-string property assignments (#4198)
    • πŸ›  @aheart fixed bugs with JUnit generation (#4234)
    • @danog added a bunch of stubs for Spl* classes (#4255)
    • πŸ›  allowMissingFiles was fixed by @ddeboer (#4259)
    • prevent crash after analysing file that defines a class twice (#4264)
    • prevent an infinite loop when analysing a closure unioned with invokable class (#4266)
    • @marcosh added more stubs for array functions (#4271)
    • prevent crash when annotating the intersection of arrays (#4287)
    • πŸ›  Fix reported property id for multiple MissingConstructor issues on a single class (#4297)
    • Prevent crash when trying to negate a positive-numeric assertion (#4306)
    • πŸ›  Fix return types for a few callmap-provided functions (#4309)
    • Prevent a class name validation check on a string argument to a class-string|Foo union (#4310)

    πŸ‘• Also thanks to @orklah for many linting PRs, and to @weirdan for very good triaging

  • v3.16 Changes

    September 15, 2020

    πŸ”‹ Features

    πŸ†• New PHPStorm-optimised output format

    βž• Added a phpstorm report format that displays errors in a manner that PHPStorm can parse more easily (#4085) – thanks @the-toster (with additional help from @Rarst)

    Detection of strpos issues

    Psalm will now raise two separate issues for the following code:

    function foo(string $s) : void { if (strpos(".", $s) !== -1) {} }

    The first, InvalidLiteralArgument, complains a string was passed where a variable was expected. The second complains that the output of strpos can never be negative.

    πŸ‘ Allow intersection of object-like arrays and regular arrays

    Psalm now allows the docblock array{foo: string}&array<string, string>, understanding it to mean an array of strings with one explicit known key.


    βž• Added support for @psalm-stub-override which only renders the stub valid if the given class already exists – thanks @weirdan (#4177)

    @psalm-suppress Issue1, Issue2

    βž• Added support for multiple suppressed issues on a given line – thanks @weirdan (#4179)

    πŸ›  Bugfixes

    πŸ‘ Allow multiple issues of the same type at a single position

    ⚑️ Psalm will now report multiple issues that map to the same code position (but whose message body is different). If you use the baseline, you might need to update it accordingly (#4167)

    πŸ›  Other bugfixes

    • πŸ‘ allow slashes in docblock tags (#4112)
    • ensure calling Closure::__invoke doesn't break when running Psalm in PHP 7.2.11 and below (#4111)
    • refine closure types more accurately according to a callable
    • prevent crash when suppressing UndefinedTrait (#4130)
    • improve inference of preg_match_all $matches array value (#4128)
    • πŸ›  fix a crash when using a short closure without specifying the Closure type anywhere in the affected methods (#4148)
    • πŸ‘ allow null checks on the output of Iterator::current (#4146)
    • Language Server @matthijskooijman made a couple of improvements (#4143)
    • treat literal numeric strings as numeric always (#4154)
    • Taint analysis @craigfrancis added additional mysql sinks (#4155)
    • Language Server @ngyuki fixed a bug using the Phar (#4174)
    • πŸ›  Fix Psalm's assertion generation from count($arr) <= 1 (#4169)
    • @ygottschalk improved Psalm's assertion generation from count calls further (#4175)
    • πŸ‘Œ Improve error message (and location) for unused params once they've been written to (#4127)
    • prevent an empty docblock from suppressing missing property types (#4178)
    • properly detect yield expressions in function arguments (#4122)
    • πŸ”€ improved Psalm's understanding of array_merge and array_filter functions
  • v3.15 Changes

    September 01, 2020

    πŸ”‹ Features

    πŸš€ This release brings a couple of features that are useful to fans of functional programming.

    If you're unfamiliar with these concepts, or want to know how Psalm uses them, read this article first.

    Automatic addition of @psalm-pure/@psalm-immutable annotations (#4036):

    βš™ Running vendor/bin/psalm --alter --issues=MissingPureAnnotation,MissingImmutableAnnotation will add those annotations to any function, method or class that deserves it.


    function sayHello(string $s): string { return 'Hello ' . $s; }

    is transformed into

    /\*\* \* @psalm-pure \*/function sayHello(string $s): string { return 'Hello ' . $s; }

    Note : running this command will not recursively add annotations, so if you have a chain of callers like

    function one(string $s) { return two($s); }function two(string $s) { return $s; }

    βš™ running the command once will produce

    function one(string $s) { return two($s); }/\*\* \* @psalm-pure \*/function two(string $s) { return $s; }

    and running it a second time will produce

    /\*\* \* @psalm-pure \*/function one(string $s) { return two($s); }/\*\* \* @psalm-pure \*/function two(string $s) { return $s; }

    Pure callables and closures

    Thanks to @azjezz, Psalm now understands the annotation pure-callable, which allows you to guarantee the purity of a pure function that executes a callable.

    Let's say we want to return the longest string in an array of strings ["a", "bbb", "cc"]. We could write that function pretty simply, but let's suppose we want to make it a bit more generic: given an array of items, and a callable that returns a score for the each entry, return the highest-scoring value.

    We can define that function in PHP like

    /\*\* \* @psalm-param non-empty-array $values \* @psalm-pure \*/function get\_max(array $values, callable $score\_func) { $max = reset($values); $max\_num = null; foreach ($values as $value) { $value\_num = $score\_func($value); if (null === $max\_num || $value\_num \>= $max\_num) { $max = $value; $max\_num = $value\_num; } } return $max; }echo get\_max(['a', 'bbb', 'cc'], 'strlen'); // outputs "bbb"

    This function is only pure, though, if the callable that we're passing is pure.

    βœ… With this latest version the full, pure type signature of the function can be written:

    /\*\* \* @template T \* @psalm-param non-empty-array\<T\> $values \* @psalm-param pure-callable(T):int $score\_func \* @psalm-return T \* \* @psalm-pure \*/function get\_max(array $values, callable $score\_func) { ... }

    πŸ›  Bugfixes

    • preserve intersections when expanding templated types (#4043)
    • 🚚 don't remove null types unnecessarily in mixed union, and refine iterable keys after is_array check (#4038)
    • assume most iterators are impure (#4064)
    • πŸ–¨ process indirect comparisons to null in assertions (#4061)
    • πŸ‘ allow pure functions to return impure closures (#4077)
    • πŸ‘ allow literal reconciliation against positive-int types (#4081, #4093)
    • πŸ‘ allow ParamNameMismatch to be suppressed locally (#4012)
    • πŸ›  fix parsing of union param types inside docblock @method annotations(#4083)
    • @staabm added a slightly-improved return type for strpos that precludes negative numbers
    • πŸ›  @weirdan fixed #3869 by creating a per-user cache directory
    • MissingPropertyType can now be refined on a per-property basis (#2200)
    • @lhchavez broadened the param type for strval to allow null
  • v3.14.2 Changes

    August 22, 2020

    πŸ›  Bugfixes

    • πŸ›  Fix exception when two mixins declare the same method (seen frequently on Laravel, thanks @xyng) – #4013
    • Prevent mixed assignment in loop after positive check (#4011)
    • πŸ‘ Allow @psalm-type to reference imported type right above (#3999)
    • πŸ›  Fixed some hash_* function signatures - thanks @baukevdw (#4014)
    • πŸ‘ Allow float defaults in namespaced class @method docblock annotations (#4017)
    • Taint analysis - added sinks for pgsql functions - thanks @TysonAndre (#4021)
    • Resolve type aliases in foreach docblock annotations - thanks @weirdan (#4029)
    • Don’t hang when pcntl_fork is disabled - thanks @weirdan (#3951)
    • βž• Add config option to discover unused @psalm-suppress on every run – thanks @micheh (#3011)
  • v3.14.1 Changes

    August 17, 2020

    πŸ›  Fixes a crash with this code:

      * @param array<int, int> $arr
     function foo(array $arr) : void {
        for ($i = 20; $arr[$i] === 5 && $i > 0; $i--) {}
  • v3.14.0 Changes

    August 17, 2020

    πŸ”‹ Features

    Named argument checks with ParamNameMismatch

    πŸ‘€ For more information, see this article.

    Preventing unsafe instantiation

    Psalm now warns you when calling new $foo() where $foo() is a class that can be extended and where the constructor is not declared final, or new static where the constructor is not declared final (#3934).

    πŸ‘€ For more information, see the issue page

    Other features

    • πŸ‘ @mr-feek added support for supplying memory limit with a --memory-limit flag (#3947)

    πŸ›  Bugfixes

    • πŸ›  fix a few false-positives around positive-int types (#3914)
    • expand scalar-class-constant types in a few more places (#3913, #3741)
    • @NicolasCARPi improved the signature for hash_file() (#3920)
    • honour arrays with class-string keys when appending literal classes (#3923)
    • @SignpostMarv marked bscale as impure (ref #3918)
    • preserve list-ness when assigning to a tuple inside a loop (#3928)
    • πŸ›  fix regression with array_shift (#3941)
    • πŸ›  @jarstelfox fixed the casing checker to ignore callStatic (#3939)
    • πŸ‘ @xyng added support for multiple mixins (#3772)
    • πŸ‘Œ improved Psalm's recovery when it encounters complex boolean logic (#3932, #3954)
    • @ygottschalk improved reset's return type
    • πŸ›  @sasezaki fixed the treatment of generators when an explicit send type is provided (#3966)
    • Language Server @ngyuki fixed file path handling on windows (#3984)
    • πŸ‘‰ Use unused code config settings when running language server (#3987)
    • Prevent an incorrect intersection of union types with usort (#3964)
    • Prevent crash with bad imported type reference (#3927)
    • @weirdan improved handling of @psalm-import-type errors (#3997)
    • comparisons between classes and interfaces are now allowed (#3917)