Search code examples
hhvmhacklang

HackLang by Facebook is not strict


Good day,

I have problem. I want to simulate some errors in hacklang.

<?hh
namespace Exsys\HHVM;

class HHVMFacade{

    private $vector = Vector {1,2,3};

    public function echoProduct() : Vector<string>{
        return $this->vector;
    }

    public function test(Vector<string> $vector) : void{
        var_dump($vector);
    }

}

Function echoProduct() returns Vector of strings. But private property $vector is Vector of integers. When I call echoFunction and returning value use as argument for function test(). I get

object(HH\Vector)#35357 (3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

Why? I am expecting some error because types mismatch.


Solution

  • There's two things at play here:

    1. Generics aren't reified, so the runtime has no information about them. This means the runtime is only checking that you're returning a Vector.
    2. $this->vector itself isn't typed. This means the type checker (hh_client) treats it as a unknown type. Unknown types match against everything, so there's no problem returning an unknown type where a Vector<string> is expected.

      This is to allow you to gradually type your code. Whenever a type isn't known, the type checker just assumes that the developer knows what's happening.

    The first thing I'd do is change the file from partial mode to strict mode, which simply involves changing from <?hh to <?hh // strict. This causes the type checker to complain about any missing type information (as well as a couple of other things, like no superglobals and you can't call non-Hack code).

    This produces the error:

    test.hh:6:13,19: Please add a type hint (Naming[2001])
    

    If you then type $vector as Vector<int> (private Vector<int> $vector), hh_client then produces:

    test.hh:9:16,28: Invalid return type (Typing[4110])
      test.hh:8:44,49: This is a string
      test.hh:6:20,22: It is incompatible with an int
      test.hh:8:44,49: Considering that this type argument is invariant with respect to Vector
    

    Which is the error you expected. You can also get this error simply by adding the type to $vector, without switching to strict mode, though I prefer to write my Hack in the strongest mode that the code supports.

    With more recent versions of HHVM, the type checker is called whenever Hack code is run (there's an INI flag to turn this off), so causing the type mismatch will also cause execution of the code to fail.