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

Optional array keys transform to non optional when spreading #7776

Closed
finalgamer opened this issue Aug 11, 2022 · 3 comments · Fixed by phpstan/phpstan-src#1619
Closed

Optional array keys transform to non optional when spreading #7776

finalgamer opened this issue Aug 11, 2022 · 3 comments · Fixed by phpstan/phpstan-src#1619

Comments

@finalgamer
Copy link

Bug report

When spreading an array shape defined in doc blocks the optional array keys are no longer optional.

Code snippet that reproduces the problem

https://phpstan.org/r/1ffb734d-5580-4593-a980-00f3dd0569ea

<?php declare(strict_types = 1);

/**
 * @param array{page?: int, search?: string} $settings
 */
function test(array $settings = []): bool {
	$copy = [...$settings];
	\PHPStan\dumpType($copy); // Dumped type: array{page: int, search: string}
	\PHPStan\dumpType($settings); // Dumped type: array{page?: int, search?: string}
	return isset($copy['search']); // Offset 'search' on array{page: int, search: string} in isset() always exists and is not nullable.
}	

test();

Expected output

PHPStan should keep the optional information. The correct type for $copy would be array{page?: int, search?: string}

@herndlm
Copy link
Contributor

herndlm commented Aug 11, 2022

No need to ping me Ondrej, I'm gonna take a look at that soon :) I was working on this recently and I could swear that it looked like it should do exactly that - retain the optionality. weird.

@finalgamer
Copy link
Author

I don't know if i am asking for too much. But when a key is defined in the array like.

<?php declare(strict_types = 1);

/**
 * @param array{page?: int, search?: string} $settings
 */
function test(array $settings = []): bool {
	$copy = ['page' => 1, ...$settings];
	\PHPStan\dumpType($copy);
	\PHPStan\dumpType($settings);
	return isset($copy['search']);
}	

test();

it would be correct to report a type of $copy array{page: int, search?: string} because it is no longer optional.

But I don't know if PHPStan does that much analysis on the body of a function.

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants