Skip to content

Commit 6c06650

Browse files
committed
Add an API to map contextual types from the pack to element environment
I'm not really convinced that the existing implementation here is correct in general; it might work for the type checker's use cases, but I don't think we can rely on not seeing opened element archetypes from other expansions in the type we're processing here. But we can at least tread water while offering a more convenient API.
1 parent 8e5044a commit 6c06650

File tree

5 files changed

+39
-14
lines changed

5 files changed

+39
-14
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,18 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
277277
/// Map a generic parameter type to a contextual type.
278278
Type mapTypeIntoContext(GenericTypeParamType *type) const;
279279

280-
/// Map a type containing parameter packs to a contextual type
281-
/// in the opened element generic context.
280+
/// Map an interface type containing parameter packs to a contextual
281+
/// type in the opened element generic context.
282282
Type mapPackTypeIntoElementContext(Type type) const;
283283

284+
/// Map a contextual type containing parameter packs to a contextual
285+
/// type in the opened element generic context.
286+
Type mapContextualPackTypeIntoElementContext(Type type) const;
287+
288+
/// Map a contextual type containing parameter packs to a contextual
289+
/// type in the opened element generic context.
290+
CanType mapContextualPackTypeIntoElementContext(CanType type) const;
291+
284292
/// Map a type containing pack element type parameters to a contextual
285293
/// type in the pack generic context.
286294
Type mapElementTypeIntoPackContext(Type type) const;

lib/AST/GenericEnvironment.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,29 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
583583
return result;
584584
}
585585

586+
Type
587+
GenericEnvironment::mapContextualPackTypeIntoElementContext(Type type) const {
588+
if (!type->hasArchetype()) return type;
589+
590+
// FIXME: this is potentially wrong if there are multiple
591+
// openings in play at once, because we really shouldn't touch
592+
// other element archetypes.
593+
return mapPackTypeIntoElementContext(type->mapTypeOutOfContext());
594+
}
595+
596+
CanType
597+
GenericEnvironment::mapContextualPackTypeIntoElementContext(CanType type) const {
598+
if (!type->hasArchetype()) return type;
599+
600+
// FIXME: this is potentially wrong if there are multiple
601+
// openings in play at once, because we really shouldn't touch
602+
// other element archetypes.
603+
// FIXME: if we do this properly, there's no way for this rewrite
604+
// to produce a non-canonical type.
605+
return mapPackTypeIntoElementContext(type->mapTypeOutOfContext())
606+
->getCanonicalType();
607+
}
608+
586609
Type
587610
GenericEnvironment::mapPackTypeIntoElementContext(Type type) const {
588611
assert(getKind() == Kind::OpenedElement);

lib/IRGen/GenPack.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,7 @@ static llvm::Value *emitPackExpansionElementMetadata(
328328
// Replace pack archetypes with element archetypes in the pattern type.
329329
auto instantiatedPatternTy =
330330
context.environment
331-
->mapPackTypeIntoElementContext(patternTy->mapTypeOutOfContext())
332-
->getCanonicalType();
331+
->mapContextualPackTypeIntoElementContext(patternTy);
333332

334333
// Emit the element metadata.
335334
auto element = IGF.emitTypeMetadataRef(instantiatedPatternTy, request)
@@ -505,9 +504,7 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
505504

506505
// Replace pack archetypes with element archetypes in the pattern type.
507506
auto instantiatedPatternTy =
508-
context.environment
509-
->mapPackTypeIntoElementContext(patternTy->mapTypeOutOfContext())
510-
->getCanonicalType();
507+
context.environment->mapContextualPackTypeIntoElementContext(patternTy);
511508
auto instantiatedConformance =
512509
context.environment->getGenericSignature()->lookupConformance(
513510
instantiatedPatternTy, conformance.getRequirement());

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,8 +3837,8 @@ class ArgEmitter {
38373837
auto loweredPatternType =
38383838
expectedParamType.castTo<PackExpansionType>().getPatternType();
38393839
auto loweredElementType =
3840-
openedElementEnv->mapPackTypeIntoElementContext(
3841-
loweredPatternType->mapTypeOutOfContext())->getCanonicalType();
3840+
openedElementEnv->mapContextualPackTypeIntoElementContext(
3841+
loweredPatternType);
38423842
return SILType::getPrimitiveAddressType(loweredElementType);
38433843
}();
38443844

lib/SILGen/SILGenPack.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,7 @@ deriveOpenedElementTypeForPackExpansion(SILGenModule &SGM,
290290
OpenedElementContext::createForContextualExpansion(SGM.getASTContext(),
291291
expansion);
292292
auto elementType =
293-
context.environment->mapPackTypeIntoElementContext(
294-
patternType->mapTypeOutOfContext())
295-
->getCanonicalType();
293+
context.environment->mapContextualPackTypeIntoElementContext(patternType);
296294
return std::make_pair(context.environment,
297295
SILType::getPrimitiveAddressType(elementType));
298296
}
@@ -485,8 +483,7 @@ void InPlacePackExpansionInitialization::
485483
// This AST-level transformation is fine on lowered types because
486484
// we're just replacing pack archetypes with element archetypes.
487485
loweredPatternTy =
488-
env->mapPackTypeIntoElementContext(
489-
loweredPatternTy->mapTypeOutOfContext())->getCanonicalType();
486+
env->mapContextualPackTypeIntoElementContext(loweredPatternTy);
490487
}
491488
auto eltAddrTy = SILType::getPrimitiveAddressType(loweredPatternTy);
492489

0 commit comments

Comments
 (0)