phpstan-src icon indicating copy to clipboard operation
phpstan-src copied to clipboard

implement loose comparison

Open staabm opened this issue 3 years ago • 7 comments

the tests added with his PR represent the comparison table from https://www.php.net/manual/en/types.comparisons.php inspired by https://github.com/phpstan/phpstan-src/pull/1602#discussion_r940628091

the more time I spent while working with loose comparisons, the more I realize how crazy those compare rules actually are.

staabm avatar Aug 22 '22 19:08 staabm

I think loose comparisons should be implemented via a new method like Type::looseCompare(Type $type): BooleanType. That will allow us to answer all possible situations.

ondrejmirtes avatar Aug 23 '22 14:08 ondrejmirtes

I see.

This implies we also need to implement Type::strictCompare($type): BooleanType in the same PR, because atm InitializerExprTypeResolver->resolveEqualType() is calling into InitializerExprTypeResolver->resolveIdenticalType().

moving the code arround will touch stuff already changed in https://github.com/phpstan/phpstan-src/pull/1634, so I will wait until #1634 is merged before starting the refactoring.

staabm avatar Aug 23 '22 18:08 staabm

Strict compare method isn't needed, that's already basically isSuperTypeOf, if you see how Identical is implemented in MutatingScope. I don't know of any bug that would suggest lack of something in this area.

ondrejmirtes avatar Aug 23 '22 18:08 ondrejmirtes

ok, just to get it right: I need to implement/test all types compared against all other types (+itself), right?

staabm avatar Aug 24 '22 13:08 staabm

Yes. It's PITA for sure 😊

ondrejmirtes avatar Aug 24 '22 14:08 ondrejmirtes

If you're going to pursue this, submit an implementation in one or two types first before fully diving in, to make sure we're on the same page. For example StringType::looseCompare() has to account for:

  • Any UnionType
  • Any IntersectionType
  • Against any object it's false
  • Looks like against any array it's also false
  • To correctly answer when it's non-empty-string, non-falsy-string, numeric-string...

The UnionType/IntersectionType is probably going to be solved similarly as accepts()/isAcceptedBy() / isSuperTypeOf()/isSubTypeOf(), meaning we're gonna need another method counterpart in CompoundType.

ondrejmirtes avatar Aug 24 '22 14:08 ondrejmirtes

ok thanks.

before bringing up the first looseCompare type, I will give other open PRs of mine some love, which are not blocked by external changes - so we can clean up the pull request queue first

staabm avatar Aug 25 '22 06:08 staabm

Hi, I'm cleaning up old and stale PRs. Please send a new PR if you're still interested, thanks.

ondrejmirtes avatar Oct 16 '22 10:10 ondrejmirtes