PHP's static:: resolves to the called class at runtime, not the class that
lexically defines the method. Manticore has no runtime metadata and monomorphises
aggressively, so LSB is implemented the same way: per-descendant method copies,
the called class threaded as a compile-time scope and the right copy selected at
each call site.
static::class→ the called class name as a string.new static()→ instantiate the called class.static::method(...)→ dispatch to the called class's override.static::$prop/static::CONST→ the called class's static member.parent::m()/self::m()forward the scope (a downstreamstatic::stays bound to the original called class).- Constructors:
new C()runs an inherited ctor withstatic == C.
For an LSB method M owned by class R, every strict descendant S of R
gets a specialised copy named R__M__lsb<S> whose static:: resolves to S.
The normal R__M copy serves the S == R case.
- Lowering (
LowerFromAst):currentStaticClassis the scope, distinct fromcurrentLowerClass(the lexical/defining class, which still drivesself::,parent::, property layout).resolveStaticClass('static')returns the scope. A method is flagged LSB (sawStaticUse) when it referencesstaticor makes a forwardingself::/parent::/static::call. Flagged methods are queued (LsbPending) and, once the whole class table is known,emitLsbSpecializationsre-lowers each body once per descendant via the sharedlowerMethodFnhelper. StaticCall_.staticClasscarries the forwarded scope separately from the dispatch target, soparent::m()dispatches to the parent but keeps the called class.- Dispatch (
EmitLlvm):lsbTarget(owner, method, scope)returnsowner__method__lsb<scope>when that specialisation exists, else the plainowner__method. Static calls andnewuse the statically-known scope; instance calls feed the runtime class into the existingclass_idvirtual switch (each case is one concrete class → one scope), so an inherited LSB method becomes polymorphic even with no override.
- Code growth is bounded by (LSB methods) × (descendants); negligible in practice — the self-host binary size is unchanged.
get_class($this)still returns the static type, not the runtime class — usestatic::class. Tracked indocs/ROADMAP.mdTier 1.