Skip to content

feat: support ::class on object expressions#569

Merged
nahime0 merged 1 commit into
mainfrom
feat/support-class-for-objects
Jul 19, 2026
Merged

feat: support ::class on object expressions#569
nahime0 merged 1 commit into
mainfrom
feat/support-class-for-objects

Conversation

@nahime0

@nahime0 nahime0 commented Jul 18, 2026

Copy link
Copy Markdown
Member

Summary

  • add a dedicated ObjectClassName AST node for object-valued ::class
    receivers
  • support $object::class and expression receivers such as
    make_object()::class
  • lower object class-name reads through the existing runtime class metadata
    lookup
  • preserve the concrete runtime class for subclasses and object-only unions
  • evaluate the receiver expression exactly once
  • reject statically known non-object receivers with a PHP-compatible
    diagnostic
  • update the static classes example and parser/classes documentation

Named and scoped forms such as ClassName::class, self::class, parent::class,
and static::class keep their existing behavior.

Implementation notes

The parser keeps object-valued class-name reads structurally distinct from
compile-time ClassConstant expressions. EIR lowering evaluates the receiver
once and reuses the runtime lookup used by get_class(), so a value typed as
a base class still reports its concrete subclass.

All AST walkers, optimizer passes, name resolution, usage scans, prelude
detection, eval fallback classification, and type-analysis passes now
recurse through the new node.

The existing get_class() behavior for non-object values is intentionally
unchanged and remains tracked in #568.

Testing

  • cargo test --test parser_tests object_class_name

  • cargo test --test error_tests object_class_name

  • cargo test --test codegen_tests object_class_name

  • cargo test --lib lowers_every_expr_variant_smoke

  • ELEPHC_PHP_CHECK=1 cargo test --test codegen_tests
    'static_class_features::test_object_class_name'

  • cargo build

  • cargo check --tests

  • git diff --check

Coverage includes fully-qualified runtime names, concrete subclass dispatch,
object-only unions, single receiver evaluation, and rejection of non-object
receivers.

@github-actions github-actions Bot added area:optimizer Touches AST or EIR optimization passes. area:types Touches type checking, inference, or compatibility. area:web Touches --web mode, its prelude, or elephc-web. scope:multi-area Touches more compiler areas than the automatic area-label cap. size:l Large pull request. type:feature Introduces new user-visible behavior or capabilities. labels Jul 18, 2026
@nahime0
nahime0 merged commit 9abe136 into main Jul 19, 2026
115 checks passed
@nahime0
nahime0 deleted the feat/support-class-for-objects branch July 19, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:optimizer Touches AST or EIR optimization passes. area:types Touches type checking, inference, or compatibility. area:web Touches --web mode, its prelude, or elephc-web. scope:multi-area Touches more compiler areas than the automatic area-label cap. size:l Large 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