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

annotating vars ? #11206

Open
MarcWeber opened this issue Jan 25, 2025 · 10 comments
Open

annotating vars ? #11206

MarcWeber opened this issue Jan 25, 2025 · 10 comments

Comments

@MarcWeber
Copy link

https://psalm.dev/r/c62b0a7eeb

Why doesn't this fail due to bad type assignment ? I mean assigning 7 to an array isn't this a problem? You also can assign a fn($x) => $x

Copy link

I found these snippets:

https://psalm.dev/r/c62b0a7eeb
<?php

/** @psalm-var array<int> */
$x = 7;
Psalm output (using commit 765dcbf):

INFO: UnusedVariable - 4:1 - $x is never referenced or the value is not used

@bdsl
Copy link
Contributor

bdsl commented Jan 25, 2025

That's how Psalm is designed - when you write /** @psalm-var array<int> */ you're overriding the built-in type inference that Psalm would do to determine the variable type and replacing it with your own. You have full control of Psalm as a code author, so if you want to do that you can.

Also there is no rule about what you can assign to a local variable with Psalm. It's not like Typescript where the variable has a type and you can only assign things that are assignable to that. With psalm the variable may have one type for the code before the assignment, and after the assignment is gets a new type based on that assignment: this is perfectly legal.

Copy link

I found these snippets:

https://psalm.dev/r/1842465ac5
<?php

$x = 3;

echo $x;

$x = ['hello'];

echo count($x);
Psalm output (using commit 765dcbf):

No issues!

@bdsl
Copy link
Contributor

bdsl commented Jan 25, 2025

In general where you can it s better to use assert (or an assertion function from a library) rather than @psalm-var. This example does give an error because Psalm detects that its impossible for an integer to also be an array: https://psalm.dev/r/c62b0a7eeb

Copy link

I found these snippets:

https://psalm.dev/r/c62b0a7eeb
<?php

/** @psalm-var array<int> */
$x = 7;
Psalm output (using commit 4bf49ce):

INFO: UnusedVariable - 4:1 - $x is never referenced or the value is not used

@MarcWeber
Copy link
Author

MarcWeber commented Jan 25, 2025

So what's the way to disambiguate the following cases ? $a = [2, 2] (tuple always exactly 2 values) and array{int} (any number) using type annotation ? Don't you think a @var which checks compatibility would make sense ? Something like @var-force and @var ? Or /** @var 'abc' | 'def' */ $s = 7; is obviously wrong.

@zmitic
Copy link

zmitic commented Jan 26, 2025

@MarcWeber

The problem goes away if you disableVarParsing. But it is not available in online testing tool.

@MarcWeber
Copy link
Author

But disabling is not a fix. If you have $a = 'red'; //* type 'red' | 'blue' no idea how to do that ? In tests there was kind of var is of type assertion maybe such is the way to go. I don't know psalm good enough yet.

@danog
Copy link
Collaborator

danog commented Jan 27, 2025

Disabling var parsing is absolutely recommended.

#10577 will introduce a better alternative to @var, but the vast majority of usecases do not need @var parsing in the first place.

@MarcWeber
Copy link
Author

There are two cases: One is @Satisfies, and another might be @Specialize. Example: If you have $db->query() returning array<array> or such you might want to specialize it to array. Does a mixed satisfy RowType ? Don't think so.

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

No branches or pull requests

4 participants