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

void vs. null #176

Closed
IanDelMar opened this issue Apr 12, 2023 · 23 comments
Closed

void vs. null #176

IanDelMar opened this issue Apr 12, 2023 · 23 comments

Comments

@IanDelMar
Copy link
Contributor

IanDelMar commented Apr 12, 2023

Should we ditch void in the EchoKey and the EchoParameter extensions and use null instead? Technically there is no such thing as void in PHP. However, as of PHP 7.1.0 there is a void return type. The PHP manual says

void is a return-only type declaration indicating the function does not return a value, but the function may still terminate. Therefore, it cannot be part of a union type declaration. Available as of PHP 7.1.0.

It also says

Note: Even if a function has a return type of void it will still return a value, this value is always null.

WordPress does use void in union types in doc blocks... which actually should be nullable return types. See the_title() for an example. Having void as return type for these functions leads to

sprintf('', the_title('<span>', '</span>', false))

giving Parameter #2 ...$values of function sprintf expects bool|float|int|string|null, string|void given. though sprintf() is completely fine with the_title('<span>', '</span>', false) as it is either string or null.

I don't know why this didn't pop up earlier.

@szepeviktor
Copy link
Owner

szepeviktor commented Apr 12, 2023

Static analysis is about strict types.

I am sorry.
Void is different from null.
When I should return null a simple return; is an error.

I consider PHP functions returning implicit null-s a language error.
It must be something from PHP 4.

@szepeviktor
Copy link
Owner

szepeviktor commented Apr 12, 2023

Wait!

Return: Void if $display argument is true, current post title if $display is false.

Why do we have an extra condition in our code for the_title?

if ($name === 'the_title') {
return TypeCombinator::union(
new StringType(),
new VoidType()
);
}

@IanDelMar
Copy link
Contributor Author

Because for the_title() void is always possible irrespective of the value of $display.

@szepeviktor
Copy link
Owner

szepeviktor commented Apr 12, 2023

I see! When title is an empty string.

If that is the case one should always check whether the return value of the_title is a string.
I get sick 🤢 in MINUTES when talking about WordPress.

@szepeviktor
Copy link
Owner

szepeviktor commented Apr 12, 2023

So properly written code for WordPress is long, hard to understand and silly.
I need to heal.

sprintf('', the_title('<span>', '</span>', false) ?? '')

@szepeviktor
Copy link
Owner

No, this is not working.

@IanDelMar
Copy link
Contributor Author

No, this is not working.

You healing or the code?

@szepeviktor
Copy link
Owner

There is no solution in PHP for detecting void.
One is forced to use /** @var string|null */

@szepeviktor
Copy link
Owner

You healing or the code?

Me healing.
This rabbit hole is stronger than me.
Each of these issues makes me delete all my software for WordPress from the Internet.

@IanDelMar
Copy link
Contributor Author

Oh no! We love szepeviktor/phpstan-wordpress!

@szepeviktor
Copy link
Owner

szepeviktor commented Apr 12, 2023

We need a businessman who can let perfectionism go. 🎦

@herndlm
Copy link
Contributor

herndlm commented Apr 13, 2023

I was also annoyed already by the fact that wpdb::prepare has a string|void return type (see also https://developer.wordpress.org/reference%2Fclasses%2Fwpdb%2Fprepare%2F/) and I can't just cast the return to string without phpstan complaining. string|null woudl allow that. But I think I just accepted it..

See also https://phpstan.org/r/23820230-f5a3-4533-9543-79b453cd5bd8

But if they internally just do return; and not return null; then the type is technically correct I suppose? It is indeed a mess though..

@herndlm
Copy link
Contributor

herndlm commented Apr 13, 2023

but wait, as @IanDelMar quoted in the beginning

Therefore, it cannot be part of a union type declaration.

and indeed it crashes spectacularly: https://3v4l.org/iRfF2

I wonder if PHPStan should be more strict with these invalid unions. Considering that PHPDoc is interpreted as it would be native type by default, the type is invalid IMO. I'll open a PHPStan issue.

@herndlm
Copy link
Contributor

herndlm commented Apr 13, 2023

@johnbillion do you think we can change all those implicit null returns from return; to return null; and adapt the return types? how high is the chance to get this in WP itself? :) union types with void are invalid and looks like PHPStan is going to check this at some point too..
what would be alternative if WP is not doing this - adapt it in the stubs I suppose?

@johnbillion
Copy link
Sponsor Contributor

Changing a return; to return null; shouldn't have any side effects because if anything is reading the return value it'll be treated as null. Example: https://3v4l.org/ZXFKY .

Making those functions nullable instead of voidable sounds like a good idea.

@szepeviktor
Copy link
Owner

Making those functions nullable instead of voidable sounds like a good idea.

Okay. Let's go on with this good idea.

@IanDelMar
Copy link
Contributor Author

The return type extension for redirect_canonical() does override WP's incorrect usage of void with null. It seems as this has already been some issue in the past.

@IanDelMar
Copy link
Contributor Author

Has anyone opened a ticket to get this into core? Or is planning to do so?

@herndlm
Copy link
Contributor

herndlm commented Nov 30, 2023

fyi this is going to be dealt with here: phpstan/phpstan-src#2778

all void returns are going to be transformed to null after calling a function and e.g. assigning them to a variable. that should avoid the issues some had here too. it should be fine to keep them in the phpdoc / stubs / wordpress.

@szepeviktor
Copy link
Owner

I dream about WordPress not having string|void-s
and PHP throwing fatal errors when void return values are used.

@szepeviktor
Copy link
Owner

PHPStan v 1.10.50 has this feature.

@herndlm
Copy link
Contributor

herndlm commented Feb 28, 2024

fyi this is going to be dealt with here: phpstan/phpstan-src#2778

all void returns are going to be transformed to null after calling a function and e.g. assigning them to a variable. that should avoid the issues some had here too. it should be fine to keep them in the phpdoc / stubs / wordpress.

PHPStan v 1.10.50 has this feature.

I think you can close this one, no?

UPDATE: or maybe bump min PHPStan version and adapt tests if necessary?
UPDATE2: nothing changed, not sure why, maybe the extensions should be adapted after all.

@szepeviktor
Copy link
Owner

A bump may be necessary.
But I have no Bump Button 🔴

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