A fluent method returning self promises the class it is declared in, so a subclass inherits a signature that lies about what it returns.
abstract class Query
{
public function where(string $c): static
{
$this->conditions[] = $c;
return $this;
}
}
final class OrderQuery extends Query
{
public function paid(): static { /* ... */ }
}
(new OrderQuery())->where('x')->paid(); // type-checks. it did not before.
Before 8.0 the honest arrangement was no native return type and a @return static docblock, which the analysers understood and the engine did not. Now the chain above resolves correctly all the way through, which removes a category of false positive that made static analysis unpleasant on any builder. It is a return type only — there is no static parameter type, and there is no reason for one.