diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index 08f254f2979..51aafa17b2d 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -43,6 +43,7 @@ namespace swift { class ValueDecl; class Decl; class DeclRefExpr; + class OpenedArchetypeType; class Pattern; class SubscriptDecl; class Stmt; @@ -2694,7 +2695,7 @@ public: /// Retrieve the existential value that is being opened. Expr *getExistentialValue() const { return ExistentialValue; } - /// Set the existential value that is being opened. + /// Set the existential val ue that is being opened. void setExistentialValue(Expr *expr) { ExistentialValue = expr; } /// Retrieve the opaque value representing the value (of archetype @@ -2703,7 +2704,7 @@ public: /// Retrieve the opened archetype, which can only be referenced /// within this expression's subexpression. - ArchetypeType *getOpenedArchetype() const; + OpenedArchetypeType *getOpenedArchetype() const; static bool classof(const Expr *E) { return E->getKind() == ExprKind::OpenExistential; diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 0ce385dbcad..cf5112fc3bb 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -55,6 +55,7 @@ namespace swift { class GenericSignature; class Identifier; class InOutType; + class OpenedArchetypeType; enum class ReferenceCounting : uint8_t; enum class ResilienceExpansion : unsigned; class SILModule; @@ -548,7 +549,7 @@ public: /// Determine whether the type involves the given opened existential /// archetype. - bool hasOpenedExistential(ArchetypeType *opened); + bool hasOpenedExistential(OpenedArchetypeType *opened); /// Determine whether the type is an opened existential type. /// @@ -561,11 +562,11 @@ public: /// Retrieve the set of opened existential archetypes that occur /// within this type. - void getOpenedExistentials(SmallVectorImpl &opened); + void getOpenedExistentials(SmallVectorImpl &opened); /// Erase the given opened existential type by replacing it with its /// existential type throughout the given type. - Type eraseOpenedExistential(ArchetypeType *opened); + Type eraseOpenedExistential(OpenedArchetypeType *opened); /// Erase DynamicSelfType from the given type by replacing it with its /// underlying type. @@ -672,7 +673,7 @@ public: bool isClassExistentialType(); /// Opens an existential instance or meta-type and returns the opened type. - Type openAnyExistentialType(ArchetypeType *&opened); + Type openAnyExistentialType(OpenedArchetypeType *&opened); /// Break an existential down into a set of constraints. ExistentialLayout getExistentialLayout(); @@ -4571,6 +4572,8 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(SubstitutableType, Type) template using ArchetypeTrailingObjects = llvm::TrailingObjects; + +class PrimaryArchetypeType; /// An archetype is a type that represents a runtime type that is /// known to conform to some set of requirements. @@ -4612,47 +4615,6 @@ protected: } public: - /// getNew - Create a new nested archetype with the given associated type. - /// - /// The ConformsTo array will be copied into the ASTContext by this routine. - /// - /// TODO: Move to NestedArchetypeType - static CanTypeWrapper - getNew(const ASTContext &Ctx, ArchetypeType *Parent, - DependentMemberType *InterfaceType, - SmallVectorImpl &ConformsTo, - Type Superclass, LayoutConstraint Layout); - - /// getNew - Create a new primary archetype with the given name. - /// - /// The ConformsTo array will be minimized then copied into the ASTContext - /// by this routine. - /// - /// TODO: Move to PrimaryArchetypeType - static CanTypeWrapper - getNew(const ASTContext &Ctx, - GenericEnvironment *GenericEnv, - GenericTypeParamType *InterfaceType, - SmallVectorImpl &ConformsTo, - Type Superclass, LayoutConstraint Layout); - - /// Create a new archetype that represents the opened type - /// of an existential value. - /// - /// \param existential The existential type to open. - /// - /// \param knownID When non-empty, the known ID of the archetype. When empty, - /// a fresh archetype with a unique ID will be opened. - static CanTypeWrapper - getOpened(Type existential, - Optional knownID = None); - - /// Create a new archetype that represents the opened type - /// of an existential value. - /// - /// \param existential The existential type or existential metatype to open. - static CanType getAnyOpened(Type existential); - /// Retrieve the name of this archetype. Identifier getName() const; @@ -4660,33 +4622,10 @@ public: /// archetype. std::string getFullName() const; - /// Retrieve the parent of this archetype, or null if this is a - /// primary archetype. - ArchetypeType *getParent() const; - - /// Retrieve the opened existential type. - /// TODO: Remove and leave on only OpenedArchetypeType - Type getOpenedExistentialType() const; - - /// Retrieve the generic environment in which this archetype resides. - /// - /// Note: opened archetypes currently don't have generic environments. - /// - /// TODO: Remove and leave only on PrimaryArchetypeType - GenericEnvironment *getGenericEnvironment() const; - /// Retrieve the interface type of this associated type, which will either /// be a GenericTypeParamType or a DependentMemberType. Type getInterfaceType() const { return InterfaceType; } - /// Retrieve the associated type to which this archetype (if it is a nested - /// archetype) corresponds. - /// - /// This associated type will have the same name as the archetype and will - /// be a member of one of the protocols to which the parent archetype - /// conforms. - AssociatedTypeDecl *getAssocType() const; - /// getConformsTo - Retrieve the set of protocols to which this substitutable /// type shall conform. ArrayRef getConformsTo() const { @@ -4759,18 +4698,8 @@ public: /// Register a nested type with the given name. void registerNestedType(Identifier name, Type nested); - /// isPrimary - Determine whether this is the archetype for a 'primary' - /// archetype, e.g., one that is not nested within another archetype and is - /// not an opened existential. - bool isPrimary() const; - /// getPrimary - Return the primary archetype parent of this archetype. - ArchetypeType *getPrimary() const; - - /// Retrieve the ID number of this opened existential. - /// - /// TODO: Remove and place on OpenedArchetypeType only - UUID getOpenedExistentialID() const; + PrimaryArchetypeType *getPrimary() const; // Implement isa/cast/dyncast/etc. static bool classof(const TypeBase *T) { @@ -4786,9 +4715,6 @@ protected: Type Superclass, LayoutConstraint Layout); }; BEGIN_CAN_TYPE_WRAPPER(ArchetypeType, SubstitutableType) -CanArchetypeType getParent() const { - return CanArchetypeType(getPointer()->getParent()); -} END_CAN_TYPE_WRAPPER(ArchetypeType, SubstitutableType) /// An archetype that represents a primary generic argument inside the generic @@ -4802,6 +4728,17 @@ class PrimaryArchetypeType final : public ArchetypeType, GenericEnvironment *Environment; public: + /// getNew - Create a new primary archetype with the given name. + /// + /// The ConformsTo array will be minimized then copied into the ASTContext + /// by this routine. + static CanTypeWrapper + getNew(const ASTContext &Ctx, + GenericEnvironment *GenericEnv, + GenericTypeParamType *InterfaceType, + SmallVectorImpl &ConformsTo, + Type Superclass, LayoutConstraint Layout); + /// Retrieve the generic environment in which this archetype resides. GenericEnvironment *getGenericEnvironment() const { return Environment; @@ -4830,6 +4767,23 @@ class OpenedArchetypeType final : public ArchetypeType, TypeBase *Opened; UUID ID; public: + /// Create a new archetype that represents the opened type + /// of an existential value. + /// + /// \param existential The existential type to open. + /// + /// \param knownID When non-empty, the known ID of the archetype. When empty, + /// a fresh archetype with a unique ID will be opened. + static CanTypeWrapper + get(Type existential, + Optional knownID = None); + + /// Create a new archetype that represents the opened type + /// of an existential value. + /// + /// \param existential The existential type or existential metatype to open. + static CanType getAny(Type existential); + /// Retrieve the ID number of this opened existential. UUID getOpenedExistentialID() const { return ID; } @@ -4860,11 +4814,22 @@ class NestedArchetypeType final : public ArchetypeType, ArchetypeType *Parent; public: + /// getNew - Create a new nested archetype with the given associated type. + /// + /// The ConformsTo array will be copied into the ASTContext by this routine. + static CanTypeWrapper + getNew(const ASTContext &Ctx, ArchetypeType *Parent, + DependentMemberType *InterfaceType, + SmallVectorImpl &ConformsTo, + Type Superclass, LayoutConstraint Layout); + /// Retrieve the parent of this archetype, or null if this is a /// primary archetype. ArchetypeType *getParent() const { return Parent; } + + AssociatedTypeDecl *getAssocType() const; static bool classof(const TypeBase *T) { return T->getKind() == TypeKind::NestedArchetype; @@ -4878,29 +4843,11 @@ private: Type Superclass, LayoutConstraint Layout); }; BEGIN_CAN_TYPE_WRAPPER(NestedArchetypeType, ArchetypeType) +CanArchetypeType getParent() const { + return CanArchetypeType(getPointer()->getParent()); +} END_CAN_TYPE_WRAPPER(NestedArchetypeType, ArchetypeType) -inline bool ArchetypeType::isPrimary() const { - return isa(this); -} - -inline UUID ArchetypeType::getOpenedExistentialID() const { - return cast(this)->getOpenedExistentialID(); -} - -inline Type ArchetypeType::getOpenedExistentialType() const { - if (auto child = dyn_cast(this)) - return child->getOpenedExistentialType(); - return nullptr; -} - -inline ArchetypeType *ArchetypeType::getParent() const { - if (auto child = dyn_cast(this)) - return child->getParent(); - - return nullptr; -} - template const Type *ArchetypeType::getSubclassTrailingObjects() const { if (auto contextTy = dyn_cast(this)) { @@ -5256,9 +5203,7 @@ inline bool TypeBase::isOpenedExistential() const { return false; CanType T = getCanonicalType(); - if (auto archetype = dyn_cast(T)) - return !archetype->getOpenedExistentialType().isNull(); - return false; + return isa(T); } inline bool TypeBase::isOpenedExistentialWithError() { @@ -5266,10 +5211,9 @@ inline bool TypeBase::isOpenedExistentialWithError() { return false; CanType T = getCanonicalType(); - if (auto archetype = dyn_cast(T)) { + if (auto archetype = dyn_cast(T)) { auto openedExistentialType = archetype->getOpenedExistentialType(); - return (!openedExistentialType.isNull() && - openedExistentialType->isExistentialWithError()); + return openedExistentialType->isExistentialWithError(); } return false; } diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h index 2cb17aea4d5..12186cd4667 100644 --- a/include/swift/SIL/SILCloner.h +++ b/include/swift/SIL/SILCloner.h @@ -253,9 +253,9 @@ public: return asImpl().remapASTType(ty); } - void remapOpenedType(CanArchetypeType archetypeTy) { + void remapOpenedType(CanOpenedArchetypeType archetypeTy) { auto existentialTy = archetypeTy->getOpenedExistentialType()->getCanonicalType(); - auto replacementTy = ArchetypeType::getOpened(getOpASTType(existentialTy)); + auto replacementTy = OpenedArchetypeType::get(getOpASTType(existentialTy)); registerOpenedExistentialRemapping(archetypeTy, replacementTy); } @@ -1878,7 +1878,7 @@ template void SILCloner::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) { // Create a new archetype for this opened existential type. - remapOpenedType(Inst->getType().castTo()); + remapOpenedType(Inst->getType().castTo()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); recordClonedInstruction( @@ -1891,7 +1891,7 @@ template void SILCloner::visitOpenExistentialValueInst( OpenExistentialValueInst *Inst) { // Create a new archetype for this opened existential type. - remapOpenedType(Inst->getType().castTo()); + remapOpenedType(Inst->getType().castTo()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); recordClonedInstruction(Inst, getBuilder().createOpenExistentialValue( @@ -1911,7 +1911,7 @@ visitOpenExistentialMetatypeInst(OpenExistentialMetatypeInst *Inst) { exType = exMetatype.getInstanceType(); openedType = cast(openedType).getInstanceType(); } - remapOpenedType(cast(openedType)); + remapOpenedType(cast(openedType)); if (!Inst->getOperand()->getType().canUseExistentialRepresentation( Inst->getModule(), ExistentialRepresentation::Class)) { @@ -1935,7 +1935,7 @@ void SILCloner:: visitOpenExistentialRefInst(OpenExistentialRefInst *Inst) { // Create a new archetype for this opened existential type. - remapOpenedType(Inst->getType().castTo()); + remapOpenedType(Inst->getType().castTo()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); recordClonedInstruction(Inst, getBuilder().createOpenExistentialRef( @@ -1949,7 +1949,7 @@ void SILCloner:: visitOpenExistentialBoxInst(OpenExistentialBoxInst *Inst) { // Create a new archetype for this opened existential type. - remapOpenedType(Inst->getType().castTo()); + remapOpenedType(Inst->getType().castTo()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); recordClonedInstruction(Inst, getBuilder().createOpenExistentialBox( @@ -1963,7 +1963,7 @@ void SILCloner:: visitOpenExistentialBoxValueInst(OpenExistentialBoxValueInst *Inst) { // Create a new archetype for this opened existential type. - remapOpenedType(Inst->getType().castTo()); + remapOpenedType(Inst->getType().castTo()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); recordClonedInstruction(Inst, getBuilder().createOpenExistentialBoxValue( diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0d67c2c3864..cbd956c92af 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -370,7 +370,7 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL) llvm::FoldingSet BuiltinVectorTypes; llvm::FoldingSet GenericSignatures; llvm::FoldingSet CompoundNames; - llvm::DenseMap OpenedExistentialArchetypes; + llvm::DenseMap OpenedExistentialArchetypes; /// List of Objective-C member conflicts we have found during type checking. std::vector ObjCMethodConflicts; @@ -4270,8 +4270,8 @@ DependentMemberType *DependentMemberType::get(Type base, return known; } -CanArchetypeType ArchetypeType::getOpened(Type existential, - Optional knownID) { +CanOpenedArchetypeType OpenedArchetypeType::get(Type existential, + Optional knownID) { auto &ctx = existential->getASTContext(); auto &openedExistentialArchetypes = ctx.getImpl().OpenedExistentialArchetypes; // If we know the ID already... @@ -4283,7 +4283,7 @@ CanArchetypeType ArchetypeType::getOpened(Type existential, auto result = found->second; assert(result->getOpenedExistentialType()->isEqual(existential) && "Retrieved the wrong opened existential type?"); - return CanArchetypeType(result); + return CanOpenedArchetypeType(result); } } else { // Create a new ID. @@ -4313,16 +4313,16 @@ CanArchetypeType ArchetypeType::getOpened(Type existential, layoutConstraint, *knownID); openedExistentialArchetypes[*knownID] = result; - return CanArchetypeType(result); + return CanOpenedArchetypeType(result); } -CanType ArchetypeType::getAnyOpened(Type existential) { +CanType OpenedArchetypeType::getAny(Type existential) { if (auto metatypeTy = existential->getAs()) { auto instanceTy = metatypeTy->getInstanceType(); - return CanMetatypeType::get(ArchetypeType::getAnyOpened(instanceTy)); + return CanMetatypeType::get(OpenedArchetypeType::getAny(instanceTy)); } assert(existential->isExistentialType()); - return ArchetypeType::getOpened(existential); + return OpenedArchetypeType::get(existential); } void TypeLoc::setInvalidType(ASTContext &C) { diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 56b6f24f414..e4a14032fe5 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3330,37 +3330,24 @@ namespace { printRec(T->getSelfType()); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } - - void visitArchetypeType(ArchetypeType *T, StringRef label) { - printCommon(label, "archetype_type"); - auto openedExistential = T->getOpenedExistentialType(); - if (openedExistential) - printField("opened_existential_id", T->getOpenedExistentialID()); - else - printField("name", T->getFullName()); + + void printArchetypeCommon(ArchetypeType *T, + StringRef className, + StringRef label) { + printCommon(label, className); printField("address", static_cast(T)); printFlag(T->requiresClass(), "class"); + if (auto layout = T->getLayoutConstraint()) { + OS << " layout="; + layout->print(OS); + } for (auto proto : T->getConformsTo()) printField("conforms_to", proto->printRef()); - if (auto parent = T->getParent()) - printField("parent", static_cast(parent)); - if (!openedExistential) { - if (auto assocType = T->getAssocType()) - printField("assoc_type", assocType->printRef()); - } - // FIXME: This is ugly. - OS << "\n"; - if (auto genericEnv = T->getGenericEnvironment()) { - if (auto owningDC = genericEnv->getOwningDeclContext()) { - owningDC->printContext(OS, Indent + 2); - } - } - if (auto superclass = T->getSuperclass()) printRec("superclass", superclass); - if (openedExistential) - printRec("opened_existential", openedExistential); - + } + + void printArchetypeNestedTypes(ArchetypeType *T) { Indent += 2; for (auto nestedType : T->getKnownNestedTypes()) { OS << "\n"; @@ -3377,7 +3364,32 @@ namespace { OS << ")"; } Indent -= 2; + } + void visitPrimaryArchetypeType(PrimaryArchetypeType *T, StringRef label) { + printArchetypeCommon(T, "primary_archetype_type", label); + printField("name", T->getFullName()); + OS << "\n"; + auto genericEnv = T->getGenericEnvironment(); + if (auto owningDC = genericEnv->getOwningDeclContext()) { + owningDC->printContext(OS, Indent + 2); + } + printArchetypeNestedTypes(T); + PrintWithColorRAII(OS, ParenthesisColor) << ')'; + } + void visitNestedArchetypeType(NestedArchetypeType *T, StringRef label) { + printArchetypeCommon(T, "nested_archetype_type", label); + printField("name", T->getFullName()); + printField("parent", T->getParent()); + printField("assoc_type", T->getAssocType()->printRef()); + printArchetypeNestedTypes(T); + PrintWithColorRAII(OS, ParenthesisColor) << ')'; + } + void visitOpenedArchetypeType(OpenedArchetypeType *T, StringRef label) { + printArchetypeCommon(T, "opened_archetype_type", label); + printRec("opened_existential", T->getOpenedExistentialType()); + printField("opened_existential_id", T->getOpenedExistentialID()); + printArchetypeNestedTypes(T); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 50bc61f3558..717cf476afc 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4005,35 +4005,40 @@ public: visit(T->getObjectType()); } - void visitArchetypeType(ArchetypeType *T) { - if (auto existentialTy = T->getOpenedExistentialType()) { - if (Options.PrintForSIL) - Printer << "@opened(\"" << T->getOpenedExistentialID() << "\") "; - visit(existentialTy); - } else { - if (auto parent = T->getParent()) { - visit(parent); - Printer << "."; - } - - if (Options.AlternativeTypeNames) { - auto found = Options.AlternativeTypeNames->find(T->getCanonicalType()); - if (found != Options.AlternativeTypeNames->end()) { - Printer << found->second.str(); - return; - } - } - - auto Name = T->getName(); - if (Name.empty()) - Printer << ""; - else { - PrintNameContext context = PrintNameContext::Normal; - if (Name == T->getASTContext().Id_Self) - context = PrintNameContext::GenericParameter; - Printer.printName(Name, context); + void visitOpenedArchetypeType(OpenedArchetypeType *T) { + if (Options.PrintForSIL) + Printer << "@opened(\"" << T->getOpenedExistentialID() << "\") "; + visit(T->getOpenedExistentialType()); + } + + void printArchetypeCommon(ArchetypeType *T) { + if (Options.AlternativeTypeNames) { + auto found = Options.AlternativeTypeNames->find(T->getCanonicalType()); + if (found != Options.AlternativeTypeNames->end()) { + Printer << found->second.str(); + return; } } + + auto Name = T->getName(); + if (Name.empty()) + Printer << ""; + else { + PrintNameContext context = PrintNameContext::Normal; + if (Name == T->getASTContext().Id_Self) + context = PrintNameContext::GenericParameter; + Printer.printName(Name, context); + } + } + + void visitNestedArchetypeType(NestedArchetypeType *T) { + visit(T->getParent()); + Printer << "."; + printArchetypeCommon(T); + } + + void visitPrimaryArchetypeType(PrimaryArchetypeType *T) { + printArchetypeCommon(T); } void visitGenericTypeParamType(GenericTypeParamType *T) { diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index 97798073941..568607bc1cc 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -189,7 +189,7 @@ struct LazyGenericEnvironment { return false; } - bool containsPrimaryArchetype(ArchetypeType *archetype) const { + bool containsPrimaryArchetype(PrimaryArchetypeType *archetype) const { // Assume true so we don't deserialize. if (isLazy()) return true; @@ -240,7 +240,7 @@ class Verifier : public ASTWalker { /// The set of opened existential archetypes that are currently /// active. - llvm::DenseSet OpenedExistentialArchetypes; + llvm::DenseSet OpenedExistentialArchetypes; /// The set of inout to pointer expr that match the following pattern: /// @@ -627,8 +627,8 @@ public: // We should know about archetypes corresponding to opened // existential archetypes. - if (archetype->getOpenedExistentialType()) { - if (OpenedExistentialArchetypes.count(archetype) == 0) { + if (auto opened = dyn_cast(archetype)) { + if (OpenedExistentialArchetypes.count(opened) == 0) { Out << "Found opened existential archetype " << archetype->getString() << " outside enclosing OpenExistentialExpr\n"; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 35ed06e0865..ed88fe55b32 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -2098,11 +2098,11 @@ bool Expr::isSelfExprOf(const AbstractFunctionDecl *AFD, bool sameBase) const { return false; } -ArchetypeType *OpenExistentialExpr::getOpenedArchetype() const { +OpenedArchetypeType *OpenExistentialExpr::getOpenedArchetype() const { auto type = getOpaqueValue()->getType()->getRValueType(); while (auto metaTy = type->getAs()) type = metaTy->getInstanceType(); - return type->castTo(); + return type->castTo(); } KeyPathExpr::KeyPathExpr(ASTContext &C, SourceLoc keywordLoc, diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp index 550a4baf75c..12b0155e7f6 100644 --- a/lib/AST/GenericSignatureBuilder.cpp +++ b/lib/AST/GenericSignatureBuilder.cpp @@ -2405,16 +2405,16 @@ Type EquivalenceClass::getTypeInContext(GenericSignatureBuilder &builder, if (parentArchetype) { // Create a nested archetype. auto *depMemTy = anchor->castTo(); - archetype = ArchetypeType::getNew(ctx, parentArchetype, depMemTy, protos, - superclass, layout); + archetype = NestedArchetypeType::getNew(ctx, parentArchetype, depMemTy, + protos, superclass, layout); // Register this archetype with its parent. parentArchetype->registerNestedType(assocType->getName(), archetype); } else { // Create a top-level archetype. auto genericParam = anchor->castTo(); - archetype = ArchetypeType::getNew(ctx, genericEnv, genericParam, protos, - superclass, layout); + archetype = PrimaryArchetypeType::getNew(ctx, genericEnv, genericParam, + protos, superclass, layout); // Register the archetype with the generic environment. genericEnv->addMapping(genericParam, archetype); @@ -2989,7 +2989,7 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance( void ArchetypeType::resolveNestedType( std::pair &nested) const { - auto genericEnv = getGenericEnvironment(); + auto genericEnv = getPrimary()->getGenericEnvironment(); auto &builder = *genericEnv->getGenericSignatureBuilder(); Type interfaceType = getInterfaceType(); diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp index a814feb1db8..23361765e12 100644 --- a/lib/AST/SubstitutionMap.cpp +++ b/lib/AST/SubstitutionMap.cpp @@ -239,8 +239,7 @@ Type SubstitutionMap::lookupSubstitution(CanSubstitutableType type) const { // If we have an archetype, map out of the context so we can compute a // conformance access path. if (auto archetype = dyn_cast(type)) { - if (archetype->isOpenedExistential() || - archetype->getParent() != nullptr) + if (!isa(archetype)) return Type(); type = cast( diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 53186291c25..8b4fdee4419 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -353,32 +353,26 @@ bool TypeBase::isSpecialized() { return false; } -bool TypeBase::hasOpenedExistential(ArchetypeType *opened) { - assert(opened->getOpenedExistentialType() && - "not an opened existential type"); - +bool TypeBase::hasOpenedExistential(OpenedArchetypeType *opened) { if (!hasOpenedExistential()) return false; return getCanonicalType().findIf([&](Type type) -> bool { - return opened == dyn_cast(type.getPointer()); + return opened == dyn_cast(type.getPointer()); }); } void TypeBase::getOpenedExistentials( - SmallVectorImpl &opened) { + SmallVectorImpl &opened) { if (!hasOpenedExistential()) return; SmallPtrSet known; getCanonicalType().findIf([&](Type type) -> bool { - auto archetype = dyn_cast(type.getPointer()); + auto archetype = dyn_cast(type.getPointer()); if (!archetype) return false; - if (!archetype->getOpenedExistentialType()) - return false; - if (known.insert(archetype).second) opened.push_back(archetype); @@ -386,10 +380,7 @@ void TypeBase::getOpenedExistentials( }); } -Type TypeBase::eraseOpenedExistential(ArchetypeType *opened) { - assert(opened->getOpenedExistentialType() && - "Not an opened existential type?"); - +Type TypeBase::eraseOpenedExistential(OpenedArchetypeType *opened) { if (!hasOpenedExistential()) return Type(this); @@ -2378,7 +2369,7 @@ ArchetypeType::ArchetypeType(TypeKind Kind, getSubclassTrailingObjects()); } -ArchetypeType *ArchetypeType::getPrimary() const { +PrimaryArchetypeType *ArchetypeType::getPrimary() const { ArchetypeType *archetype = const_cast(this); while (auto child = dyn_cast(archetype)) { archetype = child->getParent(); @@ -2425,7 +2416,7 @@ NestedArchetypeType::NestedArchetypeType(const ASTContext &Ctx, { } -CanArchetypeType ArchetypeType::getNew( +CanNestedArchetypeType NestedArchetypeType::getNew( const ASTContext &Ctx, ArchetypeType *Parent, DependentMemberType *InterfaceType, @@ -2443,12 +2434,12 @@ CanArchetypeType ArchetypeType::getNew( ConformsTo.size(), Superclass ? 1 : 0, Layout ? 1 : 0), alignof(NestedArchetypeType), arena); - return CanArchetypeType(new (mem) NestedArchetypeType( + return CanNestedArchetypeType(new (mem) NestedArchetypeType( Ctx, Parent, InterfaceType, ConformsTo, Superclass, Layout)); } -CanArchetypeType -ArchetypeType::getNew(const ASTContext &Ctx, +CanPrimaryArchetypeType +PrimaryArchetypeType::getNew(const ASTContext &Ctx, GenericEnvironment *GenericEnv, GenericTypeParamType *InterfaceType, SmallVectorImpl &ConformsTo, @@ -2466,7 +2457,7 @@ ArchetypeType::getNew(const ASTContext &Ctx, ConformsTo.size(), Superclass ? 1 : 0, Layout ? 1 : 0), alignof(PrimaryArchetypeType), arena); - return CanArchetypeType(new (mem) PrimaryArchetypeType( + return CanPrimaryArchetypeType(new (mem) PrimaryArchetypeType( Ctx, GenericEnv, InterfaceType, ConformsTo, Superclass, Layout)); } @@ -2603,26 +2594,22 @@ void ArchetypeType::registerNestedType(Identifier name, Type nested) { static void collectFullName(const ArchetypeType *Archetype, SmallVectorImpl &Result) { - if (auto Parent = Archetype->getParent()) { - collectFullName(Parent, Result); + if (auto nested = dyn_cast(Archetype)) { + collectFullName(nested->getParent(), Result); Result.push_back('.'); } Result.append(Archetype->getName().str().begin(), Archetype->getName().str().end()); } -AssociatedTypeDecl *ArchetypeType::getAssocType() const { - assert(!getOpenedExistentialType()); - if (auto *depMemTy = InterfaceType->getAs()) - return depMemTy->getAssocType(); - return nullptr; +AssociatedTypeDecl *NestedArchetypeType::getAssocType() const { + return InterfaceType->castTo()->getAssocType(); } Identifier ArchetypeType::getName() const { - assert(!getOpenedExistentialType()); - if (auto assocType = getAssocType()) - return assocType->getName(); - + if (auto nested = dyn_cast(this)) + return nested->getAssocType()->getName(); + assert(InterfaceType); return InterfaceType->castTo()->getName(); } @@ -2632,16 +2619,6 @@ std::string ArchetypeType::getFullName() const { return Result.str().str(); } -GenericEnvironment *ArchetypeType::getGenericEnvironment() const { - if (auto child = dyn_cast(this)) { - return child->getParent()->getGenericEnvironment(); - } - if (auto context = dyn_cast(this)) { - return context->getGenericEnvironment(); - } - return nullptr; -} - void ProtocolCompositionType::Profile(llvm::FoldingSetNodeID &ID, ArrayRef Members, bool HasExplicitAnyObject) { @@ -3014,22 +2991,22 @@ static Type substType(Type derivedType, return Type(); } - auto archetype = cast(substOrig); - - // Opened existentials cannot be substituted in this manner, - // but if they appear in the original type this is not an - // error. - if (archetype->isOpenedExistential()) - return Type(type); - - // For archetypes, we can substitute the parent (if present). - auto parent = archetype->getParent(); - if (!parent) { + if (auto primaryArchetype = dyn_cast(substOrig)) { if (options.contains(SubstFlags::UseErrorType)) return ErrorType::get(type); return Type(); } + // Opened existentials cannot be substituted in this manner, + // but if they appear in the original type this is not an + // error. + if (isa(substOrig)) + return Type(type); + + // For nested archetypes, we can substitute the parent. + auto nestedArchetype = cast(substOrig); + auto parent = nestedArchetype->getParent(); + // Substitute into the parent type. Type substParent = substType(parent, substitutions, lookupConformances, options); @@ -3039,10 +3016,10 @@ static Type substType(Type derivedType, return Type(type); // Get the associated type reference from a child archetype. - AssociatedTypeDecl *assocType = archetype->getAssocType(); + AssociatedTypeDecl *assocType = nestedArchetype->getAssocType(); return getMemberForBaseType(lookupConformances, parent, substParent, - assocType, archetype->getName(), + assocType, nestedArchetype->getName(), options); }); } @@ -4087,15 +4064,15 @@ SILBoxType::SILBoxType(ASTContext &C, assert(Substitutions.isCanonical()); } -Type TypeBase::openAnyExistentialType(ArchetypeType *&opened) { +Type TypeBase::openAnyExistentialType(OpenedArchetypeType *&opened) { assert(isAnyExistentialType()); if (auto metaty = getAs()) { - opened = ArchetypeType::getOpened(metaty->getInstanceType()); + opened = OpenedArchetypeType::get(metaty->getInstanceType()); if (metaty->hasRepresentation()) return MetatypeType::get(opened, metaty->getRepresentation()); else return MetatypeType::get(opened); } - opened = ArchetypeType::getOpened(this); + opened = OpenedArchetypeType::get(this); return opened; } diff --git a/lib/IRGen/GenArchetype.cpp b/lib/IRGen/GenArchetype.cpp index 94ddd423a05..528e3393e56 100644 --- a/lib/IRGen/GenArchetype.cpp +++ b/lib/IRGen/GenArchetype.cpp @@ -62,11 +62,10 @@ irgen::emitArchetypeTypeMetadataRef(IRGenFunction &IGF, return response; // If that's not present, this must be an associated type. - assert(!archetype->isPrimary() && - "type metadata for primary archetype was not bound in context"); + auto nested = cast(archetype); - CanArchetypeType parent(archetype->getParent()); - AssociatedType association(archetype->getAssocType()); + CanArchetypeType parent(nested->getParent()); + AssociatedType association(nested->getAssocType()); MetadataResponse response = emitAssociatedTypeMetadataRef(IGF, parent, association, request); @@ -176,10 +175,7 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF, // If we don't have an environment, this must be an implied witness table // reference. // FIXME: eliminate this path when opened types have generic environments. - auto environment = archetype->getGenericEnvironment(); - if (!environment) { - assert(archetype->isOpenedExistential() && - "non-opened archetype lacking generic environment?"); + if (auto opened = dyn_cast(archetype)) { SmallVector entries; for (auto p : archetype->getConformsTo()) { const ProtocolInfo &impl = @@ -198,6 +194,8 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF, return wtable; }); } + + auto environment = archetype->getPrimary()->getGenericEnvironment(); // Otherwise, ask the generic signature for the environment for the best // path to the conformance. diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp index f20c725e66b..9dc66dc0a04 100644 --- a/lib/IRGen/GenExistential.cpp +++ b/lib/IRGen/GenExistential.cpp @@ -1637,7 +1637,7 @@ OwnedAddress irgen::emitBoxedExistentialContainerAllocation(IRGenFunction &IGF, auto box = IGF.Builder.CreateExtractValue(result, 0); auto addr = IGF.Builder.CreateExtractValue(result, 1); - auto archetype = ArchetypeType::getOpened(destType.getASTType()); + auto archetype = OpenedArchetypeType::get(destType.getASTType()); auto &srcTI = IGF.getTypeInfoForUnlowered(AbstractionPattern(archetype), formalSrcType); addr = IGF.Builder.CreateBitCast(addr, diff --git a/lib/IRGen/GenHeap.cpp b/lib/IRGen/GenHeap.cpp index d5294da14d7..91e450d1c6e 100644 --- a/lib/IRGen/GenHeap.cpp +++ b/lib/IRGen/GenHeap.cpp @@ -1904,7 +1904,7 @@ IsaEncoding irgen::getIsaEncodingForType(IRGenModule &IGM, // Existentials use the encoding of the enclosed dynamic type. if (type->isAnyExistentialType()) { - return getIsaEncodingForType(IGM, ArchetypeType::getOpened(type)); + return getIsaEncodingForType(IGM, OpenedArchetypeType::getAny(type)); } if (auto archetype = dyn_cast(type)) { diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 61e38785437..9c8b4592439 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -1420,11 +1420,15 @@ const TypeInfo &TypeConverter::getCompleteTypeInfo(CanType T) { } ArchetypeType *TypeConverter::getExemplarArchetype(ArchetypeType *t) { + // Get the primary archetype. + auto primary = t->getPrimary(); + + // If there is no primary (IOW, it's an opened archetype), the archetype is + // an exemplar. + if (!primary) return t; + // Retrieve the generic environment of the archetype. - auto genericEnv = t->getGenericEnvironment(); - - // If there is no generic environment, the archetype is an exemplar. - if (!genericEnv) return t; + auto genericEnv = primary->getGenericEnvironment(); // Dig out the canonical generic environment. auto genericSig = genericEnv->getGenericSignature(); @@ -2128,8 +2132,9 @@ void IRGenFunction::setLocalSelfMetadata(llvm::Value *value, #ifndef NDEBUG bool TypeConverter::isExemplarArchetype(ArchetypeType *arch) const { - auto genericEnv = arch->getGenericEnvironment(); - if (!genericEnv) return true; + auto primary = arch->getPrimary(); + if (!primary) return true; + auto genericEnv = primary->getGenericEnvironment(); // Dig out the canonical generic environment. auto genericSig = genericEnv->getGenericSignature(); diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 5f827f08757..a008c9b16dd 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1197,7 +1197,10 @@ private: case TypeKind::OpenedArchetype: case TypeKind::NestedArchetype: { auto *Archetype = BaseTy->castTo(); - auto L = getDebugLoc(*this, Archetype->getAssocType()); + AssociatedTypeDecl *assocType = nullptr; + if (auto nested = dyn_cast(Archetype)) + assocType = nested->getAssocType(); + auto L = getDebugLoc(*this, assocType); auto Superclass = Archetype->getSuperclass(); auto DerivedFrom = Superclass.isNull() ? nullptr diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp index 11b1c06562e..d26170cf915 100644 --- a/lib/IRGen/LocalTypeData.cpp +++ b/lib/IRGen/LocalTypeData.cpp @@ -336,7 +336,7 @@ static void maybeEmitDebugInfoForLocalTypeData(IRGenFunction &IGF, auto type = dyn_cast(key.Type); if (!type) return; - if (type->getOpenedExistentialType()) + if (isa(type)) return; llvm::Value *data = value.getMetadata(); diff --git a/lib/IRGen/Outlining.cpp b/lib/IRGen/Outlining.cpp index 9c0e046fdce..34455d20ba4 100644 --- a/lib/IRGen/Outlining.cpp +++ b/lib/IRGen/Outlining.cpp @@ -110,7 +110,7 @@ irgen::getTypeAndGenericSignatureForManglingOutlineFunction(SILType type) { GenericEnvironment *env = nullptr; loweredType.findIf([&env](Type t) -> bool { if (auto arch = t->getAs()) { - env = arch->getGenericEnvironment(); + env = arch->getPrimary()->getGenericEnvironment(); return true; } return false; diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp index 5ef3c56024b..3090892612d 100644 --- a/lib/ParseSIL/ParseSIL.cpp +++ b/lib/ParseSIL/ParseSIL.cpp @@ -4676,7 +4676,7 @@ bool SILParser::parseSILInstruction(SILBuilder &B) { // Lower the type at the abstraction level of the existential. auto archetype - = ArchetypeType::getOpened(Val->getType().getASTType()) + = OpenedArchetypeType::get(Val->getType().getASTType()) ->getCanonicalType(); SILType LoweredTy = SILMod.Types.getLoweredType( diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp index 547efab5ad7..391e46a9999 100644 --- a/lib/SIL/SILVerifier.cpp +++ b/lib/SIL/SILVerifier.cpp @@ -77,16 +77,16 @@ static llvm::cl::opt SkipConvertEscapeToNoescapeAttributes( /// Returns true if A is an opened existential type or is equal to an /// archetype from F's generic context. static bool isArchetypeValidInFunction(ArchetypeType *A, const SILFunction *F) { - if (!A->getOpenedExistentialType().isNull()) + if (isa(A)) return true; // Find the primary archetype. - A = A->getPrimary(); + auto P = A->getPrimary(); // Ok, we have a primary archetype, make sure it is in the nested generic // environment of our caller. if (auto *genericEnv = F->getGenericEnvironment()) - if (A->getGenericEnvironment() == genericEnv) + if (P->getGenericEnvironment() == genericEnv) return true; return false; @@ -2015,7 +2015,7 @@ public: if (auto *AEBI = dyn_cast(PEBI->getOperand())) { // The lowered type must be the properly-abstracted form of the AST type. SILType exType = AEBI->getExistentialType(); - auto archetype = ArchetypeType::getOpened(exType.getASTType()); + auto archetype = OpenedArchetypeType::get(exType.getASTType()); auto loweredTy = F.getModule().Types.getLoweredType( Lowering::AbstractionPattern(archetype), @@ -3035,7 +3035,7 @@ public: "existential type"); // The lowered type must be the properly-abstracted form of the AST type. - auto archetype = ArchetypeType::getOpened(exType.getASTType()); + auto archetype = OpenedArchetypeType::get(exType.getASTType()); auto loweredTy = F.getModule().Types.getLoweredType( Lowering::AbstractionPattern(archetype), @@ -3065,7 +3065,7 @@ public: "init_existential_value result must not be an address"); // The operand must be at the right abstraction level for the existential. SILType exType = IEI->getType(); - auto archetype = ArchetypeType::getOpened(exType.getASTType()); + auto archetype = OpenedArchetypeType::get(exType.getASTType()); auto loweredTy = F.getModule().Types.getLoweredType( Lowering::AbstractionPattern(archetype), IEI->getFormalConcreteType()); requireSameType( @@ -3097,7 +3097,7 @@ public: // The operand must be at the right abstraction level for the existential. SILType exType = IEI->getType(); - auto archetype = ArchetypeType::getOpened(exType.getASTType()); + auto archetype = OpenedArchetypeType::get(exType.getASTType()); auto loweredTy = F.getModule().Types.getLoweredType( Lowering::AbstractionPattern(archetype), IEI->getFormalConcreteType()); diff --git a/lib/SILGen/ResultPlan.cpp b/lib/SILGen/ResultPlan.cpp index ab6e5be7cf1..3cc27ef9be7 100644 --- a/lib/SILGen/ResultPlan.cpp +++ b/lib/SILGen/ResultPlan.cpp @@ -80,7 +80,7 @@ public: /// corresponding to each opened type, static std::tuple mapTypeOutOfOpenedExistentialContext(CanType t) { - SmallVector openedTypes; + SmallVector openedTypes; t->getOpenedExistentials(openedTypes); ArrayRef openedTypesAsTypes( diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 5ec5437b1fe..4aa6800ad51 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -705,7 +705,7 @@ static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &SGF, // If the input argument is known to be an existential, save the runtime // some work by opening it. if (nativeType->isExistentialType()) { - auto openedType = ArchetypeType::getOpened(nativeType); + auto openedType = OpenedArchetypeType::get(nativeType); FormalEvaluationScope scope(SGF); diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index aaf54201f30..f76d96cadaf 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -308,7 +308,7 @@ static ManagedValue emitCastToReferenceType(SILGenFunction &SGF, // If the argument is existential, open it. if (argTy->isClassExistentialType()) { - auto openedTy = ArchetypeType::getOpened(argTy); + auto openedTy = OpenedArchetypeType::get(argTy); SILType loweredOpenedTy = SGF.getLoweredLoadableType(openedTy); arg = SGF.B.createOpenExistentialRef(loc, arg, loweredOpenedTy); } @@ -797,7 +797,7 @@ static ManagedValue emitBuiltinCastToBridgeObject(SILGenFunction &SGF, // If the argument is existential, open it. if (sourceType->isClassExistentialType()) { - auto openedTy = ArchetypeType::getOpened(sourceType); + auto openedTy = OpenedArchetypeType::get(sourceType); SILType loweredOpenedTy = SGF.getLoweredLoadableType(openedTy); ref = SGF.B.createOpenExistentialRef(loc, ref, loweredOpenedTy); } diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 095157980c1..1700891281a 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -1750,7 +1750,7 @@ RValue RValueEmitter::visitErasureExpr(ErasureExpr *E, SGFContext C) { auto &existentialTL = SGF.getTypeLowering(E->getType()); auto concreteFormalType = E->getSubExpr()->getType()->getCanonicalType(); - auto archetype = ArchetypeType::getAnyOpened(E->getType()); + auto archetype = OpenedArchetypeType::getAny(E->getType()); AbstractionPattern abstractionPattern(archetype); auto &concreteTL = SGF.getTypeLowering(abstractionPattern, concreteFormalType); @@ -2553,7 +2553,7 @@ emitKeyPathRValueBase(SILGenFunction &subSGF, // new one (which we'll upcast immediately below) for a class member. ArchetypeType *opened; if (storage->getDeclContext()->getSelfClassDecl()) { - opened = ArchetypeType::getOpened(baseType); + opened = OpenedArchetypeType::get(baseType); } else { opened = subs.getReplacementTypes()[0]->castTo(); } diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index 90c9e55a9bf..6cf3f420f5e 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -202,7 +202,7 @@ static ManagedValue emitTransformExistential(SILGenFunction &SGF, ArchetypeType *openedArchetype = nullptr; if (inputType->isAnyExistentialType()) { - CanType openedType = ArchetypeType::getAnyOpened(inputType); + CanType openedType = OpenedArchetypeType::getAny(inputType); SILType loweredOpenedType = SGF.getLoweredType(openedType); // Unwrap zero or more metatype levels @@ -575,7 +575,7 @@ ManagedValue Transform::transform(ManagedValue v, auto layout = instanceType.getExistentialLayout(); if (layout.explicitSuperclass) { - CanType openedType = ArchetypeType::getAnyOpened(inputSubstType); + CanType openedType = OpenedArchetypeType::getAny(inputSubstType); SILType loweredOpenedType = SGF.getLoweredType(openedType); // Unwrap zero or more metatype levels @@ -2889,7 +2889,7 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc, static CanGenericSignature buildThunkSignature(SILGenFunction &SGF, bool inheritGenericSig, - ArchetypeType *openedExistential, + OpenedArchetypeType *openedExistential, GenericEnvironment *&genericEnv, SubstitutionMap &contextSubs, SubstitutionMap &interfaceSubs, @@ -2988,16 +2988,17 @@ CanSILFunctionType SILGenFunction::buildThunkType( // Does the thunk type involve archetypes other than opened existentials? bool hasArchetypes = false; // Does the thunk type involve an open existential type? - CanArchetypeType openedExistential; + CanOpenedArchetypeType openedExistential; auto archetypeVisitor = [&](CanType t) { if (auto archetypeTy = dyn_cast(t)) { - if (archetypeTy->getOpenedExistentialType()) { + if (auto opened = dyn_cast(archetypeTy)) { assert((openedExistential == CanArchetypeType() || - openedExistential == archetypeTy) && + openedExistential == opened) && "one too many open existentials"); - openedExistential = archetypeTy; - } else + openedExistential = opened; + } else { hasArchetypes = true; + } } }; diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index ed81e28c9b2..8924ef2ea1c 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -730,7 +730,7 @@ static SILFunction *emitSelfConformanceWitness(SILGenModule &SGM, ProtocolConformanceRef(protocol)); // Open the protocol type. - auto openedType = ArchetypeType::getOpened(protocolType); + auto openedType = OpenedArchetypeType::get(protocolType); // Form the substitutions for calling the witness. auto witnessSubs = SubstitutionMap::getProtocolSubstitutions(protocol, diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp index 614e40dc403..7e23285156b 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp @@ -384,7 +384,7 @@ void ExistentialTransform::populateThunkBody() { auto it = ExistentialArgDescriptor.find(ArgDesc.Index); if (iter != ArgToGenericTypeMap.end() && it != ExistentialArgDescriptor.end()) { - ArchetypeType *Opened; + OpenedArchetypeType *Opened; auto OrigOperand = ThunkBody->getArgument(ArgDesc.Index); auto SwiftType = ArgDesc.Arg->getType().getASTType(); auto OpenedType = diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 1173647228d..b1f54ff0f5e 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -51,15 +51,11 @@ Type Solution::getFixedType(TypeVariableType *typeVar) const { /// This comes up in computeSubstitutions() when accessing /// members via dynamic lookup. static bool isOpenedAnyObject(Type type) { - auto archetype = type->getAs(); + auto archetype = type->getAs(); if (!archetype) return false; - auto existential = archetype->getOpenedExistentialType(); - if (!existential) - return false; - - return existential->isAnyObject(); + return archetype->getOpenedExistentialType()->isAnyObject(); } SubstitutionMap Solution::computeSubstitutions( @@ -644,7 +640,7 @@ namespace { /// Describes an opened existential that has not yet been closed. struct OpenedExistential { /// The archetype describing this opened existential. - ArchetypeType *Archetype; + OpenedArchetypeType *Archetype; /// The existential value being opened. Expr *ExistentialValue; @@ -757,7 +753,7 @@ namespace { /// \returns An OpaqueValueExpr that provides a reference to the value /// stored within the expression or its metatype (if the base was a /// metatype). - Expr *openExistentialReference(Expr *base, ArchetypeType *archetype, + Expr *openExistentialReference(Expr *base, OpenedArchetypeType *archetype, ValueDecl *member) { assert(archetype && "archetype not already opened?"); @@ -5228,7 +5224,7 @@ Expr *ExprRewriter::coerceSuperclass(Expr *expr, Type toType, if (fromInstanceType->isExistentialType()) { // Coercion from superclass-constrained existential to its // concrete superclass. - auto fromArchetype = ArchetypeType::getAnyOpened(fromType); + auto fromArchetype = OpenedArchetypeType::getAny(fromType); auto *archetypeVal = cs.cacheType( @@ -5296,7 +5292,7 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType, // For existential-to-existential coercions, open the source existential. if (fromType->isAnyExistentialType()) { - fromType = ArchetypeType::getAnyOpened(fromType); + fromType = OpenedArchetypeType::getAny(fromType); auto *archetypeVal = cs.cacheType( @@ -7235,7 +7231,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType, ->castTo() ->getInstanceType(); } - assert(openedInstanceTy->castTo() + assert(openedInstanceTy->castTo() ->getOpenedExistentialType() ->isEqual(existentialInstanceTy)); diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 0d9e3706f12..77f1579ad88 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -3350,10 +3350,8 @@ namespace { Type type = CS.getType(expr); if (type->hasOpenedExistential()) { type = type.transform([&](Type type) -> Type { - if (auto archetype = type->getAs()) - if (auto existentialType = archetype->getOpenedExistentialType()) - return existentialType; - + if (auto archetype = type->getAs()) + return archetype->getOpenedExistentialType(); return type; }); CS.setType(expr, type); diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index e694d51dbe9..226d5593f78 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -4162,7 +4162,7 @@ ConstraintSystem::simplifyOpenedExistentialOfConstraint( instanceTy = metaTy->getInstanceType(); } assert(instanceTy->isExistentialType()); - Type openedTy = ArchetypeType::getOpened(instanceTy); + Type openedTy = OpenedArchetypeType::get(instanceTy); if (isMetatype) openedTy = MetatypeType::get(openedTy, TC.Context); return matchTypes(type1, openedTy, ConstraintKind::Bind, subflags, locator); diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp index f7836dcaa98..cc3f9d585a8 100644 --- a/lib/Sema/CalleeCandidateInfo.cpp +++ b/lib/Sema/CalleeCandidateInfo.cpp @@ -464,7 +464,7 @@ CalleeCandidateInfo::ClosenessResultTy CalleeCandidateInfo::evaluateCloseness( allGenericSubstitutions[archetype] = substitution; // Not yet handling nested archetypes. - if (!archetype->isPrimary()) + if (!isa(archetype)) return { CC_ArgumentMismatch, {}}; if (!isSubstitutableFor(substitution, archetype, CS.DC)) { diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 31dbb4c2a5a..e44311c4cad 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -1322,7 +1322,7 @@ ConstraintSystem::getTypeOfMemberReference( Type baseOpenedTy = baseObjTy; if (baseObjTy->isExistentialType()) { - ArchetypeType *openedArchetype = ArchetypeType::getOpened(baseObjTy); + auto openedArchetype = OpenedArchetypeType::get(baseObjTy); OpenedExistentialTypes.push_back({ getConstraintLocator(locator), openedArchetype }); baseOpenedTy = openedArchetype; diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index f7f3a8a2093..1006880deb8 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -602,7 +602,7 @@ public: llvm::SmallDenseMap> OpenedTypes; /// The opened existential type for a given locator. - llvm::SmallDenseMap + llvm::SmallDenseMap OpenedExistentialTypes; /// The locators of \c Defaultable constraints whose defaults were used. @@ -1075,7 +1075,7 @@ private: /// A mapping from constraint locators to the opened existential archetype /// used for the 'self' of an existential type. - SmallVector, 4> + SmallVector, 4> OpenedExistentialTypes; SmallVector, 8> diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 876b75260ba..a67a5aaea19 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -2919,10 +2919,9 @@ static Type replaceArchetypesWithTypeVariables(ConstraintSystem &cs, if (found != types.end()) return found->second; - if (auto archetypeType = dyn_cast(origType)) { - if (archetypeType->getParent()) - return Type(); - + if (isa(origType)) + return Type(); + else if (auto archetypeType = dyn_cast(origType)) { auto locator = cs.getConstraintLocator(nullptr); auto replacement = cs.createTypeVariable(locator); diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 4ba3a69b589..443b2578fe6 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2174,7 +2174,7 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs, if (!ty->isExistentialType()) { diagnose(attrs.getLoc(TAK_opened), diag::opened_non_protocol, ty); } else { - ty = ArchetypeType::getOpened(ty, attrs.OpenedID); + ty = OpenedArchetypeType::get(ty, attrs.OpenedID); } attrs.clearAttribute(TAK_opened); } diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 7daea91282f..fa3165f6626 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -4668,7 +4668,7 @@ Expected ModuleFile::getTypeChecked(TypeID TID) { decls_block::OpenedExistentialTypeLayout::readRecord(scratch, existentialID); - typeOrOffset = ArchetypeType::getOpened(getType(existentialID)); + typeOrOffset = OpenedArchetypeType::get(getType(existentialID)); break; } diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index db4d1e215af..5dbc2063760 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -3792,19 +3792,10 @@ void Serializer::writeType(Type ty) { } case TypeKind::PrimaryArchetype: - case TypeKind::OpenedArchetype: case TypeKind::NestedArchetype: { auto archetypeTy = cast(ty.getPointer()); - // Opened existential types use a separate layout. - if (auto existentialTy = archetypeTy->getOpenedExistentialType()) { - unsigned abbrCode = DeclTypeAbbrCodes[OpenedExistentialTypeLayout::Code]; - OpenedExistentialTypeLayout::emitRecord(Out, ScratchRecord, abbrCode, - addTypeRef(existentialTy)); - break; - } - - auto env = archetypeTy->getGenericEnvironment(); + auto env = archetypeTy->getPrimary()->getGenericEnvironment(); assert(env && "Primary archetype without generic environment?"); GenericEnvironmentID envID = addGenericEnvironmentRef(env); @@ -3816,6 +3807,14 @@ void Serializer::writeType(Type ty) { break; } + case TypeKind::OpenedArchetype: { + auto archetypeTy = cast(ty.getPointer()); + unsigned abbrCode = DeclTypeAbbrCodes[OpenedExistentialTypeLayout::Code]; + OpenedExistentialTypeLayout::emitRecord(Out, ScratchRecord, abbrCode, + addTypeRef(archetypeTy->getOpenedExistentialType())); + break; + } + case TypeKind::GenericTypeParam: { auto genericParam = cast(ty.getPointer()); unsigned abbrCode = DeclTypeAbbrCodes[GenericTypeParamTypeLayout::Code];