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

Wrong LessSpecificReturnStatement and MoreSpecificReturnType #2670

Closed
thelmuxkriovar opened this issue Jan 21, 2020 · 8 comments
Closed

Wrong LessSpecificReturnStatement and MoreSpecificReturnType #2670

thelmuxkriovar opened this issue Jan 21, 2020 · 8 comments

Comments

@thelmuxkriovar
Copy link

thelmuxkriovar commented Jan 21, 2020

In some code I wrote that 2 errors would show up no matter what I did, LessSpecificReturnStatement and MoreSpecificReturnType, so I noticed that psalm doesn't know when a list contains for certain only strings.
Here's some example code that shows the issue https://psalm.dev/r/657911d214

$metadata['tags'] = array_filter($metadata['tags'], fn($tag) => is_string($tag));

ensures without any doubt that $metadata['tags'] only contains strings.

What's interesting is that

$metadata['tags'] = array_map((fn($tag) => (string) $tag), $metadata['tags']);

works. However it's not ideal as it's not filtering anything, just string casting.

Maybe psalm doesn't consider array_filter?

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/657911d214
<?php
/**
* @psalm-return array{something: int, tags: list<string>}
*/
function testFunc() : array {
 	$metadata = ['something' => rand()];
  	// imagine a bunch of code with a bunch of checks and filters including:
	$metadata['tags'] = array_filter($metadata['tags'], fn($tag) => is_string($tag));
	$metadata['tags'] = array_values($metadata['tags']);
	return $metadata;
}
Psalm output (using commit 504de0a):

ERROR: InvalidArrayOffset - 8:35 - Cannot access value on variable $metadata using offset value of 'tags', expecting 'something'

INFO: MissingParamType - 8:57 - Parameter $tag has no provided type

INFO: MixedArgument - 8:35 - Argument 1 of array_filter cannot be mixed, expecting array<array-key, mixed>

INFO: LessSpecificReturnStatement - 10:9 - The type 'array{something: int, tags: list<mixed>}' is more general than the declared return type 'array{something: int, tags: list<string>}' for testFunc

INFO: MoreSpecificReturnType - 3:17 - The declared return type 'array{something: int, tags: list<string>}' for testFunc is more specific than the inferred return type 'array{something: int, tags: list<mixed>}'

@SignpostMarv
Copy link
Contributor

I believe it's tripping up because $metadata['tags'] doesn't exist, so is probably defaulting to mixed in it's absence.

see https://psalm.dev/r/1f8c1c193c

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/1f8c1c193c
<?php
/**
* @psalm-return array{something: int, tags: list<string>}
*/
function testFunc() : array {
 	$metadata = ['something' => rand(), 'tags' => ['foo', 1, 2.3]];
  	// imagine a bunch of code with a bunch of checks and filters including:
	$metadata['tags'] = array_filter($metadata['tags'], fn($tag) => is_string($tag));
	$metadata['tags'] = array_values($metadata['tags']);
	return $metadata;
}
Psalm output (using commit 504de0a):

No issues!

@thelmuxkriovar
Copy link
Author

Sorry! The fact that it's missing is only an issue with my test code, the actual code loads a bunch of things from a yaml file, amongst which is 'tags', I even have a check to create an empty array it if it's missing

@SignpostMarv
Copy link
Contributor

does it make a difference in your local code if you $metadata['tags'] = array_filter($metadata['tags'], 'is_string'); ?

@thelmuxkriovar
Copy link
Author

Surprisingly it does! I expected it to make no difference, but it absolutely does

@muglug
Copy link
Collaborator

muglug commented Jan 21, 2020

Did you try on latest master?

@muglug
Copy link
Collaborator

muglug commented Jan 21, 2020

Pretty sure this is a dupe of #2627 – I'll release soon.

@muglug muglug closed this as completed Jan 21, 2020
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

3 participants