facebook / facebook/hhvm

Property initialisation checks fail when methods are in trait

Open
#8,339 0 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: 3.28.3-0(brew)
hh_client: hh-d6bb63c6982aedf5c3c978f9097e066f5e208786-3.28.3

### Operating System and Version

MacOS High Sierra

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

```php
class A {
use T;

public function __construct() {
$this->setFoo();
}
}

trait T {
public string $foo;

private function setFoo() : void {
$this->foo = "fs";
}
}
```

### Actual result

```
test.hh:5:19,29: Class A does not initialize all of its members; foo is not always initialized.
Make sure you systematically set $this->foo when the method __construct is called.
Alternatively, you can define the member as optional (?...)
(NastCheck[3015])
test.hh:6:5,17: Until the initialization of $this is over, you can only call private methods
The initialization is not over because $this->foo can still potentially be null (NastCheck[3004])
```

### Expected result

No issues. If we inline `setFoo` into `A` explicitly the code passes:

```php
class A {
use T;

public function __construct() {
$this->setFoo();
}

private function setFoo() : void {
$this->foo = "fs";
}
}

trait T {
public string $foo;
}
```

I *think* the basic initialisation algorithm Hack's typechecker uses is: "a non-nullable property without a default is only validly initialised if defined in the `__construct`, or in a private method called in all branches of the `__construct`". It seems like private trait methods should be allowed as part of that.

This also isn't important - I just found it while playing around, and didn't see the behaviour documented.

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.