Skip to content

feat(types): array element covariance into a declared array<Object> parameter#520

Open
chadmandoo wants to merge 1 commit into
illegalstudio:mainfrom
chadmandoo:upstream-pr/array-element-covariance-mixed
Open

feat(types): array element covariance into a declared array<Object> parameter#520
chadmandoo wants to merge 1 commit into
illegalstudio:mainfrom
chadmandoo:upstream-pr/array-element-covariance-mixed

Conversation

@chadmandoo

Copy link
Copy Markdown
Contributor

What

A PHP array parameter is a bare array — PHP does not enforce the @param array<T> element type at runtime, so the declared element type is a hint, not a hard bound. Two cases were rejected:

final class Builder {
    /** @param list<CondI> $conditions */
    public function __construct(private array $conditions) {}
    private function mkGroup(string $op): Group { return new Group($op); }
    public function addLeaf(Leaf $c): self {
        return $this->withConditions([...$this->conditions, $c]); // spread -> Array(Mixed)
    }
    public function addGroup(string $op): self {
        return $this->withConditions([$this->mkGroup($op)]);       // method-call element
    }
}

How

  • types_compatible accepts Array(Mixed) (a spread literal or an adaptive local) and an element-compatible array in either covariance direction for a declared Array(T) param — mirroring the whole-value (_, Mixed) => true trust posture, one container level down.
  • array_literal_element_type_for_ir types a method-call element as Mixed instead of the syntactic Int fallback. The old fallback stored an object-returning method's result in an Array(Int) and int-cast it at the element store (a hard backend error).

Test

test_array_element_covariance_spread_and_method_call — a fluent builder using both a spread element and a method-call element into an object-element array, byte-parity vs PHP 8.5.

🤖 Generated with Claude Code

…arameter

A PHP `array` parameter is a bare `array` — PHP does NOT enforce the `@param
array<T>` element type at runtime, so the declared element type is a hint, not
a hard bound.

- `types_compatible` accepts `Array(Mixed)` (a spread literal `[...$list, $x]`
  or an adaptive local) and an element-compatible array in either covariance
  direction for a declared `Array(T)` parameter — mirroring the whole-value
  `(_, Mixed) => true` trust posture, one container level down.
- `array_literal_element_type_for_ir` now types a method-call element
  (`[$this->mk()]`) as `Mixed` instead of the syntactic `Int` fallback. The old
  fallback stored an object-returning method's result in an `Array(Int)` and
  int-cast it at the element store (a hard backend error).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chadmandoo chadmandoo force-pushed the upstream-pr/array-element-covariance-mixed branch from c174d77 to 78d6c4a Compare July 11, 2026 14:04
@github-actions github-actions Bot added area:eir Touches EIR definitions, lowering, validation, or passes. area:types Touches type checking, inference, or compatibility. size:xs Very small pull request. type:feature Introduces new user-visible behavior or capabilities. labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:eir Touches EIR definitions, lowering, validation, or passes. area:types Touches type checking, inference, or compatibility. size:xs Very small pull request. type:feature Introduces new user-visible behavior or capabilities.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant