Skip to content

Instantly share code, notes, and snippets.

@veewee
Created September 30, 2022 09:20
Show Gist options
  • Select an option

  • Save veewee/3624bd80a4c9d28c4048a8cf51eeb4d5 to your computer and use it in GitHub Desktop.

Select an option

Save veewee/3624bd80a4c9d28c4048a8cf51eeb4d5 to your computer and use it in GitHub Desktop.

Revisions

  1. veewee created this gist Sep 30, 2022.
    180 changes: 180 additions & 0 deletions NeverTypeTest.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,180 @@
    <?php

    namespace Psalm\Tests\Template;

    use Psalm\Tests\TestCase;
    use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;

    class NeverTypeTest extends TestCase
    {
    use ValidCodeAnalysisTestTrait;

    /**
    * @return iterable<string,array{code:string,assertions?:array<string,string>,ignored_issues?:list<string>}>
    */
    public function providerValidCodeParse(): iterable
    {
    return [
    'neverDuringOptionalConstruction' => [
    'code' => '<?php
    /**
    * @template A
    */
    class Config {
    /**
    * @psalm-assert A is )
    * @param (callable(): A)|null $x
    */
    public function __construct($x = null)
    {}
    /**
    * @template NewA
    * @param (callable(): NewA)|null $x
    * @return Config<NewA>
    */
    public static function create($x = null)
    {
    return new self($x);
    }
    }
    $neverA = Config::create();
    $neverB = Config::create(null);
    $neverC = new Config();
    $neverD = new Config(null);
    $anyA = Config::create(function () { return "hello"; });
    $anyB = new Config(function () { return "hello"; });
    ',
    'assertions' => [
    '$neverA' => 'Config<never>',
    '$neverB' => 'Config<never>',
    '$neverC' => 'Config<never>',
    '$neverD' => 'Config<never>',
    '$anyA' => 'Config<string>',
    '$anyB' => 'Config<string>',
    ]
    ],
    'conditionalNever' => [
    'code' => '<?php
    /**
    * @template A
    */
    class Config {
    /**
    * @param (callable(): A)|null $x
    */
    public function __construct(public $x = null)
    {}
    }
    /**
    * @template A
    */
    class Client
    {
    /**
    * @param Config<A>|null $config
    */
    public function __construct(
    private ?Config $config
    ) {
    }
    /**
    * @return (A is never ? "world" : A)
    */
    public function run()
    {
    $this->config->x ? $this->config->x() : "world";
    }
    }
    $neverConfigA = new Config();
    $neverClientA = new Client($neverConfigA);
    $neverResultA = $neverClientA->run();
    $mixedConfigA = new Config(function () { return "hello"; });
    $mixedClientA = new Client($anyConfigA);
    $mixedResultA = $neverClientA->run();
    ',
    'assertions' => [
    '$neverConfigA' => 'Config<never>',
    '$neverClientA' => 'Client<never>',
    '$neverResultA' => '"world"',
    '$mixedConfigA' => 'Config<string>',
    '$mixedClientA' => 'Config<string>',
    '$mixedResultA' => 'string',
    ],
    'error_levels' => [],
    'php_version' => '8.1',
    ],
    'neverDuringUnion' => [
    'code' => '<?php
    /**
    * @template-covariant T
    */
    class Ok
    {
    /** @param T $v */
    public function __construct(
    public mixed $v
    ) {
    }
    }
    class Err
    {
    public function __construct(
    public string $e
    ) {
    }
    }
    /**
    * @template-covariant V
    */
    class Result
    {
    /** @param Ok<V>|Err $val */
    private function __construct(
    public Ok|Err $val
    ) {
    }
    /**
    * @template OkType
    *
    * @param OkType $item
    *
    * @return self<OkType>
    */
    public static function ok($item): self
    {
    return new self(new Ok($item));
    }
    /**
    * @return self<never>
    */
    public static function err(string $error): self
    {
    return new self(new Err($error));
    }
    }
    $never = Result::err("hello");
    $mixed = Result::ok("hello");
    ',
    'assertions' => [
    '$never' => 'Result<never>',
    '$mixed' => 'Result<string>',
    ],
    'error_levels' => [],
    'php_version' => '8.1',
    ],
    ];
    }
    }