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

ReferenceConstraintViolation with non-empty-literal-string in array #7095

Closed
AndrolGenhald opened this issue Dec 8, 2021 · 2 comments
Closed

Comments

@AndrolGenhald
Copy link
Collaborator

non-empty-literal-string should be a subtype of non-empty-string, but it still results in a ReferenceConstraintViolation: https://psalm.dev/r/2756501f64

This seems specific to ReferenceConstraintViolation, it acts correctly when a non-empty-literal-string is used as an argument that requires non-empty-string: https://psalm.dev/r/f8845a750d

In fact, it seems to be something about using it in an array, just having it as the parameter itself works fine: https://psalm.dev/r/c9ad19355c

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/2756501f64
<?php

/**
 * @param "a"|"b"|"c" $a
 * @param array<non-empty-string, true> $b
 */
function foo(string $a, array &$b): void
{
    /** @psalm-trace $baz */
    $baz = "bar $a";
    $b[$baz] = true;
}

$b = [];
foo("a", $b);
Psalm output (using commit 0ca856b):

INFO: Trace - 10:5 - $baz: non-empty-literal-string

ERROR: ReferenceConstraintViolation - 7:32 - Variable $b is limited to values of type array<non-empty-string, true> because it is passed by reference, non-empty-array<string, true> type found. Use @param-out to specify a different output type
https://psalm.dev/r/f8845a750d
<?php

/**
 * @param non-empty-string $bar
 */
function foo(string $bar): string
{
    return $bar;
}

/** @var "bar"|"baz" */
$bar = "bar";
/** @psalm-trace $baz */
$baz = "foo$bar";
foo($baz);
Psalm output (using commit 0ca856b):

INFO: Trace - 14:1 - $baz: non-empty-literal-string
https://psalm.dev/r/c9ad19355c
<?php

/**
 * @param "a"|"b"|"c" $a
 * @param non-empty-string $b
 */
function foo(string $a, string &$b): void
{
    /** @psalm-trace $baz */
    $baz = "bar $a";
    $b = $baz;
}

$b = "b";
foo("a", $b);
Psalm output (using commit 0ca856b):

INFO: Trace - 10:5 - $baz: non-empty-literal-string

@craigfrancis
Copy link
Contributor

I'm not familiar with Psalm internals (and I've run out of time today), but it looks like $all_types_contain is getting set to false in ArrayTypeComparator.php (I assume that shouldn't be the case).

AndrolGenhald added a commit to AndrolGenhald/psalm that referenced this issue Dec 8, 2021
@orklah orklah closed this as completed in a89e8ec Dec 8, 2021
orklah added a commit that referenced this issue Dec 8, 2021
Fix non-empty-literal-string to behave as subtype of non-empty-string (fixes #7095).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants