Skip to content

Commit c0f9d29

Browse files
committed
AST: Move TypeBase::typeEraseOpenedArchetypesWithRoot() into ConstraintSystem.cpp
1 parent 04577fe commit c0f9d29

File tree

5 files changed

+97
-95
lines changed

5 files changed

+97
-95
lines changed

include/swift/AST/Types.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -757,10 +757,6 @@ class alignas(1 << TypeAlignInBits) TypeBase
757757
/// Retrieve the set of type parameter packs that occur within this type.
758758
void walkPackReferences(llvm::function_ref<bool (Type)> fn);
759759

760-
/// Replace opened archetypes with the given root with their most
761-
/// specific non-dependent upper bounds throughout this type.
762-
Type typeEraseOpenedArchetypesWithRoot(const OpenedArchetypeType *root) const;
763-
764760
/// Given a declaration context, returns a function type with the 'self'
765761
/// type curried as the input if the declaration context describes a type.
766762
/// Otherwise, returns the type itself.

include/swift/Sema/ConstraintSystem.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5776,12 +5776,19 @@ llvm::Optional<MatchCallArgumentResult> matchCallArguments(
57765776
Expr *getArgumentLabelTargetExpr(Expr *fn);
57775777

57785778
/// Given a type that includes an existential type that has been opened to
5779-
/// the given type variable, type-erase occurrences of that opened type
5780-
/// variable and anything that depends on it to their non-dependent bounds.
5779+
/// the given type variable, replace the opened type variable and its member
5780+
/// types with their upper bounds.
57815781
Type typeEraseOpenedExistentialReference(Type type, Type existentialBaseType,
57825782
TypeVariableType *openedTypeVar,
57835783
TypePosition outermostPosition);
57845784

5785+
5786+
/// Given a type that includes opened existential archetypes derived from
5787+
/// the given generic environment, replace the archetypes with their upper
5788+
/// bounds.
5789+
Type typeEraseOpenedArchetypesWithRoot(Type type,
5790+
const OpenedArchetypeType *root);
5791+
57855792
/// Returns true if a reference to a member on a given base type will apply
57865793
/// its curried self parameter, assuming it has one.
57875794
///

lib/AST/Type.cpp

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -606,87 +606,6 @@ void TypeBase::getRootOpenedExistentials(
606606
});
607607
}
608608

609-
Type TypeBase::typeEraseOpenedArchetypesWithRoot(
610-
const OpenedArchetypeType *root) const {
611-
assert(root->isRoot() && "Expected a root archetype");
612-
613-
Type type = Type(const_cast<TypeBase *>(this));
614-
if (!hasOpenedExistential())
615-
return type;
616-
617-
auto *env = root->getGenericEnvironment();
618-
auto sig = env->getGenericSignature();
619-
620-
unsigned metatypeDepth = 0;
621-
622-
std::function<Type(Type)> transformFn;
623-
transformFn = [&](Type type) -> Type {
624-
return type.transformRec([&](TypeBase *ty) -> llvm::Optional<Type> {
625-
// Don't recurse into children unless we have to.
626-
if (!ty->hasOpenedExistential())
627-
return Type(ty);
628-
629-
if (isa<MetatypeType>(ty)) {
630-
const auto instanceTy = ty->getMetatypeInstanceType();
631-
++metatypeDepth;
632-
const auto erasedTy = transformFn(instanceTy);
633-
--metatypeDepth;
634-
635-
if (instanceTy.getPointer() == erasedTy.getPointer()) {
636-
return Type(ty);
637-
}
638-
639-
return Type(ExistentialMetatypeType::get(erasedTy));
640-
}
641-
642-
// Opaque types whose substitutions involve this type parameter are
643-
// erased to their upper bound.
644-
if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(ty)) {
645-
for (auto replacementType :
646-
opaque->getSubstitutions().getReplacementTypes()) {
647-
if (replacementType->hasOpenedExistentialWithRoot(root)) {
648-
return opaque->getExistentialType();
649-
}
650-
}
651-
}
652-
653-
if (auto lvalue = dyn_cast<LValueType>(type)) {
654-
auto objTy = lvalue->getObjectType();
655-
auto erased = transformFn(objTy);
656-
if (erased.getPointer() == objTy.getPointer())
657-
return Type(lvalue);
658-
659-
return erased;
660-
}
661-
662-
auto *const archetype = dyn_cast<OpenedArchetypeType>(ty);
663-
if (!archetype) {
664-
// Recurse.
665-
return llvm::None;
666-
}
667-
668-
if (archetype->getGenericEnvironment() != env)
669-
return Type(ty);
670-
671-
Type erasedTy;
672-
if (root->isEqual(archetype)) {
673-
erasedTy = root->getExistentialType();
674-
} else {
675-
erasedTy = sig->getUpperBound(archetype->getInterfaceType());
676-
}
677-
678-
if (metatypeDepth) {
679-
if (const auto existential = erasedTy->getAs<ExistentialType>())
680-
return existential->getConstraintType();
681-
}
682-
683-
return erasedTy;
684-
});
685-
};
686-
687-
return transformFn(type);
688-
}
689-
690609
Type TypeBase::addCurriedSelfType(const DeclContext *dc) {
691610
if (!dc->isTypeContext())
692611
return this;

lib/Sema/CSApply.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,8 @@ namespace {
880880
Type resultTy;
881881
resultTy = cs.getType(result);
882882
if (resultTy->hasOpenedExistentialWithRoot(record.Archetype)) {
883-
Type erasedTy = resultTy->typeEraseOpenedArchetypesWithRoot(
884-
record.Archetype);
883+
Type erasedTy = constraints::typeEraseOpenedArchetypesWithRoot(
884+
resultTy, record.Archetype);
885885
auto range = result->getSourceRange();
886886
result = coerceToType(result, erasedTy, locator);
887887
// FIXME: Implement missing tuple-to-tuple conversion
@@ -1590,8 +1590,8 @@ namespace {
15901590
} else {
15911591
// Erase opened existentials from the type of the thunk; we're
15921592
// going to open the existential inside the thunk's body.
1593-
containerTy = containerTy->typeEraseOpenedArchetypesWithRoot(
1594-
knownOpened->second);
1593+
containerTy = constraints::typeEraseOpenedArchetypesWithRoot(
1594+
containerTy, knownOpened->second);
15951595
selfTy = containerTy;
15961596
}
15971597
}
@@ -1673,8 +1673,8 @@ namespace {
16731673
// If the base was an opened existential, erase the opened
16741674
// existential.
16751675
if (openedExistential) {
1676-
refType = refType->typeEraseOpenedArchetypesWithRoot(
1677-
baseTy->castTo<OpenedArchetypeType>());
1676+
refType = constraints::typeEraseOpenedArchetypesWithRoot(
1677+
refType, baseTy->castTo<OpenedArchetypeType>());
16781678
}
16791679

16801680
return refType;
@@ -1884,8 +1884,8 @@ namespace {
18841884
getConstraintSystem().getConstraintLocator(memberLocator));
18851885
if (knownOpened != solution.OpenedExistentialTypes.end()) {
18861886
curryThunkTy =
1887-
curryThunkTy
1888-
->typeEraseOpenedArchetypesWithRoot(knownOpened->second)
1887+
constraints::typeEraseOpenedArchetypesWithRoot(
1888+
curryThunkTy, knownOpened->second)
18891889
->castTo<FunctionType>();
18901890
}
18911891
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,86 @@ Type constraints::typeEraseOpenedExistentialReference(
22662266
});
22672267
}
22682268

2269+
Type constraints::typeEraseOpenedArchetypesWithRoot(
2270+
Type type, const OpenedArchetypeType *root) {
2271+
assert(root->isRoot() && "Expected a root archetype");
2272+
2273+
if (!type->hasOpenedExistential())
2274+
return type;
2275+
2276+
auto *env = root->getGenericEnvironment();
2277+
auto sig = env->getGenericSignature();
2278+
2279+
unsigned metatypeDepth = 0;
2280+
2281+
std::function<Type(Type)> transformFn;
2282+
transformFn = [&](Type type) -> Type {
2283+
return type.transformRec([&](TypeBase *ty) -> llvm::Optional<Type> {
2284+
// Don't recurse into children unless we have to.
2285+
if (!ty->hasOpenedExistential())
2286+
return Type(ty);
2287+
2288+
if (isa<MetatypeType>(ty)) {
2289+
const auto instanceTy = ty->getMetatypeInstanceType();
2290+
++metatypeDepth;
2291+
const auto erasedTy = transformFn(instanceTy);
2292+
--metatypeDepth;
2293+
2294+
if (instanceTy.getPointer() == erasedTy.getPointer()) {
2295+
return Type(ty);
2296+
}
2297+
2298+
return Type(ExistentialMetatypeType::get(erasedTy));
2299+
}
2300+
2301+
// Opaque types whose substitutions involve this type parameter are
2302+
// erased to their upper bound.
2303+
if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(ty)) {
2304+
for (auto replacementType :
2305+
opaque->getSubstitutions().getReplacementTypes()) {
2306+
if (replacementType->hasOpenedExistentialWithRoot(root)) {
2307+
return opaque->getExistentialType();
2308+
}
2309+
}
2310+
}
2311+
2312+
if (auto lvalue = dyn_cast<LValueType>(type)) {
2313+
auto objTy = lvalue->getObjectType();
2314+
auto erased = transformFn(objTy);
2315+
if (erased.getPointer() == objTy.getPointer())
2316+
return Type(lvalue);
2317+
2318+
return erased;
2319+
}
2320+
2321+
auto *const archetype = dyn_cast<OpenedArchetypeType>(ty);
2322+
if (!archetype) {
2323+
// Recurse.
2324+
return llvm::None;
2325+
}
2326+
2327+
if (archetype->getGenericEnvironment() != env)
2328+
return Type(ty);
2329+
2330+
Type erasedTy;
2331+
if (root->isEqual(archetype)) {
2332+
erasedTy = root->getExistentialType();
2333+
} else {
2334+
erasedTy = sig->getUpperBound(archetype->getInterfaceType());
2335+
}
2336+
2337+
if (metatypeDepth) {
2338+
if (const auto existential = erasedTy->getAs<ExistentialType>())
2339+
return existential->getConstraintType();
2340+
}
2341+
2342+
return erasedTy;
2343+
});
2344+
};
2345+
2346+
return transformFn(type);
2347+
}
2348+
22692349
Type ConstraintSystem::getMemberReferenceTypeFromOpenedType(
22702350
Type &openedType, Type baseObjTy, ValueDecl *value, DeclContext *outerDC,
22712351
ConstraintLocator *locator, bool hasAppliedSelf,

0 commit comments

Comments
 (0)