[ Typechecker ] Regex Match type inference ignores the positional result of named captures
- Dominant language
- C++
- Stars
- 18.7k
- Forks
- 3.1k
- Avg merge
- 1h 47m
- Merged PRs (30d)
- 2
Description
**Describe the bug**
A regex with a named capture `(?...)` appears twice in the result, but the typechecker believes that the positional variant does not exist.
**Standalone code, or other way to reproduce the problem**
```HACK
use namespace HH\Lib\Regex;
use namespace HH\Lib\_Private\_Regex;
// ?shape(0 => string, 1 => string)
$match = Regex\first_match('hello world', re"/(hello)/");
echo \json_encode($match, \JSON_FORCE_OBJECT).\PHP_EOL;
// {"0":"hello","1":"hello"}
// ?shape(0 => string, 'named_capture' => string)
$match = Regex\first_match('hello world', re"/(?hello)/");
echo \json_encode($match).\PHP_EOL;
// {"0":"hello","named_capture":"hello","1":"hello"}
// The `1` key is present at runtime ^
$_offset = 0;
// ?shape(0 => string, 'name' => string)
list($match, $_) = _Regex\match(
'hello world',
re"/(?hello)/",
inout $_offset,
);
echo \json_encode($match).\PHP_EOL;
// {"0":"hello","named_capture":"hello","1":"hello"}
// The `1` key is present at runtime ^
```
__EntryPoint and autoloader not shown for brevity.
Steps to reproduce the behavior:
1. Validate the hover type of `$match`
2. Validate the json output
3. Observe "1" in second and third json encode, but not in the hover type.
**Expected behavior**
Named arguments should not "hide" their positional name for the typechecker.
**Actual behavior**
See standalone code
**Environment**
- Operating system
> Ubuntu 20.04
- Installation method
> apt-get with dl.hhvm.com repository
- HHVM Version
```
HipHop VM 4.85.0 (rel)
Compiler: 1606769234_148788027
Repo schema: d1ae8e21bf3419a65f12a010527485564e719d07
hackc-fd31045126d9e76368e3fa73817029cf8e5da3f3-4.85.0
```
**Additional context**
I filed this issue against the typechecker instead of of the hsl. The tests in the hsl specify that the numeric key must be preserved.
https://github.com/hhvm/hsl/blob/202fc6d705d9635eb524156f1fe12c40c8aec669/tests/regex/RegexTest.php#L62-L66
The current runtime behavior might be incorrect. The case could be made for removing "1" if "named_capture" already refers to that same result. In that case, the current `preg_` based implementation is incorrect, as is the built-in `_Private` version.
Contributor guide
Assessment
This issue has not been assessed yet.