Skip to content

Instantly share code, notes, and snippets.

@pbl64k
Last active August 20, 2018 10:36
Show Gist options
  • Save pbl64k/51610d55229dc67e4b6df20aefe893df to your computer and use it in GitHub Desktop.
Save pbl64k/51610d55229dc67e4b6df20aefe893df to your computer and use it in GitHub Desktop.
Type system unsoundness in HHVM 3.27.1: inout parameters, shape subtyping, bounded quantification
<?hh
require_once(__DIR__ . '/soundness.hh');
breakage();
<?hh
require_once(__DIR__ . '/soundness2.hh');
breakage2();
<?hh // strict
final class Dummy
{
final public function bork(): void
{
print('Bork.' . "\n");
}
}
type Narrow = shape(...);
type Broad = shape('dummy' => Dummy);
type Dad = shape('child' => Narrow);
function naive<Tx as Dad>(inout Tx $parent): void
{
$parent['child'] = shape();
}
function breakage(): void
{
$oops = shape('child' => shape('dummy' => new Dummy()));
naive(inout $oops);
$oops['child']['dummy']->bork();
}
<?hh // strict
final class Dummy2
{
final public function bork(): void
{
print('Bork.' . "\n");
}
}
type Narrow2 = shape(...);
type Broad2 = shape('dummy' => Dummy2);
type Dad2 = shape('child' => Narrow2);
final class Breakage<Tx>
{
final public function __construct(public Tx $shape) { }
}
function naive2<Tx as Dad2>(Breakage<Tx> $parent): void
{
$parent->shape['child'] = shape();
}
function breakage2(): void
{
$oops = new Breakage(shape('child' => shape('dummy' => new Dummy2())));
naive2($oops);
$oops->shape['child']['dummy']->bork();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment