Skip to content

refactor: model static and $this as bounded types in the type system#287

Merged
calebdw merged 1 commit into
mainfrom
calebdw/push-sonmumonmmzk
Jul 26, 2026
Merged

refactor: model static and $this as bounded types in the type system#287
calebdw merged 1 commit into
mainfrom
calebdw/push-sonmumonmmzk

Conversation

@calebdw

@calebdw calebdw commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Add PhpType::StaticType(Atom) and PhpType::ThisType(Atom) variants that preserve late-static-binding semantics instead of flattening static/$this to a bare class name. StaticType carries the bound class ("at least this class or a subclass"), ThisType is more specific ("the exact runtime instance type").

The subtype chain is ThisType(A) <: StaticType(A) <: Named(A).
Display: static(Foo), $this(Foo) -- shows the bound class.

Production sites updated:

  • replace_self(fqn) now delegates to resolve_self_refs_bounded() so static -> StaticType(fqn) and $this -> ThisType(fqn); replace_self_with_type(&receiver) is unchanged (preserves full generic receiver types for accurate chain resolution)
  • Subject resolution: $this -> ThisType, static -> StaticType
  • First-class callable partial application: preserves static/this
  • Template substitution: preserve_static path uses bounded types
  • new static() -> StaticType instead of Named
  • Diagnostic param checking: resolve_self_refs_bounded() produces bounded types so class-string is properly validated

Subtype checking updated:

  • StaticType(A) <: Named(A) and ThisType(A) <: Named(A)
  • ThisType(A) <: StaticType(A)
  • base_name(), top_level_class_names(), collect_class_names() all handle the new variants

Peripheral sites updated:

  • return_type_is_mixin_self handles StaticType/ThisType
  • is_simple_php_type handles StaticType/ThisType
  • Union member deduplication handles StaticType/ThisType

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, examples/)
  • I have updated the config schema (config-schema.json)
  • I have added/updated tests to cover my changes
  • I fully understand the code that I am submitting (what it does,
    how it works, how it's organized), including any code drafted by an LLM.
  • For any prose generated by an LLM, I have proof-read and copy-edited with
    an eye towards deleting anything that is irrelevant, clarifying anything
    that is confusing, and adding details that are relevant. This includes,
    for example, commit descriptions, PR descriptions, and code comments.

@codecov-commenter

codecov-commenter commented Jul 26, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 63.81910% with 72 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/php_type/transform.rs 53.19% 66 Missing ⚠️
src/diagnostics/type_errors/mod.rs 76.92% 3 Missing ⚠️
src/php_type/mod.rs 85.71% 1 Missing ⚠️
src/php_type/subtype.rs 88.88% 1 Missing ⚠️
src/type_engine/call_resolution/template_subs.rs 75.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Add PhpType::StaticType(Atom) and PhpType::ThisType(Atom) variants
that preserve late-static-binding semantics instead of flattening
static/$this to a bare class name.  StaticType carries the bound
class ("at least this class or a subclass"), ThisType is more
specific ("the exact runtime instance type").

The subtype chain is ThisType(A) <: StaticType(A) <: Named(A).
Display: static(Foo), $this(Foo) -- shows the bound class.

Production sites updated:
- replace_self(fqn) now delegates to resolve_self_refs_bounded()
  so static -> StaticType(fqn) and $this -> ThisType(fqn);
  replace_self_with_type(&receiver) is unchanged (preserves full
  generic receiver types for accurate chain resolution)
- Subject resolution: $this -> ThisType, static -> StaticType
- First-class callable partial application: preserves static/this
- Template substitution: preserve_static path uses bounded types
- new static() -> StaticType instead of Named
- Diagnostic param checking: resolve_self_refs_bounded() produces
  bounded types so class-string<static> is properly validated

Subtype checking updated:
- StaticType(A) <: Named(A) and ThisType(A) <: Named(A)
- ThisType(A) <: StaticType(A)
- base_name(), top_level_class_names(), collect_class_names() all
  handle the new variants

Peripheral sites updated:
- return_type_is_mixin_self handles StaticType/ThisType
- is_simple_php_type handles StaticType/ThisType
- Union member deduplication handles StaticType/ThisType
@calebdw
calebdw force-pushed the calebdw/push-sonmumonmmzk branch from f0d570a to 4abfa75 Compare July 26, 2026 01:52
@calebdw
calebdw merged commit 03ceb68 into main Jul 26, 2026
7 checks passed
@calebdw
calebdw deleted the calebdw/push-sonmumonmmzk branch July 26, 2026 02:09
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.

2 participants