[ Typechecker ] <<__Memoize>> can cause the same object to be typed in incompatible ways
- Dominant language
- C++
- Stars
- 18.7k
- Forks
- 3.1k
- Avg merge
- 1h 47m
- Merged PRs (30d)
- 2
Description
**Describe the bug**
`<<__Memoize>>` can cause the same object to be typed in incompatible ways.
**Standalone code, or other way to reproduce the problem**
```HACK
final class Box {
public function __construct(public ?T $value)[] {}
}
<<__Memoize>>
function smuggling_boxes()[]: Box {
return new Box(null);
}
<<__EntryPoint>>
function main()[write_props]: void {
$int_box = smuggling_boxes();
$int_box->value = 2;
$string_box = smuggling_boxes();
$string_box->value = 'Oh no!';
$oh_no = $int_box->value;
if ($oh_no !== null) {
$_ = $oh_no * 6;
}
}
```
Steps to reproduce the behavior:
1. <<__Memoize>> says, if the arguments (all zero) are the same, return the old object.
2. The hack typechecker believes that `$int_box` and `$string_box` are different objects.
3. Setting `->value` via either typed reference updates the other to a value of the wrong type.
4. 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**
- Operating system
> For example, 'Docker Ubuntu 26.04 on host, 24.04 in container'
- Installation method
> 'docker hersheltheodorelayton/hhvm-basic'
- HHVM Version
```
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.
Contributor guide
Assessment
This issue has not been assessed yet.