Skip to content

Fix PreInc/PreDec of NeverType#1641

Merged
ondrejmirtes merged 3 commits intophpstan:1.8.xfrom
herndlm:pre-inc-pre-dec-never-type
Aug 23, 2022
Merged

Fix PreInc/PreDec of NeverType#1641
ondrejmirtes merged 3 commits intophpstan:1.8.xfrom
herndlm:pre-inc-pre-dec-never-type

Conversation

@herndlm
Copy link
Copy Markdown
Contributor

@herndlm herndlm commented Aug 22, 2022

Found this while working on something else. The problem is that with the NeverType being the bottom type the next if block elseif ($stringType->isSuperTypeOf($varType)->yes()) would always evaluate to true leading to a string. That could still be improved by using isString() instead, but then the code afterwards would create Plus or Minus expressions leading to e.g. float.

While reading https://www.php.net/manual/en/language.operators.increment.php

Note: The increment/decrement operators only affect numbers and strings. Arrays, objects, booleans and resources are not affected. Decrementing null values has no effect too, but incrementing them results in 1.

I thought those expressions should only be created for numbers or null but I also don't like to use instanceof for that. Therefore I decided to check explicitly if it is a NeverType. Maybe, but I'm really not sure, the Type interface should have a couple more primitive type methods like isInteger, isFloat, isNull or so to deal with this a bit different. Those would definitely be no for a NeverType then.

@herndlm
Copy link
Copy Markdown
Contributor Author

herndlm commented Aug 22, 2022

Or, other idea: maybe I should further debug why never + 1 apparently leads to a float? If that would lead to never I don't need this extra if block if I also use isString() instead I guess.

UPDATE: found it, it comes from InitializerExprTypeResolver::resolveCommonMath. I think fixing common math operations with a NeverType makes more sense then. Will add another commit.

@staabm
Copy link
Copy Markdown
Contributor

staabm commented Aug 22, 2022

Just guesswork: maybe you could use toNumber Beforehand?

public function toNumber(): Type;

@herndlm
Copy link
Copy Markdown
Contributor Author

herndlm commented Aug 22, 2022

Just guesswork: maybe you could use toNumber Beforehand?

public function toNumber(): Type;

it would still stay being the NeverType, which makes sense. But this info is lost in InitializerExprTypeResolver when dealing with common math and is simply transformed to a float which does not make sense to me. I'm currently adapting it to lead to a NeverType, as also does the ErrorType. That makes at least sense to me, but let's see :)

@herndlm herndlm marked this pull request as ready for review August 22, 2022 20:14
@herndlm
Copy link
Copy Markdown
Contributor Author

herndlm commented Aug 22, 2022

Hmm did only see that one new pmmp error now. Coming from https://github.com/pmmp/PocketMine-MP/blob/e0b07ff3087b652407439a29c941f3b66ca92c86/src/pocketmine/utils/Utils.php#L480

I cannot comprehend this now, need to check it though

@herndlm herndlm marked this pull request as draft August 22, 2022 20:56
@herndlm
Copy link
Copy Markdown
Contributor Author

herndlm commented Aug 23, 2022

The pmmp types before the loop did not change, also according to https://phpstan.org/r/a0ce70a0-43ad-4324-8113-4eda1914b536 the loop is basically dead if I read the types and ranges right. I think I didn't break anything related to this but rather unhid a pmmp error or a phpstan bug.

I'm not entirely sure if this loop is dead code or not, but at least I can't also simply trigger it via e.g. https://3v4l.org/DaGfU

@herndlm herndlm marked this pull request as ready for review August 23, 2022 07:17
@staabm
Copy link
Copy Markdown
Contributor

staabm commented Aug 23, 2022

//cc @dktapps

@staabm
Copy link
Copy Markdown
Contributor

staabm commented Aug 23, 2022

I think you should add a explicit never + 1 test

@dktapps
Copy link
Copy Markdown
Contributor

dktapps commented Aug 23, 2022

I've no idea how that code works. @SOF3 can you shed any light on this?

@herndlm
Copy link
Copy Markdown
Contributor Author

herndlm commented Aug 23, 2022

jfyi it looks close to some other java string hash functions that can be found online, e.g. https://github.com/openjdk/jdk/blob/jdk-20+11/src/java.base/share/classes/java/lang/StringUTF16.java#L414 but with additional things going on :)

@ondrejmirtes ondrejmirtes merged commit b16c100 into phpstan:1.8.x Aug 23, 2022
@ondrejmirtes
Copy link
Copy Markdown
Member

Thank you!

@herndlm herndlm deleted the pre-inc-pre-dec-never-type branch August 23, 2022 15:00
@dktapps
Copy link
Copy Markdown
Contributor

dktapps commented Aug 23, 2022

jfyi it looks close to some other java string hash functions that can be found online, e.g. https://github.com/openjdk/jdk/blob/jdk-20+11/src/java.base/share/classes/java/lang/StringUTF16.java#L414 but with additional things going on :)

Thanks. Looks like some overengineering going on here, probably to prevent overflowing into a float.

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

Successfully merging this pull request may close these issues.

4 participants