On Tue, Mar 25, 2025 at 11:01 AM Rowan Tommins [IMSoP] <imsop....@rwec.co.uk>
wrote:

>
> I don't think the language should pretend to support something that it
> doesn't
>

I don't see what the pretending is here - the engine supports declaring
that a method must accept a parameter but makes no promises about the type
of that parameter, which is what we claim it supports. If people want to
use this for generics, then great, but I don't think this should be blocked
on the expectation that it is only useful for userland generics (e.g.
the Serde use case isn't really generics).


> - if the contract is actually enforced by a third-party tool reading
> docblocks, put the contract in a docblock:
>
>     /**
>        * @template T
>        * @method compareTo(T $other): int;
>        */
>     interface Comparable {
>     }
>
>     /** @implements Comparable<Number> */
>     final class Number implements Comparable {
>         public function compareTo(Number $other): int { return $this <=>
> $other; }
>     }
>
>
> What happens if there is a bigger contract than just the never parameter,
and we want the engine to enforce the rest? For example, the Serde use case
given previously. Or, if you had an object store that might occasionally
clean up expired items:

     /** @template T */
     interface ObjectStore {
         /** @param T $object */
         public function storeObject(never $object, bool $alsoDoCleanup):
void;
     }

If we move the entire contract to the docblock, then the engine cannot be
used to enforce the non-never-related parts.

--Daniel

Reply via email to