Skip to content

Support ExpressionWithReturnType from ORM 3.7 - #790

Draft
janedbal wants to merge 4 commits into
phpstan:2.0.xfrom
janedbal:expression-with-return-type
Draft

Support ExpressionWithReturnType from ORM 3.7#790
janedbal wants to merge 4 commits into
phpstan:2.0.xfrom
janedbal:expression-with-return-type

Conversation

@janedbal

@janedbal janedbal commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

ORM 3.7 deprecates TypedExpression in favor of ExpressionWithReturnType (doctrine/orm#12543). A custom DQL function that implements only the new interface lost its declared type. The walker treated it as an untyped expression and inferred the driver-dependent default.

Changes:

  • QueryResultTypeWalker reads the type name from ExpressionWithReturnType::getReturnTypeName() first. It falls back to TypedExpression::getReturnType() for ORM < 3.7.
  • The StringType / EnumType no-op check now works on the resolved type name, so both paths share it.
  • New platform fixtures implement only ExpressionWithReturnType. The matrix test registers and runs them only when the interface exists.
  • compatibility/orm-3-baseline.php excludes those fixtures from analysis on ORM < 3.7. PHPStan cannot ignore "implements unknown interface", so the exclusion has to be dynamic.
  • phpstan.neon ignores the TypedExpression deprecation reports that ORM 3.7 produces. The fallback and its fixtures must stay for ORM < 3.7.
  • The Id, JoinColumns, and OrderBy patches in compatibility/patches/ are updated for ORM 3.7.0 (released 2026-09-07). Id gained a constructor and needs @NamedArgumentConstructor. JoinColumns and OrderBy changed their headers, so the old patch context did not apply. This is unrelated to the walker change but blocks the ORM 3 CI jobs on 2.0.x as well.

Verified locally with ORM 2.20 / DBAL 3 and with ORM 3.7.0 / DBAL 4.4.4: PHPStan level 8 is clean under both, the full unit suite passes under both, and the sqlite platform cases for both interfaces pass.

Co-Authored-By: Claude Code

ORM 3.7 deprecates TypedExpression in favor of ExpressionWithReturnType
(doctrine/orm#12543). Custom DQL functions that implement only the new
interface lost their declared type and fell back to the driver-dependent
default. The walker now checks the new interface first and keeps the
TypedExpression fallback for older ORM versions.

Co-Authored-By: Claude Code
ORM 3.7 marks TypedExpression as deprecated. The extension must keep the
fallback for ORM < 3.7, and the test fixtures must keep covering it.

Co-Authored-By: Claude Code
ORM 3.7 adds a constructor with an int $position parameter to
Doctrine\ORM\Mapping\Id. Without @NamedArgumentConstructor the
annotation reader passes the values array to that parameter and fails
with a TypeError.

Co-Authored-By: Claude Code
ORM 3.7 adds a class docblock to JoinColumns and a SortDirection import
to OrderBy. The old patch context no longer matches, so composer-patches
skipped both patches and the annotation reader rejected the classes.

Co-Authored-By: Claude Code
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