Skip to content

Commit 4b80f0a

Browse files
authored
Merge pull request swiftlang#63736 from slavapestov/archetype-subst-cleanup
Small cleanup of ArchetypeType handling in substType()
2 parents 8873f19 + 29a45d9 commit 4b80f0a

File tree

1 file changed

+52
-55
lines changed

1 file changed

+52
-55
lines changed

lib/AST/Type.cpp

Lines changed: 52 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,9 +3564,14 @@ bool ArchetypeType::requiresClass() const {
35643564
Type ArchetypeType::getNestedType(AssociatedTypeDecl *assocType) {
35653565
Type interfaceType = getInterfaceType();
35663566
Type memberInterfaceType =
3567-
DependentMemberType::get(interfaceType, assocType->getName());
3568-
return getGenericEnvironment()->getOrCreateArchetypeFromInterfaceType(
3569-
memberInterfaceType);
3567+
DependentMemberType::get(interfaceType, assocType);
3568+
auto genericSig = getGenericEnvironment()->getGenericSignature();
3569+
if (genericSig->isValidTypeParameter(memberInterfaceType)) {
3570+
return getGenericEnvironment()->getOrCreateArchetypeFromInterfaceType(
3571+
memberInterfaceType);
3572+
}
3573+
3574+
return Type();
35703575
}
35713576

35723577
Type ArchetypeType::getNestedTypeByName(Identifier name) {
@@ -4387,24 +4392,9 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
43874392
return DependentMemberType::get(baseType, name);
43884393
};
43894394

4390-
// If we don't have a substituted base type, fail.
4391-
if (!substBase) return failed();
4392-
43934395
if (auto *selfType = substBase->getAs<DynamicSelfType>())
43944396
substBase = selfType->getSelfType();
43954397

4396-
// If the parent is an archetype, extract the child archetype with the
4397-
// given name.
4398-
if (auto archetypeParent = substBase->getAs<ArchetypeType>()) {
4399-
if (Type memberArchetypeByName = archetypeParent->getNestedTypeByName(name))
4400-
return memberArchetypeByName;
4401-
4402-
// If looking for an associated type and the archetype is constrained to a
4403-
// class, continue to the default associated type lookup
4404-
if (!assocType || !archetypeParent->getSuperclass())
4405-
return failed();
4406-
}
4407-
44084398
// If the parent is a type variable or a member rooted in a type variable,
44094399
// or if the parent is a type parameter, we're done. Also handle
44104400
// UnresolvedType here, which can come up in diagnostics.
@@ -4413,53 +4403,63 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
44134403
substBase->is<UnresolvedType>())
44144404
return getDependentMemberType(substBase);
44154405

4416-
// Retrieve the member type with the given name.
4406+
// All remaining cases require an associated type declaration and not just
4407+
// the name of a member type.
4408+
if (!assocType)
4409+
return failed();
44174410

4418-
// If we know the associated type, look in the witness table.
4419-
if (assocType) {
4420-
auto proto = assocType->getProtocol();
4421-
ProtocolConformanceRef conformance =
4422-
lookupConformances(origBase->getCanonicalType(), substBase, proto);
4411+
// If the parent is an archetype, extract the child archetype with the
4412+
// given name.
4413+
if (auto archetypeParent = substBase->getAs<ArchetypeType>()) {
4414+
if (Type memberArchetypeByName = archetypeParent->getNestedType(assocType))
4415+
return memberArchetypeByName;
44234416

4424-
if (conformance.isInvalid())
4417+
// If looking for an associated type and the archetype is constrained to a
4418+
// class, continue to the default associated type lookup
4419+
if (!assocType || !archetypeParent->getSuperclass())
44254420
return failed();
4421+
}
44264422

4427-
Type witnessTy;
4428-
4429-
// Retrieve the type witness.
4430-
if (conformance.isPack()) {
4431-
auto *packConformance = conformance.getPack();
4423+
auto proto = assocType->getProtocol();
4424+
ProtocolConformanceRef conformance =
4425+
lookupConformances(origBase->getCanonicalType(), substBase, proto);
44324426

4433-
witnessTy = packConformance->getAssociatedType(
4434-
assocType->getDeclaredInterfaceType());
4435-
} else if (conformance.isConcrete()) {
4436-
auto witness =
4437-
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
4427+
if (conformance.isInvalid())
4428+
return failed();
44384429

4439-
witnessTy = witness.getWitnessType();
4440-
if (!witnessTy || witnessTy->hasError())
4441-
return failed();
4430+
Type witnessTy;
44424431

4443-
// This is a hacky feature allowing code completion to migrate to
4444-
// using Type::subst() without changing output.
4445-
if (options & SubstFlags::DesugarMemberTypes) {
4446-
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
4447-
witnessTy = aliasType->getSinglyDesugaredType();
4432+
// Retrieve the type witness.
4433+
if (conformance.isPack()) {
4434+
auto *packConformance = conformance.getPack();
44484435

4449-
// Another hack. If the type witness is a opaque result type. They can
4450-
// only be referred using the name of the associated type.
4451-
if (witnessTy->is<OpaqueTypeArchetypeType>())
4452-
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
4453-
}
4454-
}
4436+
witnessTy = packConformance->getAssociatedType(
4437+
assocType->getDeclaredInterfaceType());
4438+
} else if (conformance.isConcrete()) {
4439+
auto witness =
4440+
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
44554441

4456-
if (!witnessTy || witnessTy->is<ErrorType>())
4442+
witnessTy = witness.getWitnessType();
4443+
if (!witnessTy || witnessTy->hasError())
44574444
return failed();
44584445

4459-
return witnessTy;
4446+
// This is a hacky feature allowing code completion to migrate to
4447+
// using Type::subst() without changing output.
4448+
if (options & SubstFlags::DesugarMemberTypes) {
4449+
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
4450+
witnessTy = aliasType->getSinglyDesugaredType();
4451+
4452+
// Another hack. If the type witness is a opaque result type. They can
4453+
// only be referred using the name of the associated type.
4454+
if (witnessTy->is<OpaqueTypeArchetypeType>())
4455+
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
4456+
}
44604457
}
44614458

4462-
return failed();
4459+
if (!witnessTy || witnessTy->is<ErrorType>())
4460+
return failed();
4461+
4462+
return witnessTy;
44634463
}
44644464

44654465
ProtocolConformanceRef LookUpConformanceInModule::
@@ -4690,9 +4690,6 @@ static Type substType(Type derivedType,
46904690
if (auto depMemTy = dyn_cast<DependentMemberType>(type)) {
46914691
auto newBase = substType(depMemTy->getBase(),
46924692
substitutions, lookupConformances, options);
4693-
if (!newBase)
4694-
return Type();
4695-
46964693
return getMemberForBaseType(lookupConformances,
46974694
depMemTy->getBase(), newBase,
46984695
depMemTy->getAssocType(),

0 commit comments

Comments
 (0)