@@ -328,7 +328,8 @@ struct ASTContext::Implementation {
328328 CanGenericSignature SingleGenericParameterSignature;
329329
330330 // / The existential signature <T : P> for each P.
331- llvm::DenseMap<CanType, CanGenericSignature> ExistentialSignatures;
331+ llvm::DenseMap<std::pair<CanType, const DeclContext *>, CanGenericSignature>
332+ ExistentialSignatures;
332333
333334 // / Overridden declarations.
334335 llvm::DenseMap<const ValueDecl *, ArrayRef<ValueDecl *>> Overrides;
@@ -4421,6 +4422,12 @@ CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
44214422 GenericEnvironment *environment, Type interfaceType,
44224423 ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
44234424 LayoutConstraint layout) {
4425+ // FIXME: It'd be great if all of our callers could submit interface types.
4426+ // But the constraint solver submits archetypes when trying to issue checks
4427+ // against members of existential types. For now, we'll work around them by
4428+ // forcing an interface type.
4429+ // assert((!superclass || !superclass->hasArchetype())
4430+ // && "superclass must be interface type");
44244431 auto arena = AllocationArena::Permanent;
44254432 ASTContext &ctx = interfaceType->getASTContext ();
44264433 void *mem = ctx.Allocate (
@@ -4434,16 +4441,21 @@ CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
44344441 environment, interfaceType, conformsTo, superclass, layout));
44354442}
44364443
4437- CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::get (
4438- CanType existential, Optional<UUID> knownID) {
4444+ CanTypeWrapper<OpenedArchetypeType>
4445+ OpenedArchetypeType::get (CanType existential, const DeclContext *useDC,
4446+ Optional<UUID> knownID) {
44394447 Type interfaceType = GenericTypeParamType::get (
4440- /* isTypeSequence=*/ false , 0 , 0 , existential->getASTContext ());
4441- return get (existential, interfaceType, knownID);
4448+ /* isTypeSequence=*/ false ,
4449+ /* depth*/ useDC->getGenericContextDepth () + 1 , /* index*/ 0 ,
4450+ existential->getASTContext ());
4451+ return get (existential, interfaceType, useDC, knownID);
44424452}
44434453
44444454CanOpenedArchetypeType OpenedArchetypeType::get (CanType existential,
44454455 Type interfaceType,
4456+ const DeclContext *useDC,
44464457 Optional<UUID> knownID) {
4458+ assert (!interfaceType->hasArchetype () && " must be interface type" );
44474459 // FIXME: Opened archetypes can't be transformed because the
44484460 // the identity of the archetype has to be preserved. This
44494461 // means that simplifying an opened archetype in the constraint
@@ -4475,8 +4487,8 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
44754487 }
44764488
44774489 // / Create a generic environment for this opened archetype.
4478- auto genericEnv = GenericEnvironment::forOpenedExistential (
4479- existential, *knownID);
4490+ auto genericEnv =
4491+ GenericEnvironment::forOpenedExistential ( existential, useDC , *knownID);
44804492 openedExistentialEnvironments[*knownID] = genericEnv;
44814493
44824494 // Map the interface type into that environment.
@@ -4485,22 +4497,24 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
44854497 return CanOpenedArchetypeType (result);
44864498}
44874499
4488-
4489- CanType OpenedArchetypeType::getAny (CanType existential, Type interfaceType ) {
4500+ CanType OpenedArchetypeType::getAny (CanType existential, Type interfaceType,
4501+ const DeclContext *useDC ) {
44904502 if (auto metatypeTy = existential->getAs <ExistentialMetatypeType>()) {
44914503 auto instanceTy =
44924504 metatypeTy->getExistentialInstanceType ()->getCanonicalType ();
44934505 return CanMetatypeType::get (
4494- OpenedArchetypeType::getAny (instanceTy, interfaceType));
4506+ OpenedArchetypeType::getAny (instanceTy, interfaceType, useDC ));
44954507 }
44964508 assert (existential->isExistentialType ());
4497- return OpenedArchetypeType::get (existential, interfaceType);
4509+ return OpenedArchetypeType::get (existential, interfaceType, useDC );
44984510}
44994511
4500- CanType OpenedArchetypeType::getAny (CanType existential) {
4512+ CanType OpenedArchetypeType::getAny (CanType existential,
4513+ const DeclContext *useDC) {
45014514 Type interfaceType = GenericTypeParamType::get (
4502- /* isTypeSequence=*/ false , 0 , 0 , existential->getASTContext ());
4503- return getAny (existential, interfaceType);
4515+ /* isTypeSequence=*/ false , useDC->getGenericContextDepth () + 1 , 0 ,
4516+ existential->getASTContext ());
4517+ return getAny (existential, interfaceType, useDC);
45044518}
45054519
45064520void SubstitutionMap::Storage::Profile (
@@ -4655,12 +4669,23 @@ GenericEnvironment *GenericEnvironment::getIncomplete(
46554669}
46564670
46574671// / Create a new generic environment for an opened archetype.
4658- GenericEnvironment *GenericEnvironment::forOpenedExistential (
4659- Type existential, UUID uuid) {
4672+ GenericEnvironment *
4673+ GenericEnvironment::forOpenedExistential (Type existential,
4674+ const DeclContext *useDC, UUID uuid) {
46604675 auto &ctx = existential->getASTContext ();
4661- auto signature = ctx.getOpenedArchetypeSignature (existential);
4676+ auto signature = ctx.getOpenedArchetypeSignature (existential, useDC);
4677+
4678+ SubstitutionMap subs;
4679+ if (auto *useEnvironment = useDC->getGenericEnvironmentOfContext ()) {
4680+ subs = useEnvironment->getForwardingSubstitutionMap ();
4681+ }
4682+ return GenericEnvironment::forOpenedExistential (existential, signature, uuid);
4683+ }
46624684
4685+ GenericEnvironment *GenericEnvironment::forOpenedExistential (
4686+ Type existential, GenericSignature signature, UUID uuid) {
46634687 // Allocate and construct the new environment.
4688+ auto &ctx = existential->getASTContext ();
46644689 unsigned numGenericParams = signature.getGenericParams ().size ();
46654690 size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
46664691 OpenedGenericEnvironmentData, Type>(
@@ -5166,38 +5191,47 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
51665191 return canonicalSig;
51675192}
51685193
5169- CanGenericSignature ASTContext::getOpenedArchetypeSignature (Type type) {
5194+ CanGenericSignature
5195+ ASTContext::getOpenedArchetypeSignature (Type type, const DeclContext *useDC) {
51705196 assert (type->isExistentialType ());
5197+ assert (useDC && " Must have a working declaration context!" );
5198+
51715199 if (auto existential = type->getAs <ExistentialType>())
51725200 type = existential->getConstraintType ();
51735201
51745202 const CanType constraint = type->getCanonicalType ();
51755203 assert (!constraint->hasTypeParameter () && " This only works with archetypes" );
51765204
51775205 // The opened archetype signature for a protocol type is identical
5178- // to the protocol's own canonical generic signature.
5179- if (const auto protoTy = dyn_cast<ProtocolType>(constraint)) {
5180- return protoTy->getDecl ()->getGenericSignature ().getCanonicalSignature ();
5206+ // to the protocol's own canonical generic signature if there aren't any
5207+ // outer generic parameters to worry about.
5208+ if (!useDC->isGenericContext ()) {
5209+ if (const auto protoTy = dyn_cast<ProtocolType>(constraint)) {
5210+ return protoTy->getDecl ()->getGenericSignature ().getCanonicalSignature ();
5211+ }
51815212 }
51825213
5183- auto found = getImpl ().ExistentialSignatures .find (constraint);
5214+ // Otherwise we need to build a generic signature that captures any outer
5215+ // generic parameters. This ensures that we keep e.g. generic superclass
5216+ // existentials contained in a well-formed generic context.
5217+ auto found = getImpl ().ExistentialSignatures .find ({constraint, useDC});
51845218 if (found != getImpl ().ExistentialSignatures .end ())
51855219 return found->second ;
51865220
5221+ auto depth = useDC->getGenericContextDepth () + 1 ;
51875222 auto genericParam =
51885223 GenericTypeParamType::get (/* type sequence*/ false ,
5189- /* depth*/ 0 , /* index*/ 0 , *this );
5224+ /* depth*/ depth , /* index*/ 0 , *this );
51905225 Requirement requirement (RequirementKind::Conformance, genericParam,
51915226 constraint);
5192- auto genericSig = buildGenericSignature (*this ,
5193- GenericSignature (),
5194- {genericParam},
5195- {requirement});
5227+ auto genericSig = buildGenericSignature (
5228+ *this , useDC->getGenericSignatureOfContext ().getCanonicalSignature (),
5229+ {genericParam}, {requirement});
51965230
51975231 CanGenericSignature canGenericSig (genericSig);
51985232
51995233 auto result = getImpl ().ExistentialSignatures .insert (
5200- std::make_pair (constraint, canGenericSig));
5234+ std::make_pair (std::make_pair ( constraint, useDC) , canGenericSig));
52015235 assert (result.second );
52025236 (void ) result;
52035237
0 commit comments