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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant