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
The generic-interface rendering previously projected a generic ABI protocol
(`protocol Name<T…>` with `associatedtype`s) plus a wrapper forwarding own
methods — the shape-1 foundation, which the non-generic-closed-base wall made
a dead end for base inheritance. Pivot the rendering onto the ABI-erased shape
windows-rs draws, reusing the merged `SignatureType.abi(…)`/`classification`
keystone:
- The ABI protocol is now NON-generic. Each method requirement reads every
parameter/return through its ABI-erased spelling: a reference-typed slot
(an interface, runtime class, delegate, generic-interface instantiation, or
`System.Object`) is the opaque interface pointer, a value-typed slot keeps
its own ABI. No generic parameters, no associated types.
- The public generic `struct` wrapper `Name<T…>` keeps the typed Swift
surface: each method takes/returns the decoded typed parameters and casts
the typed value to the erased pointer (and the erased result back) as it
forwards through `base` — `unsafeBitCast`, the text analogue of
windows-rs's `transmute_copy` across the vtable. A value slot needs no cast
(its typed and erased spellings coincide), so it forwards unchanged.
- Base inheritance becomes trivial and is INCLUDED: a non-generic ABI
protocol inherits its base's non-generic ABI protocol by plain protocol
inheritance — a generic base inherits `<stripped>ABI` (no arguments, no
`where`-constraints), a non-generic base (`IInspectable`) is inherited
unchanged. The non-generic-closed-base wall cannot occur.
The `Database+SQL` decode layer gains erased-ABI (`abi(return:)`/
`abi(parameter:)`) and classification (`reference(return:)`/
`reference(parameter:)`) accessors beside the existing typed `decode(…)`, all
sharing the extracted signature-navigation. `Shell` composes the per-slot
erased/typed spellings and the forwarding cast into the render context; the
`com.mustache` `{{#generic}}` arm emits the erased protocol + casting wrapper.
The non-generic `{{^generic}}` path is byte-identical.
The generated Swift is swiftc-typecheck-verified for a simple generic
interface (erased/cast element return), a generic interface with a generic
base (plain non-generic ABI inheritance, wrapper casts), an out/interface-array
method (erased element under the pointer), and a keyword-named generic
parameter.
Three metadata-shape fixes complete the erased shape:
- `SignatureType.classification` now treats a `VAR`/`MVAR` generic type
variable as a REFERENCE, so `abi(…)` erases a type-variable slot to the
opaque interface pointer rather than spelling its declared name. The ABI
protocol is non-generic and declares no associated type, so a requirement
`-> Element` would name an undeclared type; the wrapper casts the typed
value across the boundary as it does for any reference slot.
- The base-ABI rewrite distinguishes a CLR arity backtick (a `` ` `` followed
by a DIGIT, the raw `` IVector`1 `` spelling) from a Swift keyword-ESCAPING
backtick, which `SANITIZE` wraps around a keyword base (`` `protocol` ``).
Only the arity form marks a generic base to rewrite, so an escaped keyword
base is inherited unchanged instead of becoming a broken `` `protocolABI` ``.
- `bases.sql` resolves a TypeSpec-recorded base: a generic interface
inheriting another (`IVector`1 : IIterable`1`) records the base through a
`TypeSpec` GENERICINST row, which the plain `Interface_TypeRef`/`_TypeDef`
arms miss. A new `GENERICBASE` scalar UDF (over `WinMD.base(decoding:)`)
decodes the spec's signature to the base coded-index token; the view splits
its tag (`BITAND(token, 3)`) and 1-based row (`token / 4`) to join the base
`TypeRef`/`TypeDef` by `Id`, so the ABI rewrite emits `IIterableABI`.
0 commit comments