Skip to content

Unresolved template parameters leak raw names into argument diagnostics #84

@AJenbo

Description

@AJenbo

PHPantom version

main

Installation method

Built from source

Operating system

Linux x86_64

Editor

Zed

Bug description

When a template parameter is not bound to a concrete type (either
because no argument carries the binding, or because the class was
instantiated without a generic annotation), the raw template name
(e.g. TValue, TKey, TReduceReturnType, TClosure) leaks
through to the type error checker. The diagnostic then reports
"expects TValue, got string" instead of recognising the parameter
as unresolved and suppressing the check.

This affects both function-level and class-level templates:

  • Function-level: @template TReduceReturnType with
    @return TReduceReturnType where no argument binds the param.
  • Class-level: Collection<TKey, TValue> where the Collection
    was created without a generic annotation (e.g. collect([]),
    new Collection()). Methods like push($item) still have
    @param TValue $item with the raw template name, so passing
    a string fires "expects TValue, got string".

Template substitution should either resolve the parameter from the
call-site arguments / class-level generic annotation, or fall back
to the template's bound (defaulting to mixed) so the raw name
never leaks through to downstream diagnostics.

Reproducer (function-level):

/**
 * @template TReduceReturnType
 * @return TReduceReturnType
 */
function reduce_result() { return null; }

function takes_int(int $x): void {}

function test(): void {
    $result = reduce_result();
    takes_int($result); // false positive: "expects int, got TReduceReturnType"
}

Reproducer (class-level):

/**
 * @template TValue
 */
class Collection {
    /** @param TValue $item */
    public function push($item): void {}
}

function test(): void {
    $items = new Collection();   // no generic annotation
    $items->push('hello');       // false positive: "expects TValue, got string"
}

Steps to reproduce

run the diagnostics

Error output or panic trace


.phpantom.toml

Additional context

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions