Failure to detect unsafe generic return
- Dominant language
- C++
- Stars
- 18.7k
- Forks
- 3.1k
- Avg merge
- 1h 47m
- Merged PRs (30d)
- 2
Description
**Describe the bug**
Here's a situation where a function is allowed to return a parent class of a passed parameter, leading to.a runtime failure.
This _would_ be valid if `CoolQuery` was declared `final` (and without the subclasses)
```hack
class Result {}
interface Query {}
class CoolResult extends Result {}
class EvenCoolerResult extends CoolResult {
public function doSomething() : void {}
}
class CoolQuery implements Query{}
class EvenCoolerQuery implements Query{}
function query(Query $q): Tr {
if ($q is CoolQuery) {
return new CoolResult(); // this is incorrect
}
throw new LogicException('Bad');
}
function foo() : void {
$r = query(new EvenCoolerQuery());
// $r correctly typed to EvenCoolerResult
$r->doSomething(); // runtime bug
}
```
**Expected behavior**
```
Typing[4110] Invalid return type [1]
-> Expected Tr [2]
-> But got CoolResult [3]
test.hack:14:16
10 | class EvenCoolerQuery implements Query{}
11 |
[2] 12 | function query(Query $q): Tr {
13 | if ($q is CoolQuery) {
[1,3] 14 | return new CoolResult(); // this is invalid
15 | }
16 |
```
**Actual behavior**
No errors!
**Environment**
- HHVM 4.81 installed on MacOS Catalina via homebrew
- hh_client: hackc-2e49583c00353eab08db093c6f14e2fb413d3954-4.79.0
Contributor guide
Research direction
Start by reproducing the provided Hack example with the stated hh_client environment and confirm that the unsafe generic return is accepted. Trace the type-checking path for the `query` return and the `if ($q is CoolQuery)` branch. Done means the example reports the expected invalid return type diagnostic.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 42/100