Skip to content

Commit 87c0b2d

Browse files
committed
AST: Implement support for projecting member types from PackType via Type::subst()
1 parent cbce4a5 commit 87c0b2d

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

lib/AST/Type.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/AST/GenericEnvironment.h"
3030
#include "swift/AST/LazyResolver.h"
3131
#include "swift/AST/Module.h"
32+
#include "swift/AST/PackConformance.h"
3233
#include "swift/AST/ParameterList.h"
3334
#include "swift/AST/ProtocolConformance.h"
3435
#include "swift/AST/SILLayout.h"
@@ -4365,10 +4366,6 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
43654366

43664367
// Retrieve the member type with the given name.
43674368

4368-
// Tuples don't have member types.
4369-
if (substBase->is<TupleType>())
4370-
return failed();
4371-
43724369
// If we know the associated type, look in the witness table.
43734370
if (assocType) {
43744371
auto proto = assocType->getProtocol();
@@ -4377,30 +4374,37 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
43774374

43784375
if (conformance.isInvalid())
43794376
return failed();
4380-
if (!conformance.isConcrete())
4381-
return failed();
4382-
4383-
// Retrieve the type witness.
4384-
auto witness =
4385-
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
4386-
4387-
auto witnessTy = witness.getWitnessType();
4388-
if (!witnessTy || witnessTy->hasError())
4389-
return failed();
43904377

4391-
// This is a hacky feature allowing code completion to migrate to
4392-
// using Type::subst() without changing output.
4393-
if (options & SubstFlags::DesugarMemberTypes) {
4394-
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
4395-
witnessTy = aliasType->getSinglyDesugaredType();
4378+
Type witnessTy;
43964379

4397-
// Another hack. If the type witness is a opaque result type. They can
4398-
// only be referred using the name of the associated type.
4399-
if (witnessTy->is<OpaqueTypeArchetypeType>())
4400-
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
4380+
// Retrieve the type witness.
4381+
if (conformance.isPack()) {
4382+
auto *packConformance = conformance.getPack();
4383+
4384+
witnessTy = packConformance->getAssociatedType(
4385+
assocType->getDeclaredInterfaceType());
4386+
} else if (conformance.isConcrete()) {
4387+
auto witness =
4388+
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
4389+
4390+
witnessTy = witness.getWitnessType();
4391+
if (!witnessTy || witnessTy->hasError())
4392+
return failed();
4393+
4394+
// This is a hacky feature allowing code completion to migrate to
4395+
// using Type::subst() without changing output.
4396+
if (options & SubstFlags::DesugarMemberTypes) {
4397+
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
4398+
witnessTy = aliasType->getSinglyDesugaredType();
4399+
4400+
// Another hack. If the type witness is a opaque result type. They can
4401+
// only be referred using the name of the associated type.
4402+
if (witnessTy->is<OpaqueTypeArchetypeType>())
4403+
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
4404+
}
44014405
}
44024406

4403-
if (witnessTy->is<ErrorType>())
4407+
if (!witnessTy || witnessTy->is<ErrorType>())
44044408
return failed();
44054409

44064410
return witnessTy;

0 commit comments

Comments
 (0)