Skip to content

Commit a27d6cf

Browse files
committed
AST: Fold getMemberForBaseType() into TypeSubstituter::transformDependentMemberType()
1 parent 26241a5 commit a27d6cf

File tree

1 file changed

+92
-101
lines changed

1 file changed

+92
-101
lines changed

lib/AST/TypeSubstitution.cpp

Lines changed: 92 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -92,101 +92,6 @@ CanGenericFunctionType::substGenericArgs(SubstitutionMap subs) const {
9292
getPointer()->substGenericArgs(subs)->getCanonicalType());
9393
}
9494

95-
static Type getMemberForBaseType(InFlightSubstitution &IFS,
96-
Type origBase,
97-
Type substBase,
98-
AssociatedTypeDecl *assocType,
99-
Identifier name,
100-
unsigned level) {
101-
// Produce a dependent member type for the given base type.
102-
auto getDependentMemberType = [&](Type baseType) {
103-
if (assocType)
104-
return DependentMemberType::get(baseType, assocType);
105-
106-
return DependentMemberType::get(baseType, name);
107-
};
108-
109-
// Produce a failed result.
110-
auto failed = [&]() -> Type {
111-
Type baseType = ErrorType::get(substBase ? substBase : origBase);
112-
if (assocType)
113-
return DependentMemberType::get(baseType, assocType);
114-
115-
return DependentMemberType::get(baseType, name);
116-
};
117-
118-
if (auto *selfType = substBase->getAs<DynamicSelfType>())
119-
substBase = selfType->getSelfType();
120-
121-
// If the parent is a type variable or a member rooted in a type variable,
122-
// or if the parent is a type parameter, we're done. Also handle
123-
// UnresolvedType here, which can come up in diagnostics.
124-
if (substBase->isTypeVariableOrMember() ||
125-
substBase->isTypeParameter() ||
126-
substBase->is<UnresolvedType>())
127-
return getDependentMemberType(substBase);
128-
129-
// All remaining cases require an associated type declaration and not just
130-
// the name of a member type.
131-
if (!assocType)
132-
return failed();
133-
134-
// If the parent is an archetype, extract the child archetype with the
135-
// given name.
136-
if (auto archetypeParent = substBase->getAs<ArchetypeType>()) {
137-
if (Type memberArchetypeByName = archetypeParent->getNestedType(assocType))
138-
return memberArchetypeByName;
139-
140-
// If looking for an associated type and the archetype is constrained to a
141-
// class, continue to the default associated type lookup
142-
if (!assocType || !archetypeParent->getSuperclass())
143-
return failed();
144-
}
145-
146-
auto proto = assocType->getProtocol();
147-
ProtocolConformanceRef conformance =
148-
IFS.lookupConformance(origBase->getCanonicalType(), substBase,
149-
proto, level);
150-
151-
if (conformance.isInvalid())
152-
return failed();
153-
154-
Type witnessTy;
155-
156-
// Retrieve the type witness.
157-
if (conformance.isPack()) {
158-
auto *packConformance = conformance.getPack();
159-
160-
witnessTy = packConformance->getAssociatedType(
161-
assocType->getDeclaredInterfaceType());
162-
} else if (conformance.isConcrete()) {
163-
auto witness =
164-
conformance.getConcrete()->getTypeWitnessAndDecl(assocType,
165-
IFS.getOptions());
166-
167-
witnessTy = witness.getWitnessType();
168-
if (!witnessTy || witnessTy->hasError())
169-
return failed();
170-
171-
// This is a hacky feature allowing code completion to migrate to
172-
// using Type::subst() without changing output.
173-
if (IFS.getOptions() & SubstFlags::DesugarMemberTypes) {
174-
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
175-
witnessTy = aliasType->getSinglyDesugaredType();
176-
177-
// Another hack. If the type witness is a opaque result type. They can
178-
// only be referred using the name of the associated type.
179-
if (witnessTy->is<OpaqueTypeArchetypeType>())
180-
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
181-
}
182-
}
183-
184-
if (!witnessTy || witnessTy->is<ErrorType>())
185-
return failed();
186-
187-
return witnessTy;
188-
}
189-
19095
ProtocolConformanceRef LookUpConformanceInModule::
19196
operator()(CanType dependentType, Type conformingReplacementType,
19297
ProtocolDecl *conformedProtocol) const {
@@ -609,12 +514,98 @@ Type TypeSubstituter::transformPackElementType(PackElementType *element,
609514

610515
Type TypeSubstituter::transformDependentMemberType(DependentMemberType *dependent,
611516
TypePosition pos) {
612-
auto newBase = doIt(dependent->getBase(), TypePosition::Invariant);
613-
return getMemberForBaseType(IFS,
614-
dependent->getBase(), newBase,
615-
dependent->getAssocType(),
616-
dependent->getName(),
617-
level);
517+
auto origBase = dependent->getBase();
518+
auto substBase = doIt(origBase, TypePosition::Invariant);
519+
520+
auto *assocType = dependent->getAssocType();
521+
522+
// Produce a dependent member type for the given base type.
523+
auto getDependentMemberType = [&](Type baseType) {
524+
if (assocType)
525+
return DependentMemberType::get(baseType, assocType);
526+
527+
return DependentMemberType::get(baseType, dependent->getName());
528+
};
529+
530+
// Produce a failed result.
531+
auto failed = [&]() -> Type {
532+
Type baseType = ErrorType::get(substBase);
533+
if (assocType)
534+
return DependentMemberType::get(baseType, assocType);
535+
536+
return DependentMemberType::get(baseType, dependent->getName());
537+
};
538+
539+
if (auto *selfType = substBase->getAs<DynamicSelfType>())
540+
substBase = selfType->getSelfType();
541+
542+
// If the parent is a type variable or a member rooted in a type variable,
543+
// or if the parent is a type parameter, we're done. Also handle
544+
// UnresolvedType here, which can come up in diagnostics.
545+
if (substBase->isTypeVariableOrMember() ||
546+
substBase->isTypeParameter() ||
547+
substBase->is<UnresolvedType>())
548+
return getDependentMemberType(substBase);
549+
550+
// All remaining cases require an associated type declaration and not just
551+
// the name of a member type.
552+
if (!assocType)
553+
return failed();
554+
555+
// If the parent is an archetype, extract the child archetype with the
556+
// given name.
557+
if (auto archetypeParent = substBase->getAs<ArchetypeType>()) {
558+
if (Type memberArchetypeByName = archetypeParent->getNestedType(assocType))
559+
return memberArchetypeByName;
560+
561+
// If looking for an associated type and the archetype is constrained to a
562+
// class, continue to the default associated type lookup
563+
if (!assocType || !archetypeParent->getSuperclass())
564+
return failed();
565+
}
566+
567+
auto proto = assocType->getProtocol();
568+
ProtocolConformanceRef conformance =
569+
IFS.lookupConformance(origBase->getCanonicalType(), substBase,
570+
proto, level);
571+
572+
if (conformance.isInvalid())
573+
return failed();
574+
575+
Type witnessTy;
576+
577+
// Retrieve the type witness.
578+
if (conformance.isPack()) {
579+
auto *packConformance = conformance.getPack();
580+
581+
witnessTy = packConformance->getAssociatedType(
582+
assocType->getDeclaredInterfaceType());
583+
} else if (conformance.isConcrete()) {
584+
auto witness =
585+
conformance.getConcrete()->getTypeWitnessAndDecl(assocType,
586+
IFS.getOptions());
587+
588+
witnessTy = witness.getWitnessType();
589+
if (!witnessTy || witnessTy->hasError())
590+
return failed();
591+
592+
// This is a hacky feature allowing code completion to migrate to
593+
// using Type::subst() without changing output.
594+
if (IFS.getOptions() & SubstFlags::DesugarMemberTypes) {
595+
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
596+
witnessTy = aliasType->getSinglyDesugaredType();
597+
598+
// Another hack. If the type witness is a opaque result type. They can
599+
// only be referred using the name of the associated type.
600+
if (witnessTy->is<OpaqueTypeArchetypeType>())
601+
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
602+
}
603+
}
604+
605+
if (!witnessTy || witnessTy->is<ErrorType>())
606+
return failed();
607+
608+
return witnessTy;
618609
}
619610

620611
SubstitutionMap TypeSubstituter::transformSubstitutionMap(SubstitutionMap subs) {

0 commit comments

Comments
 (0)