Skip to content

feat: add four new native diagnostics#288

Open
calebdw wants to merge 4 commits into
mainfrom
calebdw/push-qtylnyylswzw
Open

feat: add four new native diagnostics#288
calebdw wants to merge 4 commits into
mainfrom
calebdw/push-qtylnyylswzw

Conversation

@calebdw

@calebdw calebdw commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds four new native diagnostics requested in issues #199, #278, #198, and #200. Each is a separate commit.

Enum declaration diagnostics (Closes #199)

Flags invalid enum declarations that would cause PHP fatal errors:

  • Backed enum cases missing a value — a backed enum (enum Foo: int) where a case lacks = value.
  • Unit enum cases with a value — a unit enum (enum Foo) where a case has = value.
  • Invalid backing type — backing types other than int or string (e.g. enum Foo: bool).
  • Duplicate backed values — two cases sharing the same backing value.

When an invalid backing type is detected, per-case value checks are skipped since they would be noise on top of the root cause.

Unimplemented trait abstract methods (Closes #278)

Concrete classes that use a trait with abstract methods without implementing them are now flagged as errors, matching PHP's fatal error at runtime. Extends the existing collect_missing_methods infrastructure (used by both the diagnostic and the "Implement missing methods" code action) with a new collect_abstract_from_used_traits pass. Also fixes an early-return that previously skipped classes with only used_traits (no interfaces or parent class).

Incompatible static return type override (Closes #198)

When a parent method declares a static return type (including ?static), child classes must also use static — using self narrows the contract and causes a PHP fatal error at runtime. This diagnostic catches that mistake at edit time. Uses native_return_type rather than the effective docblock type, since PHP only enforces native type hints.

Match arm type checking (Closes #200)

match expressions where a literal arm condition can never match the subject's type under strict comparison (===) now produce a warning. For example, an int literal in a match against a string subject is flagged as unreachable. Uses the Walker trait to collect match expressions from the AST, then resolves the subject type via the forward walker. Handles union and nullable subject types conservatively: a literal is only flagged when it is incompatible with every branch of the union.

Test coverage

  • 13 tests for enum diagnostics
  • 26 tests for implementation errors (existing suite expanded)
  • 9 tests for incompatible override
  • 10 tests for match type errors

All pass. Clippy and fmt clean.

calebdw added 4 commits July 25, 2026 22:05
Flag invalid enum declarations that would cause PHP fatal errors:
- Backed enum cases missing a value
- Unit enum cases that have a value
- Backing types other than int or string (e.g. bool, float)
- Duplicate backed values across cases

When an invalid backing type is detected, per-case value checks are
skipped since they would be noise on top of the root cause.

Closes #199
Closes #278 (enum-related portion)
Extend the missing-method diagnostic and code action to cover abstract
methods declared in used traits. Previously only interface methods and
abstract parent class methods were checked.

Three changes:
- collect_missing_methods now walks used_traits for abstract methods
  (with BackedEnum/UnitEnum filtered out for enums)
- The early-return in implementation_errors that skipped classes with
  no interfaces and no parent now also considers used_traits
- method_source_description reports the originating trait name

Closes #278
When a parent method declares a `static` return type (including
`?static`), child classes must also use `static` — using `self`
narrows the contract and causes a PHP fatal error at runtime. This
diagnostic catches that mistake at edit time.

Checks all method sources: parent classes, interfaces, and traits.
Uses `native_return_type` (the PHP type hint) rather than the
effective docblock type, since PHP only enforces native hints.

Closes #198
When a match expression's subject has a known scalar type, literal
arm conditions of a different scalar type are flagged as unreachable
since match uses strict comparison (===).  For example, an int
literal in a match against a string subject will never match.

Uses the Walker trait to collect match expressions from the AST,
then resolves the subject type via the forward walker.  Handles
union and nullable subject types conservatively: a literal is only
flagged when it is incompatible with every branch of the union.

Closes #200
@codecov-commenter

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 89.64218% with 55 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/diagnostics/match_type_errors.rs 84.81% 29 Missing ⚠️
src/diagnostics/incompatible_override.rs 85.71% 17 Missing ⚠️
src/diagnostics/enum_errors.rs 94.77% 8 Missing ⚠️
src/code_actions/implement_methods.rs 98.11% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants