Describe the bug
<<__Memoize>> can cause the same object to be typed in incompatible ways.
Standalone code, or other way to reproduce the problem
final class Box<T> {
public function __construct(public ?T $value)[] {}
}
<<__Memoize>>
function smuggling_boxes<Tv>()[]: Box<Tv> {
return new Box<Tv>(null);
}
<<__EntryPoint>>
function main()[write_props]: void {
$int_box = smuggling_boxes<int>();
$int_box->value = 2;
$string_box = smuggling_boxes<string>();
$string_box->value = 'Oh no!';
$oh_no = $int_box->value;
if ($oh_no !== null) {
$_ = $oh_no * 6;
}
}
Steps to reproduce the behavior:
- <<__Memoize>> says, if the arguments (all zero) are the same, return the old object.
- The hack typechecker believes that
$int_box and $string_box are different objects.
- Setting
->value via either typed reference updates the other to a value of the wrong type.
- In this example, multiplying 'Oh no!' by 6 blows up at runtime.
Expected behavior
This typehole exists in strict Hack. Closing this typehole would cause churn in correct code. I am not sure if it should be closed.
Actual behavior
hh_client No errors!
Fatal error: Uncaught exception 'InvalidOperationException' with message 'Cannot perform mathematical operation on string and int'
Environment
For example, 'Docker Ubuntu 26.04 on host, 24.04 in container'
'docker hersheltheodorelayton/hhvm-basic'
HipHop VM 26.3.28 (rel) (non-lowptr)
Compiler: heads/hhvm-oss-20260328-0-gcf488896c50fc865bc5d3e15608f9f1503f1343f
Repo schema: 768e783da4ee9ceac6534045f6369f37c27f9539
Additional context
A reified type argument gets a separate memoization cache, closing the typehole.
Describe the bug
<<__Memoize>>can cause the same object to be typed in incompatible ways.Standalone code, or other way to reproduce the problem
Steps to reproduce the behavior:
$int_boxand$string_boxare different objects.->valuevia either typed reference updates the other to a value of the wrong type.Expected behavior
This typehole exists in strict Hack. Closing this typehole would cause churn in correct code. I am not sure if it should be closed.
Actual behavior
hh_clientNo errors!Fatal error: Uncaught exception 'InvalidOperationException' with message 'Cannot perform mathematical operation on string and int'
Environment
Additional context
A reified type argument gets a separate memoization cache, closing the typehole.