Search code examples
hacklang

Catchable fatal error: Hack type error


Example from presentation on page 31

class Foo<T>  {

    public function add(T $delta): Foo {
        $this->num += $delta;        // line 6
        return $this;
    }

    public function get(): T {
         return $this->num;
    }

    public function __construct(private T $num): void {}
}

$f1 = new Foo(123);
$f1->add(567);
echo $f1->get(), PHP_EOL;

$f2 = new Foo(1.23);
echo $f2->add(5.67)->get(), PHP_EOL;

Error

Catchable fatal error: Hack type error: Typing error at example.php line 6

What is the problem?


HipHop VM 3.11.1 (rel)

Compiler: tags/HHVM-3.11.1-0-g64d37362bc0b6aee919492ad61cf65ce0a5d5e92

Repo schema: 8b80ba45250a6669cd610c189dbbb55b6218c2a3


Solution

  • If you run the typechecker (hh_client), you'll get an error like:

    This is a num because this is used in an arithmetic operation. It is incompatible with a value of generic type T

    This is because the + operator requires that both sides be num types, but T can be any type.

    You can add a constraint to T so that it has to be a num (class Foo<T as num>), or you could just use num as the type instead of a generic T.

    Using num will allow you to mix floats and ints in the same instance. Using a constraint, an instance will only work with either floats or ints, but not both.