Skip to content

PHPStan fails to resolve static return types in fluent method chains after recent version upgrade #13298

@andrewdwallo

Description

@andrewdwallo

Bug report

After upgrading PHPStan, fluent interfaces that use static return types now produce "Call to method X() on an unknown class static" errors. This appears to be a regression in how PHPStan handles static return type resolution in method chains, possibly related to stub file processing for self-returning methods.

The issue occurs with fluent interfaces where methods return static to enable method chaining. PHPStan loses track of what the concrete class is after the first method that returns static, causing subsequent method calls to fail analysis with "unknown class static" errors.

This was working correctly in previous PHPStan versions and the code executes without issues at runtime.

This issue has been observed with various fluent testing interfaces including:

  • Livewire testing helpers
  • Filament testing helpers
  • Other fluent interface patterns using static returns

Code snippet that reproduces the problem

<?php

// Example with Livewire testing that reproduces the issue
use function Pest\Livewire\livewire;

// This chain produces errors: "Call to method call() on an unknown class static"
livewire(SomeClass::class)
    ->fillForm(['field' => 'value'])  // Returns static - PHPStan loses concrete type here
    ->call('create')                  // Error: Call to method call() on unknown class static  
    ->assertHasNoFormErrors();        // Error: Call to method assertHasNoFormErrors() on unknown class static

// The pattern that's breaking:
class TestHelper 
{
    public function fillForm(array $data): static 
    {
        // ... implementation
        return $this;
    }
    
    public function call(string $method): static
    {
        // ... implementation  
        return $this;
    }
}

Code snippet that reproduces the problem

No response

Expected output

PHPStan should maintain type information through the method chain. When a method returns static, PHPStan should resolve this to the concrete class and allow subsequent method calls to be analyzed correctly.

The expected analysis flow:

  1. livewire() returns \Livewire\Features\SupportTesting\Testable
  2. fillForm() returns static → should resolve to Testable
  3. call() should be recognized as a valid method on Testable
  4. Chain continues without "unknown class static" errors

Did PHPStan help you today? Did it make you happy in any way?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions