Skip to content

Commit 5826d7f

Browse files
committed
Add bug note
1 parent 54c8bcb commit 5826d7f

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

docs/todo/bugs.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,64 @@ pipeline so it produces correct data. Downstream consumers
77
(diagnostics, hover, completion, definition) should never need
88
to second-guess upstream output.
99

10+
## B116. Renaming a constructor-promoted property parameter doesn't cascade to `$this->prop` usages
11+
12+
**Severity: Low-Medium (rename only updates the parameter declaration
13+
itself; every `$this->field` reference elsewhere in the class is left
14+
stale, silently producing a broken rename) · Discovered while
15+
investigating a user-reported GitHub Q&A about rename support for
16+
promoted properties**
17+
18+
```php
19+
final class SomeService {
20+
public function __construct(
21+
private int $someField, // renaming this parameter...
22+
) {}
23+
24+
public function handle(): void {
25+
$this->someField; // ...doesn't rename this usage
26+
}
27+
}
28+
```
29+
30+
The symbol-map extraction for constructor parameters
31+
(`src/symbol_map/extraction/class_like.rs:605-642`) unconditionally
32+
tags every parameter's `VarDefSite`/`SymbolSpan` with
33+
`kind: VarDefKind::Parameter` (line 633), with no check for
34+
`param.is_promoted_property()`. This is the symbol map that
35+
`find_references`/rename consult, and it's a separate structure from
36+
the properties list the type engine builds in
37+
`src/parser/classes.rs:1040-1049`, which *does* special-case
38+
`is_promoted_property()` to synthesize a property for hover/completion/
39+
type-inference of `$this->someField` — but that data isn't wired back
40+
into the symbol map's `VarDefKind`.
41+
42+
Because of this, `lookup_var_def_kind_at` (`src/definition/resolve.rs:130`)
43+
reports `VarDefKind::Parameter` for a promoted property, so
44+
`src/references/dispatch.rs:136-172` routes the rename to
45+
`find_variable_references` (`src/references/variables.rs:22`) instead
46+
of the cross-file, member-access-aware `find_member_references`.
47+
`find_variable_references` is explicitly file-local/scope-local and
48+
never looks at `$this->foo` sites, so it only renames the parameter's
49+
own token(s). The same `VarDefKind::Property` check gates
50+
`is_property_rename` in `src/rename/prepare.rs:302-306`, so the rename
51+
is also misclassified as a plain-variable rename rather than a
52+
property rename, which skips the `$this->foo` prefix-fixup logic
53+
`src/rename/mod.rs` documents for property renames.
54+
55+
Fix by making the symbol-map extraction in `class_like.rs` emit
56+
`VarDefKind::Property` (or an equivalent alias treated like `Property`
57+
everywhere) for parameters where `param.is_promoted_property()` is
58+
true, and register the declaration wherever
59+
`find_member_references`/the declaration-hierarchy resolvers expect
60+
property declarations to live. Audit the other call sites that branch
61+
on `VarDefKind::Parameter` vs `Property` for promoted params for their
62+
own reasons (semantic tokens at `semantic_tokens.rs:757-770`, hover at
63+
`hover/mod.rs:152-158`) so they keep working once the kind changes.
64+
There is no existing test coverage for promoted-property rename or
65+
references (`src/rename/tests.rs` and `tests/integration/references.rs`
66+
have no `__construct`/promoted-property cases).
67+
1068
## B115. Closure-parameter inference uses call-position instead of the declared parameter index, so named arguments that reorder a call break it
1169

1270
**Severity: Low-Medium (closure/arrow-function parameters silently lose

0 commit comments

Comments
 (0)