Skip to content

Reflect modern generics, opaque types & generalized existentials#77

Open
NSExceptional wants to merge 4 commits into
Azoy:mainfrom
NSExceptional:generics-opaque-and-existentials
Open

Reflect modern generics, opaque types & generalized existentials#77
NSExceptional wants to merge 4 commits into
Azoy:mainfrom
NSExceptional:generics-opaque-and-existentials

Conversation

@NSExceptional

@NSExceptional NSExceptional commented Jun 6, 2026

Copy link
Copy Markdown

Summary

Completes modern-Swift type reflection: variadic/value generic parameters, parameter-pack shapes, opaque-type realization, and generalized (parameterized-protocol) existentials — the last of which was an outright crash.

New Features

Generic parameter & requirement kindsGenericParameterKind only had .type, and GenericRequirementKind lacked .sameShape/.invertedProtocols, so the force-unwrapped decode crashed when reflecting any variadic-generic (each T), integer-generic (let N: Int), or noncopyable-constrained type. Adds .typePack/.value and .sameShape/.invertedProtocols.

Variadic-generic pack shapes (GenericContext.swift) — descriptorFlags (hasTypePacks / hasConditionalInvertedProtocols / hasValues), packShapeHeader, and packShapeDescriptors (pack kind, generic-argument index, same-shape equivalence class).

Opaque type realizationOpaqueDescriptor.underlyingType(at:genericArguments:) resolves a some P opaque type's mangled underlying type into a live metatype.

Generalized existential metadata — reflecting any Collection<Int> (a parameterized-protocol existential) crashed Echo with "unknown kind 775". Adds the .extendedExistential MetadataKind, an ExtendedExistentialMetadata type, and ExtendedExistentialTypeShape (special kind + generalization/type-expression/value-witness flags), wired into getMetadata.

Tests

Tests reflect a variadic-generic type (pack parameter decodes as .typePack, pack shape exposes a metadata pack), realize two opaque-returning functions' underlying types to Int/String via image enumeration, and reflect any Collection<Int> (kind .extendedExistential, generalization signature present, round-trips) while confirming a plain any Equatable keeps the classic layout. swift test green (32 tests).

GenericParameterKind only had .type, and GenericRequirementKind lacked
.sameShape/.invertedProtocols, so the force-unwrapped rawValue decode
crashed on any variadic-generic (each T), integer-generic (let N: Int),
or noncopyable-generic type. Add:
- GenericParameterKind: .typePack, .value
- GenericRequirementKind: .sameShape, .invertedProtocols

Test reflects a variadic-generic type and confirms its pack parameter
decodes as .typePack without trapping.
OpaqueDescriptor.underlyingType(at:genericArguments:) resolves a 'some P'
opaque type's mangled underlying-type name into a live metatype via the
in-context resolver, threading the opaque descriptor's generic context.
Out-of-range indices return nil.

Test enumerates the image's opaque descriptors and confirms two
opaque-returning functions' underlying types realize to Int and String.
…load)

Adds GenericContext.descriptorFlags (hasTypePacks / hasConditionalInverted
Protocols / hasValues), packShapeHeader, and packShapeDescriptors, decoding
the GenericPackShapeHeader + GenericPackShapeDescriptor records that trail a
variadic-generic context's parameters and requirements. Each descriptor
reports its pack kind (metadata / witness-table), generic-argument index, and
same-shape equivalence class. Also relaxes GenericRequirementDescriptor.
mangledTypeName to accept .sameShape requirements.

Tests confirm PackGeneric<each Element> exposes a metadata pack shape and a
non-pack generic exposes none.
Reflecting a parameterized-protocol existential like 'any Collection<Int>'
crashed Echo with 'unknown kind 775' (ExtendedExistential = 0x307). Adds the
.extendedExistential MetadataKind, an ExtendedExistentialMetadata type
exposing the existential shape, and ExtendedExistentialTypeShape with flags
(specialKind: opaque/class/metatype/explicit-layout; hasGeneralization
Signature / hasTypeExpression / hasSuggestedValueWitnesses), wired into
getMetadata.

Test reflects 'any Collection<Int>': kind .extendedExistential, the shape
reports a generalization signature and opaque special kind, and the metadata
round-trips; a plain 'any Equatable' still uses the classic layout.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant