@@ -15,4 +15,63 @@ within the same impact tier.
1515
1616---
1717
18- No outstanding items.
18+ #### B12. Interface-extends-interface constants (and other members) not merged
19+
20+ | | |
21+ | ---| ---|
22+ | ** Impact** | Low-Medium |
23+ | ** Effort** | Low-Medium |
24+
25+ When an interface extends multiple parent interfaces (e.g.
26+ ` interface CarbonInterface extends DateTimeInterface, JsonSerializable, UnitValue ` ),
27+ ` resolve_class_with_inheritance ` only walks the ` parent_class ` field (the
28+ first extended interface). The remaining parent interfaces stored in the
29+ ` interfaces ` list are not traversed for member merging.
30+
31+ Then ` resolve_class_fully_inner ` calls ` resolve_class_with_inheritance ` on
32+ each interface collected from the class, but that inner call has the same
33+ limitation — it does not recurse into the interface's own ` interfaces ` list.
34+
35+ ** Reproducer:** ` Illuminate\Support\Carbon::JANUARY ` — the ` JANUARY ` constant
36+ lives on ` Carbon\Constants\UnitValue ` , which ` CarbonInterface ` extends (6th
37+ in the extends list). PHPantom reports "Member 'JANUARY' not found on class
38+ 'Illuminate\Support\Carbon'".
39+
40+ ** Fix:** In ` resolve_class_with_inheritance ` , when processing an interface
41+ (or always), also merge members from all entries in ` self.interfaces ` , not
42+ just ` parent_class ` . Alternatively, make ` resolve_class_fully_inner `
43+ recursively collect parent interfaces when resolving each interface.
44+
45+ Affects 4 diagnostics in shared (Carbon month constants) and likely more in
46+ other projects that use interfaces with multi-extends chains.
47+
48+ ---
49+
50+ #### B13. Variable type resolved from reassignment target inside RHS expression
51+
52+ | | |
53+ | ---| ---|
54+ | ** Impact** | Low |
55+ | ** Effort** | Medium |
56+
57+ When a variable is reassigned with an expression that references itself in
58+ the RHS arguments, PHPantom resolves the variable to the NEW type inside
59+ those arguments instead of the original type.
60+
61+ ** Reproducer:**
62+ ``` php
63+ public function requestToken(PaymentTokenRequest $request, ...): ... {
64+ // $request is PaymentTokenRequest here
65+ $request = new CreateRecurringSessionRequest(
66+ paymentMethodReference: $request->uuid, // ← PHPantom resolves $request as CreateRecurringSessionRequest
67+ );
68+ }
69+ ```
70+
71+ PHP evaluates all arguments before performing the assignment, so ` $request->uuid `
72+ should resolve against ` PaymentTokenRequest ` . PHPantom's variable definition
73+ offset tracking considers the new definition active too early — it should
74+ only take effect after the full RHS expression is evaluated.
75+
76+ Affects 1 diagnostic in shared. Edge case but could appear in code that
77+ reuses variable names across reassignments with self-referencing expressions.
0 commit comments