You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This class has no computed member. Confirmed on 757beace0 (current main, i.e. with #9386 merged), byte-compared against node --experimental-strip-types.
#9386 fixed the computed-member case by gating the computed-member lowering routes on a new FnCtx::is_static_class_this. It deliberately left the deeper cause alone, and that cause is not computed-member-specific:
static_type_of(Expr::This) (crates/perry-hir/src/type_analysis/predicates.rs:689) returns Named(class_stack.last()) in a static body — the same answer it gives in an instance body — and refine_type_from_init writes that into local_types. receiver_class_name(Expr::This) (same file, ~366) has the identical shape.
So a static body's this is typed as an instance of the class everywhere that answer is consumed.
Two known consequences
The example above: instance members resolve on the class object.
const t = this makes the receiver a LocalGet, so is_static_class_this no longer applies and it reaches the computed-member route through the metadata-only guarded_declared_class_get_candidate fallback — carrying the wrong type from local_types.
Note also that the computed-member gate is not under receiver_class_is_proven, contrary to the rule stated three lines above it in that file.
Making static_type_of / receiver_class_name honest about static this changes every consumer of that answer inside static bodies — static field reads, static-method dispatch, private brand checks. That is materially larger than a change whose job was to unblock the cc --help parity gate, which is why #9386 scoped it out deliberately rather than by oversight.
Not currently reachable from claude-code
A tokenizer scan of the cc bundle (brace-matching through strings/templates/regex/comments) found 412 static methods, 0 containing an alias-of-this that is then member-accessed. The scanner was validated by appending known instances to a copy of the bundle and finding 2/2. So the alias half is theoretical for cc today; the typeof this.instanceMethod half is a plain spec divergence reachable by any user.
Inside a static method, perry treats
thisas though it were an instance, so instance members appear to exist on the class object.This class has no computed member. Confirmed on
757beace0(current main, i.e. with #9386 merged), byte-compared againstnode --experimental-strip-types.Why this is filed separately from #9369
#9386 fixed the computed-member case by gating the computed-member lowering routes on a new
FnCtx::is_static_class_this. It deliberately left the deeper cause alone, and that cause is not computed-member-specific:static_type_of(Expr::This)(crates/perry-hir/src/type_analysis/predicates.rs:689) returnsNamed(class_stack.last())in a static body — the same answer it gives in an instance body — andrefine_type_from_initwrites that intolocal_types.receiver_class_name(Expr::This)(same file, ~366) has the identical shape.So a static body's
thisis typed as an instance of the class everywhere that answer is consumed.Two known consequences
thisis the class, not an instance — unblocks cc --help (#9369, #9341) #9386, still broken on current main:const t = thismakes the receiver aLocalGet, sois_static_class_thisno longer applies and it reaches the computed-member route through the metadata-onlyguarded_declared_class_get_candidatefallback — carrying the wrong type fromlocal_types.Note also that the computed-member gate is not under
receiver_class_is_proven, contrary to the rule stated three lines above it in that file.Scope, and why it wasn't folded into #9386
Making
static_type_of/receiver_class_namehonest about staticthischanges every consumer of that answer inside static bodies — static field reads, static-method dispatch, private brand checks. That is materially larger than a change whose job was to unblock thecc --helpparity gate, which is why #9386 scoped it out deliberately rather than by oversight.Not currently reachable from claude-code
A tokenizer scan of the cc bundle (brace-matching through strings/templates/regex/comments) found 412 static methods, 0 containing an alias-of-
thisthat is then member-accessed. The scanner was validated by appending known instances to a copy of the bundle and finding 2/2. So the alias half is theoretical for cc today; thetypeof this.instanceMethodhalf is a plain spec divergence reachable by any user.