facebook / facebook/hhvm

Type hole by substitution of generic method type parameter

Open
#7,828 2 comments 0 reactions 0 assignees View on GitHub
hack
Dominant language
C++
Stars
18.7k
Forks
3.1k
Avg merge
1h 47m
Merged PRs (30d)
2

Description

### HHVM Version

```
$ hhvm --version
HipHop VM 3.19.1 (rel)
Compiler: tags/HHVM-3.19.1-0-g6129094b1b61e1ae32245a583db0283e645384c1
Repo schema: 062f6c54b49727e83a10a43cdbb861741076e51d
```

### Standalone code, or other way to reproduce the problem

Generic methods can be implemented/overridden by replacing the function's generic parameter with a class-wide one, like so:

```hack
(T $v): void;
}
class C implements I {
public function foo(T $v): void {
$v::some_method();
}
}
```

The implementation vs. the interface contract shouldn't be compatible, but the typechecker doesn't complain. Then, it's pretty easy to break:

```hack
function cast(C $v): void {
violate($v);
}
function violate(I $v): void {
$v->foo(new \stdClass());
}
```

### Expected result

```
(Typing[4120])
Member foo has the wrong type
This is an object of type Base
It is incompatible with a value of generic type T
```

Such is the error if it's `C`'s `foo` instead that redeclares the type `as Base`, e.g.:

```
class C implements I { public function foo(T $v): void // ...
```

### Actual result

```
No errors!
```

But calling `cast(new C());` results in:

```
Fatal error: Call to undefined method stdClass::some_method()
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.