From 5ab94a6ef055dd4576a4d8ed4690a361b1cf8006 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 7 Oct 2016 01:38:45 -0400 Subject: [PATCH 1/3] AST: Add "re-sugaring" to GenericEnvironment Sugared GenericTypeParamTypes point to GenericTypeParamDecls, allowing the name of the parameter as written by the user to be recovered. Canonical GenericTypeParamTypes on the other hand only store a depth and index, without referencing the original declaration. When printing SIL, we wish to output the original generic parameter names, even though SIL only uses canonical types. Previously, we used to accomplish this by mapping the generic parameter to an archetype and printing the name of the archetype. This was not adequate if multiple generic parameters mapped to the same archetype, or if a generic parameter was mapped to a concrete type. The new approach preserves the original sugared types in the GenericEnvironment, adding a new GenericEnvironment::getSugaredType() method. There are also some other assorted simplifications made possible by this. Unfortunately this makes GenericEnvironments use a bit more memory, however I have more improvements coming that will offset the gains, in addition to making substitution lists smaller also. --- include/swift/AST/ArchetypeBuilder.h | 18 ++---- include/swift/AST/GenericEnvironment.h | 17 +++++- .../Serialization/DeclTypeRecordNodes.def | 1 + include/swift/Serialization/ModuleFormat.h | 23 +++----- lib/AST/ASTContext.cpp | 4 +- lib/AST/ASTDumper.cpp | 3 + lib/AST/ASTPrinter.cpp | 34 +++++++---- lib/AST/ArchetypeBuilder.cpp | 27 +++++---- lib/AST/Builtins.cpp | 3 +- lib/AST/GenericEnvironment.cpp | 13 +++++ lib/ClangImporter/ImportDecl.cpp | 4 +- lib/SIL/SILPrinter.cpp | 21 ++++--- lib/SILGen/SILGenDecl.cpp | 14 ++++- lib/Sema/TypeCheckDecl.cpp | 8 +-- lib/Sema/TypeCheckGeneric.cpp | 39 +------------ lib/Serialization/Deserialization.cpp | 29 +++++++++- lib/Serialization/Serialization.cpp | 56 ++++++++++--------- lib/Serialization/Serialization.h | 3 +- lib/Serialization/SerializeSIL.cpp | 7 +-- test/SILGen/constrained_extensions.swift | 32 +++++------ 20 files changed, 198 insertions(+), 158 deletions(-) diff --git a/include/swift/AST/ArchetypeBuilder.h b/include/swift/AST/ArchetypeBuilder.h index e87993f23572a..819e61696b479 100644 --- a/include/swift/AST/ArchetypeBuilder.h +++ b/include/swift/AST/ArchetypeBuilder.h @@ -254,21 +254,11 @@ class ArchetypeBuilder { GenericEnvironment *genericEnv, bool treatRequirementsAsExplicit = false); - /// \brief Get a generic signature based on the provided complete list - /// of generic parameter types. - /// - /// \returns a generic signature built from the provided list of - /// generic parameter types. - GenericSignature * - getGenericSignature(ArrayRef genericParamsTypes); + /// \brief Build the generic signature. + GenericSignature *getGenericSignature(); - /// \brief Get a generic context based on the complete list of generic - /// parameter types. - /// - /// \returns a generic context built from the provided list of - /// generic parameter types. - GenericEnvironment *getGenericEnvironment( - ArrayRef genericParamsTypes); + /// \brief Build the generic environment. + GenericEnvironment *getGenericEnvironment(); /// Infer requirements from the given type, recursively. /// diff --git a/include/swift/AST/GenericEnvironment.h b/include/swift/AST/GenericEnvironment.h index f98319191242e..9c5ec2c868243 100644 --- a/include/swift/AST/GenericEnvironment.h +++ b/include/swift/AST/GenericEnvironment.h @@ -28,10 +28,15 @@ class GenericTypeParamType; /// Describes the mapping between archetypes and interface types for the /// generic parameters of a DeclContext. class GenericEnvironment final { + SmallVector GenericParams; TypeSubstitutionMap ArchetypeToInterfaceMap; TypeSubstitutionMap InterfaceToArchetypeMap; public: + ArrayRef getGenericParams() const { + return GenericParams; + } + const TypeSubstitutionMap &getArchetypeToInterfaceMap() const { return ArchetypeToInterfaceMap; } @@ -40,10 +45,13 @@ class GenericEnvironment final { return InterfaceToArchetypeMap; } - explicit GenericEnvironment(TypeSubstitutionMap interfaceToArchetypeMap); + GenericEnvironment(ArrayRef genericParamTypes, + TypeSubstitutionMap interfaceToArchetypeMap); - static GenericEnvironment *get(ASTContext &ctx, - TypeSubstitutionMap interfaceToArchetypeMap); + static + GenericEnvironment * get(ASTContext &ctx, + ArrayRef genericParamTypes, + TypeSubstitutionMap interfaceToArchetypeMap); /// Make vanilla new/delete illegal. void *operator new(size_t Bytes) = delete; @@ -62,6 +70,9 @@ class GenericEnvironment final { /// Map a generic parameter type to a contextual type. Type mapTypeIntoContext(GenericTypeParamType *type) const; + /// Get the sugared form of a generic parameter type. + GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const; + /// Derive a contextual type substitution map from a substitution array. /// This is just like GenericSignature::getSubstitutionMap(), except /// with contextual types instead of interface types. diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def index d5c1a0398b57b..f930c6f1e941f 100644 --- a/include/swift/Serialization/DeclTypeRecordNodes.def +++ b/include/swift/Serialization/DeclTypeRecordNodes.def @@ -169,6 +169,7 @@ OTHER(GENERIC_PARAM_LIST, 240) TRAILING_INFO(GENERIC_PARAM) TRAILING_INFO(GENERIC_REQUIREMENT) TRAILING_INFO(GENERIC_ENVIRONMENT) +TRAILING_INFO(SIL_GENERIC_ENVIRONMENT) OTHER(LOCAL_DISCRIMINATOR, 248) OTHER(PRIVATE_DISCRIMINATOR, 249) diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h index 3fa3816c46142..e0412f95bcde3 100644 --- a/include/swift/Serialization/ModuleFormat.h +++ b/include/swift/Serialization/ModuleFormat.h @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0; /// in source control, you should also update the comment to briefly /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. -const uint16_t VERSION_MINOR = 273; // Last change: partial_apply ownership control +const uint16_t VERSION_MINOR = 274; // Last change: SIL generic environment sugar using DeclID = PointerEmbeddedInt; using DeclIDField = BCFixed<31>; @@ -1095,21 +1095,16 @@ namespace decls_block { DeclIDField // Typealias >; - // Subtlety here: GENERIC_ENVIRONMENT is serialized for both Decls and - // SILFunctions. - // - // For Decls, the interface type is non-canonical, so it points back - // to the GenericParamListDecl. This allows us to use the serialized - // GENERIC_ENVIRONMENT records to form the GenericSignature, as well. - // The type is canonicalized when forming the actual GenericEnvironment - // instance. - // - // For SILFunctions, the interface type below is always canonical, - // since SILFunctions never point back to any original - // GenericTypeParamDecls. using GenericEnvironmentLayout = BCRecordLayout< GENERIC_ENVIRONMENT, - TypeIDField, // interface type + TypeIDField, // sugared interface type + TypeIDField // contextual type + >; + + using SILGenericEnvironmentLayout = BCRecordLayout< + SIL_GENERIC_ENVIRONMENT, + IdentifierIDField, // generic parameter name + TypeIDField, // canonical interface type TypeIDField // contextual type >; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index ea54a40b0658c..1264c832b84f6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3567,8 +3567,10 @@ GenericSignature *GenericSignature::get(ArrayRef params, GenericEnvironment * GenericEnvironment::get(ASTContext &ctx, + ArrayRef genericParamTypes, TypeSubstitutionMap interfaceToArchetypeMap) { - return new (ctx) GenericEnvironment(interfaceToArchetypeMap); + return new (ctx) GenericEnvironment(genericParamTypes, + interfaceToArchetypeMap); } void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id, diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 6ba4202e178b8..19754f268018f 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3090,4 +3090,7 @@ void GenericEnvironment::dump() const { pair.first->dump(); pair.second->dump(); } + llvm::errs() << "Generic parameters:\n"; + for (auto paramTy : getGenericParams()) + paramTy->dump(); } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index d94263bc4832a..2d1382061dab8 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -3418,14 +3418,6 @@ class TypePrinter : public TypeVisitor { Printer.printTypePre(TypeLoc::withoutLoc(T)); SWIFT_DEFER { Printer.printTypePost(TypeLoc::withoutLoc(T)); }; - // If we have an alternate name for this type, use it. - if (Options.AlternativeTypeNames) { - auto found = Options.AlternativeTypeNames->find(T.getCanonicalTypeOrNull()); - if (found != Options.AlternativeTypeNames->end()) { - Printer << found->second.str(); - return; - } - } super::visit(T); } @@ -3992,6 +3984,14 @@ class TypePrinter : public TypeVisitor { Printer << "."; } + if (Options.AlternativeTypeNames) { + auto found = Options.AlternativeTypeNames->find(T->getCanonicalType()); + if (found != Options.AlternativeTypeNames->end()) { + Printer << found->second.str(); + return; + } + } + if (T->getName().empty()) Printer << ""; else { @@ -4012,9 +4012,21 @@ class TypePrinter : public TypeVisitor { } void visitGenericTypeParamType(GenericTypeParamType *T) { - // Substitute a context archetype if we have context generic params. - if (Options.GenericEnv) - return visit(Options.GenericEnv->mapTypeIntoContext(T)); + if (T->getDecl() == nullptr) { + // If we have an alternate name for this type, use it. + if (Options.AlternativeTypeNames) { + auto found = Options.AlternativeTypeNames->find(T->getCanonicalType()); + if (found != Options.AlternativeTypeNames->end()) { + Printer << found->second.str(); + return; + } + } + + // When printing SIL types, use a generic environment to map them from + // canonical types to sugared types. + if (Options.GenericEnv) + T = Options.GenericEnv->getSugaredType(T); + } auto Name = T->getName(); if (Name.empty()) diff --git a/lib/AST/ArchetypeBuilder.cpp b/lib/AST/ArchetypeBuilder.cpp index d7169fac87d79..a301d62f81545 100644 --- a/lib/AST/ArchetypeBuilder.cpp +++ b/lib/AST/ArchetypeBuilder.cpp @@ -2096,9 +2096,14 @@ static void collectRequirements(ArchetypeBuilder &builder, }); } -GenericSignature *ArchetypeBuilder::getGenericSignature( - ArrayRef genericParamTypes) { +GenericSignature *ArchetypeBuilder::getGenericSignature() { // Collect the requirements placed on the generic parameter types. + SmallVector genericParamTypes; + for (auto pair : Impl->PotentialArchetypes) { + auto paramTy = pair.second->getGenericParam(); + genericParamTypes.push_back(paramTy); + } + SmallVector requirements; collectRequirements(*this, genericParamTypes, requirements); @@ -2106,17 +2111,16 @@ GenericSignature *ArchetypeBuilder::getGenericSignature( return sig; } -GenericEnvironment *ArchetypeBuilder::getGenericEnvironment( - ArrayRef genericParamTypes) { +GenericEnvironment *ArchetypeBuilder::getGenericEnvironment() { + SmallVector genericParamTypes; TypeSubstitutionMap interfaceToArchetypeMap; - for (auto paramTy : genericParamTypes) { - auto known = Impl->PotentialArchetypes.find( - GenericTypeParamKey::forType(paramTy)); - assert(known != Impl->PotentialArchetypes.end()); + for (auto pair : Impl->PotentialArchetypes) { + auto paramTy = pair.second->getGenericParam(); + genericParamTypes.push_back(paramTy); - auto archetypeTy = known->second->getType(*this).getAsArchetype(); - auto concreteTy = known->second->getType(*this).getAsConcreteType(); + auto archetypeTy = pair.second->getType(*this).getAsArchetype(); + auto concreteTy = pair.second->getType(*this).getAsConcreteType(); if (archetypeTy) interfaceToArchetypeMap[paramTy] = archetypeTy; else if (concreteTy) @@ -2125,6 +2129,7 @@ GenericEnvironment *ArchetypeBuilder::getGenericEnvironment( llvm_unreachable("broken generic parameter"); } - return GenericEnvironment::get(Context, interfaceToArchetypeMap); + return GenericEnvironment::get(Context, genericParamTypes, + interfaceToArchetypeMap); } diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index bd96055f90ce4..f3ff97303f39c 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -205,7 +205,8 @@ getBuiltinGenericFunction(Identifier Id, GenericSignature *Sig = GenericSignature::get(GenericParamTypes, requirements); GenericEnvironment *Env = - GenericEnvironment::get(Context, InterfaceToArchetypeMap); + GenericEnvironment::get(Context, GenericParamTypes, + InterfaceToArchetypeMap); Type InterfaceType = GenericFunctionType::get(Sig, ArgParamType, ResType, AnyFunctionType::ExtInfo()); diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp index 6b4bf911756c5..74ec859954e05 100644 --- a/lib/AST/GenericEnvironment.cpp +++ b/lib/AST/GenericEnvironment.cpp @@ -20,10 +20,14 @@ using namespace swift; GenericEnvironment::GenericEnvironment( + ArrayRef genericParamTypes, TypeSubstitutionMap interfaceToArchetypeMap) { assert(!interfaceToArchetypeMap.empty()); + for (auto *paramTy : genericParamTypes) + GenericParams.push_back(paramTy); + // Build a mapping in both directions, making sure to canonicalize the // interface type where it is used as a key, so that substitution can // find them, and to preserve sugar otherwise, so that @@ -74,6 +78,15 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const { return found->second; } +GenericTypeParamType *GenericEnvironment::getSugaredType( + GenericTypeParamType *type) const { + for (auto *sugaredType : GenericParams) + if (sugaredType->isEqual(type)) + return sugaredType; + + llvm_unreachable("missing generic parameter"); +} + ArrayRef GenericEnvironment::getForwardingSubstitutions( ModuleDecl *M, GenericSignature *sig) const { diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index b4db203e752d1..fbd02424b3319 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -6861,8 +6861,8 @@ buildGenericSignature(GenericParamList *genericParams, param->getDeclaredType()->castTo()); } - auto *sig = builder.getGenericSignature(genericParamTypes); - auto *env = builder.getGenericEnvironment(genericParamTypes); + auto *sig = builder.getGenericSignature(); + auto *env = builder.getGenericEnvironment(); return std::make_pair(sig, env); } diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp index 9989370b71bfb..6678c163b0290 100644 --- a/lib/SIL/SILPrinter.cpp +++ b/lib/SIL/SILPrinter.cpp @@ -30,6 +30,7 @@ #include "swift/SIL/SILVTable.h" #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" +#include "swift/AST/GenericEnvironment.h" #include "swift/AST/Module.h" #include "swift/AST/PrintOptions.h" #include "swift/AST/Types.h" @@ -1835,21 +1836,25 @@ void SILFunction::print(SILPrintContext &PrintCtx) const { llvm::SmallString<16> disambiguatedNameBuf; unsigned disambiguatedNameCounter = 1; for (auto *paramTy : sig->getGenericParams()) { - auto *archetypeTy = mapTypeIntoContext(paramTy)->getAs(); - if (!archetypeTy) - continue; - - Identifier name = archetypeTy->getName(); + auto sugaredTy = env->getSugaredType(paramTy); + Identifier name = sugaredTy->getName(); while (!UsedNames.insert(name).second) { disambiguatedNameBuf.clear(); { llvm::raw_svector_ostream names(disambiguatedNameBuf); - names << archetypeTy->getName() << disambiguatedNameCounter++; + names << sugaredTy->getName() << disambiguatedNameCounter++; } name = getASTContext().getIdentifier(disambiguatedNameBuf); } - if (name != archetypeTy->getName()) - Aliases[CanType(archetypeTy)] = name; + if (name != sugaredTy->getName()) { + Aliases[paramTy->getCanonicalType()] = name; + + // Also for the archetype + auto archetypeTy = env->mapTypeIntoContext(paramTy) + ->getAs(); + if (archetypeTy) + Aliases[archetypeTy->getCanonicalType()] = name; + } } } diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp index 796f2926cfab4..7ac7392b35eb1 100644 --- a/lib/SILGen/SILGenDecl.cpp +++ b/lib/SILGen/SILGenDecl.cpp @@ -1780,7 +1780,7 @@ substSelfTypeIntoProtocolRequirementType(SILModule &M, if (!allParams.empty()) { builder.finalize(SourceLoc()); - auto *sig = builder.getGenericSignature(allParams); + auto *sig = builder.getGenericSignature(); return cast( GenericFunctionType::get(sig, input, result, reqtTy->getExtInfo()) @@ -1800,6 +1800,7 @@ getSubstitutedGenericEnvironment(SILModule &M, return reqtEnv; } + SmallVector genericParamTypes; TypeSubstitutionMap witnessContextParams; auto selfTy = conformance->getProtocol()->getSelfInterfaceType() @@ -1809,8 +1810,14 @@ getSubstitutedGenericEnvironment(SILModule &M, // the conformance (which might not be the same as the generic // context of the witness, if the witness is defined in a // superclass, concrete extension or protocol extension). - if (auto *outerEnv = conformance->getGenericEnvironment()) + if (auto *outerEnv = conformance->getGenericEnvironment()) { witnessContextParams = outerEnv->getInterfaceToArchetypeMap(); + for (auto *paramTy : outerEnv->getGenericParams()) + genericParamTypes.push_back(paramTy); + } + + for (auto *paramTy : reqtEnv->getGenericParams().slice(1)) + genericParamTypes.push_back(paramTy); // Inner generic parameters come from the requirement and // also map to the archetypes of the requirement. @@ -1824,7 +1831,8 @@ getSubstitutedGenericEnvironment(SILModule &M, } if (!witnessContextParams.empty()) - return GenericEnvironment::get(M.getASTContext(), witnessContextParams); + return GenericEnvironment::get(M.getASTContext(), genericParamTypes, + witnessContextParams); return nullptr; } diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index abaaaf1f1f4d7..a6dd871f1e584 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -738,7 +738,7 @@ TypeChecker::handleSILGenericParams(GenericParamList *genericParams, checkGenericParamList(&builder, genericParams, parentSig, parentEnv, nullptr); parentSig = genericSig; - parentEnv = builder.getGenericEnvironment(genericSig->getGenericParams()); + parentEnv = builder.getGenericEnvironment(); finalizeGenericParamList(genericParams, parentSig, parentEnv, DC); } @@ -4841,7 +4841,7 @@ class DeclChecker : public DeclVisitor { // Assign archetypes. auto *sig = FD->getGenericSignature(); - auto *env = builder.getGenericEnvironment(sig->getGenericParams()); + auto *env = builder.getGenericEnvironment(); FD->setGenericEnvironment(env); TC.finalizeGenericParamList(gp, sig, env, FD); @@ -6529,7 +6529,7 @@ class DeclChecker : public DeclVisitor { // Assign archetypes. auto *sig = CD->getGenericSignature(); - auto *env = builder.getGenericEnvironment(sig->getGenericParams()); + auto *env = builder.getGenericEnvironment(); CD->setGenericEnvironment(env); TC.finalizeGenericParamList(gp, sig, env, CD); @@ -7540,7 +7540,7 @@ static Type checkExtensionGenericParams( tc.checkGenericParamList(&builder, genericParams, parentSig, parentEnv, nullptr); inferExtendedTypeReqs(builder); - auto *env = builder.getGenericEnvironment(sig->getGenericParams()); + auto *env = builder.getGenericEnvironment(); ext->setGenericEnvironment(env); tc.finalizeGenericParamList(genericParams, sig, env, ext); diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 7fc9cfcfccdc2..c85abaa7f7804 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -361,27 +361,6 @@ void TypeChecker::checkGenericParamList(ArchetypeBuilder *builder, } } -/// Collect all of the generic parameter types at every level in the generic -/// parameter list. -static void collectGenericParamTypes( - GenericParamList *genericParams, - GenericSignature *parentSig, - SmallVectorImpl &allParams) { - // If the parent context has a generic signature, add its generic parameters. - if (parentSig) { - allParams.append(parentSig->getGenericParams().begin(), - parentSig->getGenericParams().end()); - } - - if (genericParams) { - // Add our parameters. - for (auto param : *genericParams) { - allParams.push_back(param->getDeclaredType() - ->castTo()); - } - } -} - /// Check the signature of a generic function. static bool checkGenericFuncSignature(TypeChecker &tc, ArchetypeBuilder *builder, @@ -508,14 +487,7 @@ void TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { // The generic function signature is complete and well-formed. Determine // the type of the generic function. - - // Collect the complete set of generic parameter types. - SmallVector allGenericParams; - collectGenericParamTypes(func->getGenericParams(), - func->getDeclContext()->getGenericSignatureOfContext(), - allGenericParams); - - auto sig = builder.getGenericSignature(allGenericParams); + auto sig = builder.getGenericSignature(); // Debugging of the archetype builder and generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { @@ -712,13 +684,8 @@ GenericSignature *TypeChecker::validateGenericSignature( checkGenericParamList(nullptr, genericParams, nullptr, nullptr, &completeResolver); - // The generic signature is complete and well-formed. Gather the - // generic parameter types at all levels. - SmallVector allGenericParams; - collectGenericParamTypes(genericParams, parentSig, allGenericParams); - // Record the generic type parameter types and the requirements. - auto sig = builder.getGenericSignature(allGenericParams); + auto sig = builder.getGenericSignature(); // Debugging of the archetype builder and generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { @@ -885,7 +852,7 @@ void TypeChecker::validateGenericTypeSignature(GenericTypeDecl *typeDecl) { auto *parentEnv = dc->getGenericEnvironmentOfContext(); checkGenericParamList(&builder, gp, parentSig, parentEnv, nullptr); - auto *env = builder.getGenericEnvironment(sig->getGenericParams()); + auto *env = builder.getGenericEnvironment(); typeDecl->setGenericEnvironment(env); finalizeGenericParamList(gp, sig, env, typeDecl); diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 3190375d7a32a..7790c76cf4796 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -876,6 +876,32 @@ GenericEnvironment *ModuleFile::readGenericEnvironment( paramTypes.push_back(paramTy); break; } + case SIL_GENERIC_ENVIRONMENT: { + uint64_t rawTypeIDs[2]; + IdentifierID IID; + SILGenericEnvironmentLayout::readRecord(scratch, IID, + rawTypeIDs[0], rawTypeIDs[1]); + + auto paramTy = getType(rawTypeIDs[0])->castTo(); + auto contextTy = getType(rawTypeIDs[1]); + + // Cons up a sugared type for this generic parameter + Identifier name = getIdentifier(IID); + auto paramDecl = createDecl(getAssociatedModule(), + name, + SourceLoc(), + paramTy->getDepth(), + paramTy->getIndex()); + paramTy = paramDecl->getDeclaredInterfaceType() + ->castTo(); + + auto result = interfaceToArchetypeMap.insert( + std::make_pair(paramTy, contextTy)); + + assert(result.second); + paramTypes.push_back(paramTy); + break; + } default: // This record is not part of the GenericEnvironment. shouldContinue = false; @@ -889,7 +915,8 @@ GenericEnvironment *ModuleFile::readGenericEnvironment( if (interfaceToArchetypeMap.empty()) return nullptr; - return GenericEnvironment::get(getContext(), interfaceToArchetypeMap); + return GenericEnvironment::get(getContext(), paramTypes, + interfaceToArchetypeMap); } std::pair diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 07af22d32c02a..bc0b0a7fe367c 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -529,6 +529,8 @@ void Serializer::writeBlockInfoBlock() { decls_block::GENERIC_REQUIREMENT); BLOCK_RECORD_WITH_NAMESPACE(sil_block, decls_block::GENERIC_ENVIRONMENT); + BLOCK_RECORD_WITH_NAMESPACE(sil_block, + decls_block::SIL_GENERIC_ENVIRONMENT); BLOCK(SIL_INDEX_BLOCK); BLOCK_RECORD(sil_index_block, SIL_FUNC_NAMES); @@ -971,24 +973,32 @@ bool Serializer::writeGenericParams(const GenericParamList *genericParams) { return true; } -void Serializer::writeGenericEnvironment(GenericSignature *sig, - GenericEnvironment *env, +void Serializer::writeGenericEnvironment(GenericEnvironment *env, const std::array &abbrCodes) { using namespace decls_block; if (env == nullptr) return; - auto envAbbrCode = abbrCodes[GenericEnvironmentLayout::Code]; - - // Iterate over the signature's generic parameters, for stable - // iteration order. - for (auto *paramTy : sig->getGenericParams()) { + for (auto *paramTy : env->getGenericParams()) { auto contextTy = env->mapTypeIntoContext(paramTy); - GenericEnvironmentLayout::emitRecord( - Out, ScratchRecord, envAbbrCode, - addTypeRef(paramTy), - addTypeRef(contextTy)); + auto *decl = paramTy->getDecl(); + + if (decl && decl->getDeclContext()->isModuleScopeContext()) { + auto envAbbrCode = abbrCodes[SILGenericEnvironmentLayout::Code]; + auto nameID = addIdentifierRef(decl->getName()); + SILGenericEnvironmentLayout::emitRecord( + Out, ScratchRecord, envAbbrCode, + nameID, + addTypeRef(paramTy->getCanonicalType()), + addTypeRef(contextTy)); + } else { + auto envAbbrCode = abbrCodes[GenericEnvironmentLayout::Code]; + GenericEnvironmentLayout::emitRecord( + Out, ScratchRecord, envAbbrCode, + addTypeRef(paramTy), + addTypeRef(contextTy)); + } } } @@ -2056,8 +2066,7 @@ void Serializer::writeDecl(const Decl *D) { } writeGenericParams(extension->getGenericParams()); - writeGenericEnvironment(extension->getGenericSignature(), - extension->getGenericEnvironment(), + writeGenericEnvironment(extension->getGenericEnvironment(), DeclTypeAbbrCodes); writeGenericRequirements(extension->getGenericRequirements()); writeMembers(extension->getMembers(), isClassExtension); @@ -2192,8 +2201,7 @@ void Serializer::writeDecl(const Decl *D) { typeAlias->isImplicit(), rawAccessLevel); writeGenericParams(typeAlias->getGenericParams()); - writeGenericEnvironment(typeAlias->getGenericSignature(), - typeAlias->getGenericEnvironment(), + writeGenericEnvironment(typeAlias->getGenericEnvironment(), DeclTypeAbbrCodes); writeGenericRequirements(typeAlias->getGenericRequirements()); break; @@ -2269,8 +2277,7 @@ void Serializer::writeDecl(const Decl *D) { writeGenericParams(theStruct->getGenericParams()); - writeGenericEnvironment(theStruct->getGenericSignature(), - theStruct->getGenericEnvironment(), + writeGenericEnvironment(theStruct->getGenericEnvironment(), DeclTypeAbbrCodes); writeGenericRequirements(theStruct->getGenericRequirements()); writeMembers(theStruct->getMembers(), false); @@ -2306,8 +2313,7 @@ void Serializer::writeDecl(const Decl *D) { inheritedTypes); writeGenericParams(theEnum->getGenericParams()); - writeGenericEnvironment(theEnum->getGenericSignature(), - theEnum->getGenericEnvironment(), + writeGenericEnvironment(theEnum->getGenericEnvironment(), DeclTypeAbbrCodes); writeGenericRequirements(theEnum->getGenericRequirements()); writeMembers(theEnum->getMembers(), false); @@ -2346,8 +2352,7 @@ void Serializer::writeDecl(const Decl *D) { inheritedTypes); writeGenericParams(theClass->getGenericParams()); - writeGenericEnvironment(theClass->getGenericSignature(), - theClass->getGenericEnvironment(), + writeGenericEnvironment(theClass->getGenericEnvironment(), DeclTypeAbbrCodes); writeGenericRequirements(theClass->getGenericRequirements()); writeMembers(theClass->getMembers(), true); @@ -2385,8 +2390,7 @@ void Serializer::writeDecl(const Decl *D) { protocolsAndInherited); writeGenericParams(proto->getGenericParams()); - writeGenericEnvironment(proto->getGenericSignature(), - proto->getGenericEnvironment(), + writeGenericEnvironment(proto->getGenericEnvironment(), DeclTypeAbbrCodes); writeGenericRequirements(proto->getGenericRequirements()); writeMembers(proto->getMembers(), true); @@ -2489,8 +2493,7 @@ void Serializer::writeDecl(const Decl *D) { nameComponents); writeGenericParams(fn->getGenericParams()); - writeGenericEnvironment(fn->getGenericSignature(), - fn->getGenericEnvironment(), + writeGenericEnvironment(fn->getGenericEnvironment(), DeclTypeAbbrCodes); // Write the body parameters. @@ -2609,8 +2612,7 @@ void Serializer::writeDecl(const Decl *D) { nameComponents); writeGenericParams(ctor->getGenericParams()); - writeGenericEnvironment(ctor->getGenericSignature(), - ctor->getGenericEnvironment(), + writeGenericEnvironment(ctor->getGenericEnvironment(), DeclTypeAbbrCodes); assert(ctor->getParameterLists().size() == 2); diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h index dc8486b5d722c..809b50a720878 100644 --- a/lib/Serialization/Serialization.h +++ b/lib/Serialization/Serialization.h @@ -416,8 +416,7 @@ class Serializer { const std::array &abbrCodes); /// Writes a generic environment. - void writeGenericEnvironment(GenericSignature *sig, - GenericEnvironment *env, + void writeGenericEnvironment(GenericEnvironment *env, const std::array &abbrCodes); }; diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 51949842585e1..02c947622155e 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -374,10 +374,8 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { // Write the body's context archetypes, unless we don't actually have a body. if (!F.isExternalDeclaration()) { - if (auto genericEnv = F.getGenericEnvironment()) { - auto genericSig = F.getLoweredFunctionType()->getGenericSignature(); - S.writeGenericEnvironment(genericSig, genericEnv, SILAbbrCodes); - } + if (auto genericEnv = F.getGenericEnvironment()) + S.writeGenericEnvironment(genericEnv, SILAbbrCodes); } // Assign a unique ID to each basic block of the SILFunction. @@ -1881,6 +1879,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); + registerSILAbbr(); for (const SILGlobalVariable &g : SILMod->getSILGlobals()) writeSILGlobalVar(g); diff --git a/test/SILGen/constrained_extensions.swift b/test/SILGen/constrained_extensions.swift index 8006fdce84a38..a6845f9877168 100644 --- a/test/SILGen/constrained_extensions.swift +++ b/test/SILGen/constrained_extensions.swift @@ -63,15 +63,15 @@ extension Array where Element == Int { } extension Dictionary where Key == Int { - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10DictionaryCfT1xT__GS0_xq__ : $@convention(method) (@thin Dictionary.Type) -> @owned Dictionary { + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10DictionaryCfT1xT__GS0_xq__ : $@convention(method) (@thin Dictionary.Type) -> @owned Dictionary { public init(x: ()) { self.init() } - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionaryg16instancePropertyq_ : $@convention(method) (@guaranteed Dictionary) -> @out Value - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionarys16instancePropertyq_ : $@convention(method) (@in Value, @inout Dictionary) -> () - // CHECK-LABEL: sil [transparent] [fragile] @_TFe22constrained_extensions0_RxzSirVs10Dictionarym16instancePropertyq_ : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout Dictionary) -> (Builtin.RawPointer, Optional) - // CHECK-LABEL: sil [transparent] [fragile] @_TFFe22constrained_extensions0_RxzSirVs10Dictionarym16instancePropertyq_U_T_ : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout Dictionary, @thick Dictionary.Type) -> () + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionaryg16instancePropertyq_ : $@convention(method) (@guaranteed Dictionary) -> @out Value + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionarys16instancePropertyq_ : $@convention(method) (@in Value, @inout Dictionary) -> () + // CHECK-LABEL: sil [transparent] [fragile] @_TFe22constrained_extensions0_RxzSirVs10Dictionarym16instancePropertyq_ : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout Dictionary) -> (Builtin.RawPointer, Optional) + // CHECK-LABEL: sil [transparent] [fragile] @_TFFe22constrained_extensions0_RxzSirVs10Dictionarym16instancePropertyq_U_T_ : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout Dictionary, @thick Dictionary.Type) -> () public var instanceProperty: Value { get { return self[0]! @@ -81,49 +81,49 @@ extension Dictionary where Key == Int { } } - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionary14instanceMethodfT_q_ : $@convention(method) (@guaranteed Dictionary) -> @out Value + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionary14instanceMethodfT_q_ : $@convention(method) (@guaranteed Dictionary) -> @out Value public func instanceMethod() -> Value { return instanceProperty } - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionary14instanceMethodfT1vq__q_ : $@convention(method) (@in Value, @guaranteed Dictionary) -> @out Value + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionary14instanceMethodfT1vq__q_ : $@convention(method) (@in Value, @guaranteed Dictionary) -> @out Value public func instanceMethod(v: Value) -> Value { return v } - // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodfT_x : $@convention(method) (@thin Dictionary.Type) -> Int + // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodfT_x : $@convention(method) (@thin Dictionary.Type) -> Int public static func staticMethod() -> Key { return staticProperty } - // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionaryg14staticPropertySi : $@convention(method) (@thin Dictionary.Type) -> Int + // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionaryg14staticPropertySi : $@convention(method) (@thin Dictionary.Type) -> Int public static var staticProperty: Key { return 0 } - // CHECK-LABEL: sil @_TIZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodFT1kGSqx_1vGSqq___q_A_ : $@convention(thin) () -> Optional - // CHECK-LABEL: sil @_TIZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodFT1kGSqx_1vGSqq___q_A0_ : $@convention(thin) () -> @out Optional - // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodfT1kGSqx_1vGSqq___q_ : $@convention(method) (Optional, @in Optional, @thin Dictionary.Type) -> @out Value + // CHECK-LABEL: sil @_TIZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodFT1kGSqx_1vGSqq___q_A_ : $@convention(thin) () -> Optional + // CHECK-LABEL: sil @_TIZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodFT1kGSqx_1vGSqq___q_A0_ : $@convention(thin) () -> @out Optional + // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary12staticMethodfT1kGSqx_1vGSqq___q_ : $@convention(method) (Optional, @in Optional, @thin Dictionary.Type) -> @out Value public static func staticMethod(k: Key? = nil, v: Value? = nil) -> Value { return v! } - // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary17callsStaticMethodfT_q_ : $@convention(method) (@thin Dictionary.Type) -> @out Value + // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary17callsStaticMethodfT_q_ : $@convention(method) (@thin Dictionary.Type) -> @out Value public static func callsStaticMethod() -> Value { return staticMethod() } - // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary16callsConstructorfT_q_ : $@convention(method) (@thin Dictionary.Type) -> @out Value + // CHECK-LABEL: sil @_TZFe22constrained_extensions0_RxzSirVs10Dictionary16callsConstructorfT_q_ : $@convention(method) (@thin Dictionary.Type) -> @out Value public static func callsConstructor() -> Value { return Dictionary(x: ()).instanceMethod() } - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionaryg9subscriptFT_q_ : $@convention(method) (@guaranteed Dictionary) -> @out Value + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionaryg9subscriptFT_q_ : $@convention(method) (@guaranteed Dictionary) -> @out Value public subscript(i: ()) -> Value { return self[0]! } - // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionary21inoutAccessOfPropertyfT_T_ : $@convention(method) (@inout Dictionary) -> () + // CHECK-LABEL: sil @_TFe22constrained_extensions0_RxzSirVs10Dictionary21inoutAccessOfPropertyfT_T_ : $@convention(method) (@inout Dictionary) -> () public mutating func inoutAccessOfProperty() { func increment(x: inout Value) { } From 092a9318ee9154a25d6dae22b580a619b3fde636 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 12 Oct 2016 17:13:44 -0700 Subject: [PATCH 2/3] Serialization: Remove some unused code Previous refactorings introducing GenericEnvironment left behind some lint. --- include/swift/Serialization/ModuleFormat.h | 13 ++++++------- lib/Serialization/Deserialization.cpp | 10 +--------- lib/Serialization/SILFormat.h | 7 ------- lib/Serialization/Serialization.cpp | 8 +------- lib/Serialization/SerializeSIL.cpp | 1 - 5 files changed, 8 insertions(+), 31 deletions(-) diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h index e0412f95bcde3..3c4da1615a2e7 100644 --- a/include/swift/Serialization/ModuleFormat.h +++ b/include/swift/Serialization/ModuleFormat.h @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0; /// in source control, you should also update the comment to briefly /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. -const uint16_t VERSION_MINOR = 274; // Last change: SIL generic environment sugar +const uint16_t VERSION_MINOR = 275; // Last change: remove some unused bits using DeclID = PointerEmbeddedInt; using DeclIDField = BCFixed<31>; @@ -769,12 +769,11 @@ namespace decls_block { using GenericTypeParamDeclLayout = BCRecordLayout< GENERIC_TYPE_PARAM_DECL, - IdentifierIDField, // name - DeclContextIDField,// context decl - BCFixed<1>, // implicit flag - BCVBR<4>, // depth - BCVBR<4>, // index - BCArray // inherited types + IdentifierIDField, // name + DeclContextIDField, // context decl + BCFixed<1>, // implicit flag + BCVBR<4>, // depth + BCVBR<4> // index >; using AssociatedTypeDeclLayout = BCRecordLayout< diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 7790c76cf4796..cfb6465b3b6e2 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -2240,14 +2240,12 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { bool isImplicit; unsigned depth; unsigned index; - ArrayRef rawInheritedIDs; decls_block::GenericTypeParamDeclLayout::readRecord(scratch, nameID, contextID, isImplicit, depth, - index, - rawInheritedIDs); + index); auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID); @@ -2264,12 +2262,6 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { if (isImplicit) genericParam->setImplicit(); - auto inherited = ctx.Allocate(rawInheritedIDs.size()); - for_each(inherited, rawInheritedIDs, [this](TypeLoc &loc, uint64_t rawID) { - loc.setType(getType(rawID)); - }); - genericParam->setInherited(inherited); - genericParam->setCheckedInheritanceClause(); break; } diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h index f42666ad2898e..3cba3bb371336 100644 --- a/lib/Serialization/SILFormat.h +++ b/lib/Serialization/SILFormat.h @@ -141,7 +141,6 @@ namespace sil_block { SIL_DEFAULT_WITNESS_TABLE, SIL_DEFAULT_WITNESS_TABLE_ENTRY, SIL_DEFAULT_WITNESS_TABLE_NO_ENTRY, - SIL_GENERIC_OUTER_PARAMS, SIL_INST_WITNESS_METHOD, SIL_SPECIALIZE_ATTR, @@ -154,7 +153,6 @@ namespace sil_block { = decls_block::SPECIALIZED_PROTOCOL_CONFORMANCE, INHERITED_PROTOCOL_CONFORMANCE = decls_block::INHERITED_PROTOCOL_CONFORMANCE, - GENERIC_PARAM_LIST = decls_block::GENERIC_PARAM_LIST, GENERIC_PARAM = decls_block::GENERIC_PARAM, GENERIC_REQUIREMENT = decls_block::GENERIC_REQUIREMENT, }; @@ -385,11 +383,6 @@ namespace sil_block { TypeIDField // Result type >; - using SILGenericOuterParamsLayout = BCRecordLayout< - SIL_GENERIC_OUTER_PARAMS, - DeclIDField // The decl id of the outer param if any. - >; - using SILInstWitnessMethodLayout = BCRecordLayout< SIL_INST_WITNESS_METHOD, TypeIDField, // result type diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index bc0b0a7fe367c..09ef2c6d394b4 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -501,7 +501,6 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(sil_block, SIL_DEFAULT_WITNESS_TABLE); BLOCK_RECORD(sil_block, SIL_DEFAULT_WITNESS_TABLE_ENTRY); BLOCK_RECORD(sil_block, SIL_DEFAULT_WITNESS_TABLE_NO_ENTRY); - BLOCK_RECORD(sil_block, SIL_GENERIC_OUTER_PARAMS); BLOCK_RECORD(sil_block, SIL_INST_WITNESS_METHOD); BLOCK_RECORD(sil_block, SIL_SPECIALIZE_ATTR); @@ -2213,18 +2212,13 @@ void Serializer::writeDecl(const Decl *D) { auto contextID = addDeclContextRef(genericParam->getDeclContext()); - SmallVector inheritedTypes; - for (auto inherited : genericParam->getInherited()) - inheritedTypes.push_back(addTypeRef(inherited.getType())); - unsigned abbrCode = DeclTypeAbbrCodes[GenericTypeParamDeclLayout::Code]; GenericTypeParamDeclLayout::emitRecord(Out, ScratchRecord, abbrCode, addIdentifierRef(genericParam->getName()), contextID, genericParam->isImplicit(), genericParam->getDepth(), - genericParam->getIndex(), - inheritedTypes); + genericParam->getIndex()); break; } diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 02c947622155e..0b944f950160c 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -1860,7 +1860,6 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); - registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); From 25e00d78d14cc174bfe924ed28c3355a33e22e59 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Wed, 5 Oct 2016 09:28:02 -0700 Subject: [PATCH 3/3] [AnyHashable] Eliminate the _AnyHashableProtocol hack. Now that we have the ability to write extensions where one of the type parameters is equivalent to a concrete type, eliminate _AnyHashableProtocol and provide AnyHashable-specific behavior for Dictionary (where Key == AnyHashable) and Set (where Element == AnyHashable) rather than employing the "Key: _AnyHashableProtocol" hack. Fixes standard library ABI FIXME's #35, #37, #39. --- ...CollectionsAnyHashableExtensions.swift.gyb | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb b/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb index 406117e8af26e..b38ae8c4f34b9 100644 --- a/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb +++ b/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb @@ -10,16 +10,6 @@ // //===----------------------------------------------------------------------===// -// FIXME(ABI)#35 (Concrete Same Type Requirements): This protocol exists to identify -// `AnyHashable` in conditional extensions. Replace this protocol -// with conditional extensions on `Set` and `Dictionary` "where Key == -// AnyHashable". -public protocol _AnyHashableProtocol { - var base: Any { get } -} - -extension AnyHashable : _AnyHashableProtocol {} - //===----------------------------------------------------------------------===// // Convenience APIs for Set //===----------------------------------------------------------------------===// @@ -49,8 +39,7 @@ extension Set { } } -// FIXME(ABI)#37 (Concrete Same Type Requirements): replace with `where Element == AnyHashable`. -extension Set where Element : _AnyHashableProtocol { +extension Set where Element == AnyHashable { public mutating func insert( _ newMember: ConcreteElement ) -> (inserted: Bool, memberAfterInsert: ConcreteElement) { @@ -65,7 +54,7 @@ extension Set where Element : _AnyHashableProtocol { public mutating func update( with newMember: ConcreteElement ) -> ConcreteElement? { - return _concreteElement_update(with: AnyHashable(newMember) as! Element) + return _concreteElement_update(with: AnyHashable(newMember)) .map { $0.base as! ConcreteElement } } @@ -73,7 +62,7 @@ extension Set where Element : _AnyHashableProtocol { public mutating func remove( _ member: ConcreteElement ) -> ConcreteElement? { - return _concreteElement_remove(AnyHashable(member) as! Element) + return _concreteElement_remove(AnyHashable(member)) .map { $0.base as! ConcreteElement } } } @@ -109,16 +98,15 @@ extension Dictionary { } } -// FIXME(ABI)#39 (Concrete Same Type Requirements): replace with `where Element == AnyHashable`. -extension Dictionary where Key : _AnyHashableProtocol { +extension Dictionary where Key == AnyHashable { public subscript(_ key: _Hashable) -> Value? { // FIXME(ABI)#40 (Generic subscripts): replace this API with a // generic subscript. get { - return self[_concreteKey: key._toAnyHashable() as! Key] + return self[_concreteKey: key._toAnyHashable()] } set { - self[_concreteKey: key._toAnyHashable() as! Key] = newValue + self[_concreteKey: key._toAnyHashable()] = newValue } } @@ -126,14 +114,14 @@ extension Dictionary where Key : _AnyHashableProtocol { public mutating func updateValue( _ value: Value, forKey key: ConcreteKey ) -> Value? { - return _concreteKey_updateValue(value, forKey: AnyHashable(key) as! Key) + return _concreteKey_updateValue(value, forKey: AnyHashable(key)) } @discardableResult public mutating func removeValue( forKey key: ConcreteKey ) -> Value? { - return _concreteKey_removeValue(forKey: AnyHashable(key) as! Key) + return _concreteKey_removeValue(forKey: AnyHashable(key)) } }