@@ -501,8 +501,9 @@ static bool isTypeErasedGenericClassType(CanType type) {
501501}
502502
503503// Get the type that exists at runtime to represent a compile-time type.
504- CanType
505- irgen::getRuntimeReifiedType (IRGenModule &IGM, CanType type) {
504+ CanType IRGenModule::getRuntimeReifiedType (CanType type) {
505+ // Leave type-erased ObjC generics with their generic arguments unbound, since
506+ // the arguments do not exist at runtime.
506507 return CanType (type.transform ([&](Type t) -> Type {
507508 if (isTypeErasedGenericClassType (CanType (t))) {
508509 return t->getAnyNominal ()->getDeclaredType ()->getCanonicalType ();
@@ -511,6 +512,53 @@ irgen::getRuntimeReifiedType(IRGenModule &IGM, CanType type) {
511512 }));
512513}
513514
515+ CanType IRGenModule::substOpaqueTypesWithUnderlyingTypes (CanType type) {
516+ // Substitute away opaque types whose underlying types we're allowed to
517+ // assume are constant.
518+ if (type->hasOpaqueArchetype ()) {
519+ ReplaceOpaqueTypesWithUnderlyingTypes replacer (getSwiftModule (),
520+ ResilienceExpansion::Maximal);
521+ type = type.subst (replacer, replacer,
522+ SubstFlags::SubstituteOpaqueArchetypes)
523+ ->getCanonicalType ();
524+ }
525+
526+ return type;
527+ }
528+
529+ SILType IRGenModule::substOpaqueTypesWithUnderlyingTypes (SILType type) {
530+ // Substitute away opaque types whose underlying types we're allowed to
531+ // assume are constant.
532+ if (type.getASTType ()->hasOpaqueArchetype ()) {
533+ ReplaceOpaqueTypesWithUnderlyingTypes replacer (getSwiftModule (),
534+ ResilienceExpansion::Maximal);
535+ type = type.subst (getSILModule (), replacer, replacer,
536+ CanGenericSignature (),
537+ /* substitute opaque*/ true );
538+ }
539+
540+ return type;
541+ }
542+
543+ std::pair<CanType, ProtocolConformanceRef>
544+ IRGenModule::substOpaqueTypesWithUnderlyingTypes (CanType type,
545+ ProtocolConformanceRef conformance) {
546+ // Substitute away opaque types whose underlying types we're allowed to
547+ // assume are constant.
548+ if (type->hasOpaqueArchetype ()) {
549+ ReplaceOpaqueTypesWithUnderlyingTypes replacer (getSwiftModule (),
550+ ResilienceExpansion::Maximal);
551+ conformance = conformance.subst (type, replacer, replacer,
552+ SubstFlags::SubstituteOpaqueArchetypes);
553+ type = type.subst (replacer, replacer,
554+ SubstFlags::SubstituteOpaqueArchetypes)
555+ ->getCanonicalType ();
556+ }
557+
558+ return std::make_pair (type, conformance);
559+ }
560+
561+
514562// / Attempts to return a constant heap metadata reference for a
515563// / class type. This is generally only valid for specific kinds of
516564// / ObjC reference, like superclasses or category references.
@@ -2313,7 +2361,9 @@ llvm::Value *IRGenFunction::emitTypeMetadataRef(CanType type) {
23132361MetadataResponse
23142362IRGenFunction::emitTypeMetadataRef (CanType type,
23152363 DynamicMetadataRequest request) {
2316- type = getRuntimeReifiedType (IGM, type);
2364+ type = IGM.getRuntimeReifiedType (type);
2365+ // Look through any opaque types we're allowed to.
2366+ type = IGM.substOpaqueTypesWithUnderlyingTypes (type);
23172367
23182368 if (type->hasArchetype () ||
23192369 isTypeMetadataAccessTrivial (IGM, type)) {
@@ -2328,7 +2378,7 @@ IRGenFunction::emitTypeMetadataRef(CanType type,
23282378// / for the given non-dependent type.
23292379llvm::Function *irgen::getOrCreateTypeMetadataAccessFunction (IRGenModule &IGM,
23302380 CanType type) {
2331- type = getRuntimeReifiedType (IGM, type);
2381+ type = IGM. getRuntimeReifiedType (type);
23322382
23332383 assert (!type->hasArchetype () &&
23342384 " cannot create global function to return dependent type metadata" );
0 commit comments