-
Notifications
You must be signed in to change notification settings - Fork 680
Prevent array{a: Foo} going cleanly into array<Foo> #8691
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
Conversation
95753d0
to
bfe6651
Compare
1243066
to
bfff411
Compare
@muglug Could you explain why a string key isn't valid for array-key? |
@othercorey it's not about the key type (in this example). It's about unknown values that may be present in the unsealed shape. E.g. Psalm currently sees nothing wrong with https://psalm.dev/r/fb73a41c80, but it actually produces a fatal error: https://3v4l.org/b7XcPK |
I found these snippets: https://psalm.dev/r/fb73a41c80<?php declare(strict_types=1);
/**
* @param array{a: float, b: float} $params
*/
function f(array $params): void {
mapAtan($params);
}
/**
* @param array<array-key, float> $arr
* @return array<array-key, float>
*/
function mapAtan(array $arr): array {
$ret = [];
foreach ($arr as $k => $v) {
$ret[$k] = atan($v);
}
return $ret;
}
f(['a' => 0.5, 'b' => 10, 'c' => new Exception()]);
|
@weirdan ah, so |
@@ -41,7 +40,6 @@ | |||
*/ | |||
final class Union implements TypeNode, Stringable | |||
{ | |||
use ImmutableNonCloneableTrait; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
Full Union immutability was recently introduced by one of my PRs, since the class is marked as psalm-immutable
it makes no sense to clone it (and after I removed all clones in a later-merged PR performance improved by some 15%) :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's great! Sadly that PR failed our end-to-end tests, because PSL apparently has a Psalm plugin that calls Union::__clone
. Not sure how to work around that — @azjezz do you have ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the meantime I'm going to merge this — we can always add the trait back once the end-to-end test has been fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@azjezz Fixing this is actually pretty simple, just replace the last three lines with return $argument_type->setPossiblyUndefined(true)
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danog Thanks! will do so :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@azjezz You should generally also remove all clone
s of Unions and atomics from your plugin code :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Please note that this is only valid for Psalm v5, Psalm v4 still generally requires clones and your legacy logic)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ops! didn't think of that :D not released broken 2.0.3 :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, this can't be fixed until Psalm v5 is released, psalm uses a different repository for testing psl ( github.com/psalm/endtoend-test-psl ), which is still in PSL 1.x, the plugin used is also 1.x, so fixing those two for Psalm 5 doesn't seem worth it to me, maybe disable testing on psl for 5.0 for now? i can add it back when psalm 5 is released.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually already did this in #8697 (basically provided a custom patch file for our version), this was just a heads-up of the required changes for v5 :)
With this PR the following unsound code:
now generates the error:
Internal changes
TKeyedArray
gets a simplified signature since$sealed
always implied a null key/value param.Future work
We need to decide if we want to change the behaviour of
array{a: float, b: float}
to be closed by default.