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..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 = 273; // Last change: partial_apply ownership control +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< @@ -1095,21 +1094,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..cfb6465b3b6e2 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 @@ -2213,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); @@ -2237,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 07af22d32c02a..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); @@ -529,6 +528,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 +972,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 +2065,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 +2200,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; @@ -2205,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; } @@ -2269,8 +2271,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 +2307,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 +2346,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 +2384,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 +2487,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 +2606,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..0b944f950160c 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. @@ -1862,7 +1860,6 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); - registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); @@ -1881,6 +1878,7 @@ void SILSerializer::writeSILBlock(const SILModule *SILMod) { registerSILAbbr(); registerSILAbbr(); registerSILAbbr(); + registerSILAbbr(); for (const SILGlobalVariable &g : SILMod->getSILGlobals()) writeSILGlobalVar(g); 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)) } } 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) { }