Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plus operator in class const not resolving type when referencing parent const #5588

Closed
AndrolGenhald opened this issue Apr 6, 2021 · 1 comment · Fixed by #5591
Closed

Comments

@AndrolGenhald
Copy link
Collaborator

Referencing self consts seem to work fine: https://psalm.dev/r/70beb89706
But referencing parent consts causes the type to become mixed: https://psalm.dev/r/cbc8e21d41
Broken for ints too: https://psalm.dev/r/6b0c9ee8fc

Concatenation seems to work ok, though it changes the type to string instead of resolving the literal concatenation: https://psalm.dev/r/b67a63d851

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/70beb89706
<?php

class A {
    public const FOO = ['foo' => true];
    public const BAR = self::FOO + ['bar' => true];
}

/** @psalm-trace $foo */
$foo = A::FOO;
/** @psalm-trace $bar */
$bar = A::BAR;
Psalm output (using commit a469c82):

INFO: Trace - 9:1 - $foo: array{foo: true}

INFO: Trace - 11:1 - $bar: array{bar: true, foo: true}

INFO: UnusedVariable - 9:1 - $foo is never referenced or the value is not used

INFO: UnusedVariable - 11:1 - $bar is never referenced or the value is not used
https://psalm.dev/r/cbc8e21d41
<?php
class A {
    /** @var array<string, true> */
    public const ARR = [
        'A' => true,
    ];
}

class B extends A {
    /** @var array<string, true> */
    public const ARR = parent::ARR + [
        'B' => true,
    ];
}

class C extends B {
    /** @var array<string, true> */
    public const ARR = parent::ARR + [
        'C' => true,
    ];
}

/** @psalm-trace $a */
$a = A::ARR;
/** @psalm-trace $b */
$b = B::ARR;
/** @psalm-trace $c */
$c = C::ARR;
Psalm output (using commit a469c82):

INFO: Trace - 24:1 - $a: array{A: true}

INFO: MixedAssignment - 26:1 - Unable to determine the type that $b is being assigned to

INFO: Trace - 26:1 - $b: mixed

INFO: MixedAssignment - 28:1 - Unable to determine the type that $c is being assigned to

INFO: Trace - 28:1 - $c: mixed

INFO: UnusedVariable - 24:1 - $a is never referenced or the value is not used

INFO: UnusedVariable - 26:1 - $b is never referenced or the value is not used

INFO: UnusedVariable - 28:1 - $c is never referenced or the value is not used

INFO: MixedOperand - 18:24 - Left operand cannot be mixed
https://psalm.dev/r/6b0c9ee8fc
<?php
class A {
    public const INT = 1;
}

class B extends A {
    public const INT = parent::INT + 2;
}

class C extends B {
    public const INT = parent::INT + 3;
}

/** @psalm-trace $a */
$a = A::INT;
/** @psalm-trace $b */
$b = B::INT;
/** @psalm-trace $c */
$c = C::INT;
Psalm output (using commit a469c82):

INFO: Trace - 15:1 - $a: 1

INFO: MixedAssignment - 17:1 - Unable to determine the type that $b is being assigned to

INFO: Trace - 17:1 - $b: mixed

INFO: MixedAssignment - 19:1 - Unable to determine the type that $c is being assigned to

INFO: Trace - 19:1 - $c: mixed

INFO: UnusedVariable - 15:1 - $a is never referenced or the value is not used

INFO: UnusedVariable - 17:1 - $b is never referenced or the value is not used

INFO: UnusedVariable - 19:1 - $c is never referenced or the value is not used

INFO: MixedOperand - 11:24 - Left operand cannot be mixed
https://psalm.dev/r/b67a63d851
<?php
class A {
    public const STR = 'a';
}

class B extends A {
    public const STR = parent::STR . 'b';
}

class C extends B {
    public const STR = parent::STR . 'c';
}

/** @psalm-trace $a */
$a = A::STR;
/** @psalm-trace $b */
$b = B::STR;
/** @psalm-trace $c */
$c = C::STR;
Psalm output (using commit a469c82):

INFO: Trace - 15:1 - $a: "a"

INFO: Trace - 17:1 - $b: string

INFO: Trace - 19:1 - $c: string

INFO: UnusedVariable - 15:1 - $a is never referenced or the value is not used

INFO: UnusedVariable - 17:1 - $b is never referenced or the value is not used

INFO: UnusedVariable - 19:1 - $c is never referenced or the value is not used

AndrolGenhald added a commit to AndrolGenhald/psalm that referenced this issue Apr 7, 2021
Handle array plus operator (fixes vimeo#5588).
Handle array spread operator.
Improve string concatenation to resolve to literal instead of unknown string.

I feel like it should be possible to let ConstantTypeResolver take advantage of
the better type analysis in ArrayAnalyzer, ConcatAnalyzer, etc, but it would
require a restructuring that's beyond me for the time being.
muglug pushed a commit that referenced this issue Apr 8, 2021
Handle array plus operator (fixes #5588).
Handle array spread operator.
Improve string concatenation to resolve to literal instead of unknown string.

I feel like it should be possible to let ConstantTypeResolver take advantage of
the better type analysis in ArrayAnalyzer, ConcatAnalyzer, etc, but it would
require a restructuring that's beyond me for the time being.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant