Why doesn't "mixed" type in PHP permit covariance/contravariance?

https://onlinephp.io/c/6f1c9

Why doesn't this satisfy compatible signatures, given that "array" or "int" are always of pseudo-type "mixed":

class A
{ function foo (mixed $bar) {} }

class B extends A
{ function foo (int|array $bar) {} }

What am i missing?

PHP Sandbox - Execute PHP code online through your browser

Run PHP code in your browser online with this tool in 400+ PHP versions

@cautionbug int|array is a subset of mixed, and you can't restrict what argument types an inherited method accepts. It won't no longer be usable in all previous locations where the parent method was accepted, and thus violating LSP.
@cautionbug @derickr It does seem a little counterintuitive because of this, though: https://onlinephp.io/c/31eb3
PHP Sandbox - Execute PHP code online through your browser

Run PHP code in your browser online with this tool in 400+ PHP versions

@derickr @cautionbug Strike that. It’s not counter-intuitive. Here it is, following LSP properly with the native types: https://onlinephp.io/c/b9cfd

You can go wider on arguments and narrower on returns.

PHP Sandbox - Execute PHP code online through your browser

Run PHP code in your browser online with this tool in 400+ PHP versions

@ramsey @derickr @cautionbug Yes, because the whole point about LSP is not about "itself" but how the component you want to replace is used before and after.

I find this article *extremely* useful: https://blog.ploeh.dk/2021/12/06/the-liskov-substitution-principle-as-a-profunctor/

The Liskov Substitution Principle as a profunctor

With a realistic example in C#.

@Girgias @ramsey @derickr Thanks for the guidance and explanations. LSP is one of the rules i struggle with sometimes - maybe because PHP has been traditionally bad at type enforcement, i dunno.

In any case, all the info helps. i do have this one last question on the topic... The set() method:
https://onlinephp.io/c/c4b4b

i'm sure it's a design issue, so suggestions would go a long way. It's moments like this that "senior developer" only refers to my age...

PHP Sandbox - Execute PHP code online through your browser

Run PHP code in your browser online with this tool in 400+ PHP versions

@cautionbug @Girgias @ramsey @derickr That would require generics, so in PHP land it depends on how much you trust your static analysis tool.

If you do, you can do this: https://psalm.dev/r/3bcfb8fde7

But if your code can get to production despite SA issues there won't be a runtime check act as a safety net: https://onlinephp.io/c/c90f2

Psalm - a static analysis tool for PHP

@weirdan Thanks for that. i had a feeling it was going into annotation/SA land. Not "enforceable" but at least detectable. Somehow, PHP Core is going to have to come up with generics. Even if it's a C or Rust extension for a while.

All the help is appreciated!