diff --git a/include/swift/AST/SubstitutionMap.h b/include/swift/AST/SubstitutionMap.h index 4b7451ca657..066bbcd2b82 100644 --- a/include/swift/AST/SubstitutionMap.h +++ b/include/swift/AST/SubstitutionMap.h @@ -73,22 +73,6 @@ private: /// signature nor any replacement types/conformances. Storage *storage = nullptr; -public: - /// Retrieve the array of replacement types, which line up with the - /// generic parameters. - /// - /// Note that the types may be null, for cases where the generic parameter - /// is concrete but hasn't been queried yet. - /// - /// Prefer \c getReplacementTypes, this is public for printing purposes. - ArrayRef getReplacementTypesBuffer() const; - -private: - MutableArrayRef getReplacementTypesBuffer(); - - /// Retrieve a mutable reference to the buffer of conformances. - MutableArrayRef getConformancesBuffer(); - /// Form a substitution map for the given generic signature with the /// specified replacement types and conformances. SubstitutionMap(GenericSignature genericSig, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index feac324505f..d94ce09709c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -5296,21 +5296,11 @@ void SubstitutionMap::Storage::Profile( id.AddPointer(genericSig.getPointer()); if (!genericSig) return; - // Profile those replacement types that corresponding to canonical generic - // parameters within the generic signature. - id.AddInteger(replacementTypes.size()); - - unsigned i = 0; - genericSig->forEachParam([&](GenericTypeParamType *gp, bool canonical) { - if (canonical) - id.AddPointer(replacementTypes[i].getPointer()); - else - id.AddPointer(nullptr); - ++i; - }); + // Replacement types. + for (auto replacementType : replacementTypes) + id.AddPointer(replacementType.getPointer()); // Conformances. - id.AddInteger(conformances.size()); for (auto conformance : conformances) id.AddPointer(conformance.getOpaqueValue()); } diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 7ee62b175d4..75db1162b42 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3816,16 +3816,13 @@ public: auto genericParams = genericSig.getGenericParams(); auto replacementTypes = - static_cast(map).getReplacementTypesBuffer(); + static_cast(map).getReplacementTypes(); for (unsigned i : indices(genericParams)) { if (style == SubstitutionMap::DumpStyle::Minimal) { printFieldRaw([&](raw_ostream &out) { genericParams[i]->print(out); out << " -> "; - if (replacementTypes[i]) - out << replacementTypes[i]; - else - out << ""; + out << replacementTypes[i]; }, ""); } else { printRecArbitrary([&](StringRef label) { @@ -3834,8 +3831,7 @@ public: genericParams[i]->print(out); out << " -> "; }, ""); - if (replacementTypes[i]) - printRec(replacementTypes[i]); + printRec(replacementTypes[i]); printFoot(); }); } diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp index a8186f65660..36f2491ea92 100644 --- a/lib/AST/SubstitutionMap.cpp +++ b/lib/AST/SubstitutionMap.cpp @@ -55,7 +55,6 @@ SubstitutionMap::Storage::Storage( getReplacementTypes().data()); std::copy(conformances.begin(), conformances.end(), getConformances().data()); - populatedAllReplacements = false; } SubstitutionMap::SubstitutionMap( @@ -69,20 +68,6 @@ SubstitutionMap::SubstitutionMap( #endif } -ArrayRef SubstitutionMap::getReplacementTypesBuffer() const { - return storage ? storage->getReplacementTypes() : ArrayRef(); -} - -MutableArrayRef SubstitutionMap::getReplacementTypesBuffer() { - return storage ? storage->getReplacementTypes() : MutableArrayRef(); -} - -MutableArrayRef -SubstitutionMap::getConformancesBuffer() { - return storage ? storage->getConformances() - : MutableArrayRef(); -} - ArrayRef SubstitutionMap::getConformances() const { return storage ? storage->getConformances() : ArrayRef(); @@ -91,16 +76,7 @@ ArrayRef SubstitutionMap::getConformances() const { ArrayRef SubstitutionMap::getReplacementTypes() const { if (empty()) return { }; - // Make sure we've filled in all of the replacement types. - if (!storage->populatedAllReplacements) { - for (auto gp : getGenericSignature().getGenericParams()) { - (void)lookupSubstitution(cast(gp->getCanonicalType())); - } - - storage->populatedAllReplacements = true; - } - - return getReplacementTypesBuffer(); + return storage->getReplacementTypes(); } ArrayRef SubstitutionMap::getInnermostReplacementTypes() const { @@ -126,32 +102,32 @@ bool SubstitutionMap::hasAnySubstitutableParams() const { } bool SubstitutionMap::hasArchetypes() const { - for (Type replacementTy : getReplacementTypesBuffer()) { - if (replacementTy && replacementTy->hasArchetype()) + for (Type replacementTy : getReplacementTypes()) { + if (replacementTy->hasArchetype()) return true; } return false; } bool SubstitutionMap::hasLocalArchetypes() const { - for (Type replacementTy : getReplacementTypesBuffer()) { - if (replacementTy && replacementTy->hasLocalArchetype()) + for (Type replacementTy : getReplacementTypes()) { + if (replacementTy->hasLocalArchetype()) return true; } return false; } bool SubstitutionMap::hasOpaqueArchetypes() const { - for (Type replacementTy : getReplacementTypesBuffer()) { - if (replacementTy && replacementTy->hasOpaqueArchetype()) + for (Type replacementTy : getReplacementTypes()) { + if (replacementTy->hasOpaqueArchetype()) return true; } return false; } bool SubstitutionMap::hasDynamicSelf() const { - for (Type replacementTy : getReplacementTypesBuffer()) { - if (replacementTy && replacementTy->hasDynamicSelfType()) + for (Type replacementTy : getReplacementTypes()) { + if (replacementTy->hasDynamicSelfType()) return true; } return false; @@ -162,8 +138,8 @@ bool SubstitutionMap::isCanonical() const { if (!getGenericSignature()->isCanonical()) return false; - for (Type replacementTy : getReplacementTypesBuffer()) { - if (replacementTy && !replacementTy->isCanonical()) + for (Type replacementTy : getReplacementTypes()) { + if (!replacementTy->isCanonical()) return false; } @@ -182,11 +158,8 @@ SubstitutionMap SubstitutionMap::getCanonical(bool canonicalizeSignature) const if (canonicalizeSignature) sig = sig.getCanonicalSignature(); SmallVector replacementTypes; - for (Type replacementType : getReplacementTypesBuffer()) { - if (replacementType) - replacementTypes.push_back(replacementType->getCanonicalType()); - else - replacementTypes.push_back(nullptr); + for (Type replacementType : getReplacementTypes()) { + replacementTypes.push_back(replacementType->getCanonicalType()); } SmallVector conformances; @@ -237,13 +210,7 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig, SmallVector replacementTypes; replacementTypes.reserve(genericSig.getGenericParams().size()); - genericSig->forEachParam([&](GenericTypeParamType *gp, bool canonical) { - // Don't eagerly form replacements for non-canonical generic parameters. - if (!canonical) { - replacementTypes.push_back(Type()); - return; - } - + for (auto *gp : genericSig.getGenericParams()) { // Record the replacement. Type replacement = Type(gp).subst(IFS); @@ -252,7 +219,7 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig, "replacement for pack parameter must be a pack type"); replacementTypes.push_back(replacement); - }); + } // Form the stored conformances. SmallVector conformances; @@ -292,11 +259,7 @@ Type SubstitutionMap::lookupSubstitution(CanSubstitutableType type) const { // Find the index of the replacement type based on the generic parameter we // have. auto genericParam = cast(type); - auto mutableThis = const_cast(this); - auto replacementTypes = mutableThis->getReplacementTypesBuffer(); - auto genericSig = getGenericSignature(); - assert(genericSig); - auto genericParams = genericSig.getGenericParams(); + auto genericParams = getGenericSignature().getGenericParams(); auto replacementIndex = GenericParamKey(genericParam).findIndexIn(genericParams); @@ -305,45 +268,7 @@ Type SubstitutionMap::lookupSubstitution(CanSubstitutableType type) const { if (replacementIndex == genericParams.size()) return Type(); - // If we already have a replacement type, return it. - Type &replacementType = replacementTypes[replacementIndex]; - if (replacementType) - return replacementType; - - // The generic parameter may have been made concrete by the generic signature, - // substitute into the concrete type. - if (auto concreteType = genericSig->getConcreteType(genericParam)) { - // Set the replacement type to an error, to block infinite recursion. - replacementType = ErrorType::get(concreteType); - - // Substitute into the replacement type. - replacementType = concreteType.subst(*this); - - // If the generic signature is canonical, canonicalize the replacement type. - if (getGenericSignature()->isCanonical()) - replacementType = replacementType->getCanonicalType(); - - return replacementType; - } - - // The generic parameter may not be reduced. Retrieve the reduced - // type, which will be dependent. - CanType canonicalType = genericSig.getReducedType(genericParam); - - // If nothing changed, we don't have a replacement. - if (canonicalType == type) return Type(); - - // If we're left with a substitutable type, substitute into that. - // First, set the replacement type to an error, to block infinite recursion. - replacementType = ErrorType::get(type); - - replacementType = lookupSubstitution(cast(canonicalType)); - - // If the generic signature is canonical, canonicalize the replacement type. - if (getGenericSignature()->isCanonical()) - replacementType = replacementType->getCanonicalType(); - - return replacementType; + return getReplacementTypes()[replacementIndex]; } ProtocolConformanceRef @@ -500,12 +425,7 @@ SubstitutionMap SubstitutionMap::subst(InFlightSubstitution &IFS) const { if (empty()) return SubstitutionMap(); SmallVector newSubs; - for (Type type : getReplacementTypesBuffer()) { - if (!type) { - // Non-canonical parameter. - newSubs.push_back(Type()); - continue; - } + for (Type type : getReplacementTypes()) { newSubs.push_back(type.subst(IFS)); assert(type->is() == newSubs.back()->is() && "substitution changed the pack-ness of a replacement type"); @@ -843,7 +763,7 @@ bool SubstitutionMap::isIdentity() const { GenericSignature sig = getGenericSignature(); bool hasNonIdentityReplacement = false; - auto replacements = getReplacementTypesBuffer(); + auto replacements = getReplacementTypes(); sig->forEachParam([&](GenericTypeParamType *paramTy, bool isCanonical) { if (isCanonical) { diff --git a/lib/AST/SubstitutionMapStorage.h b/lib/AST/SubstitutionMapStorage.h index d8ff967620c..c0098bd7918 100644 --- a/lib/AST/SubstitutionMapStorage.h +++ b/lib/AST/SubstitutionMapStorage.h @@ -40,10 +40,7 @@ class SubstitutionMap::Storage final /// The number of conformance requirements, cached to avoid constantly /// recomputing it on conformance-buffer access. - const unsigned numConformanceRequirements : 31; - - /// Whether we've populated all replacement types already. - unsigned populatedAllReplacements : 1; + const unsigned numConformanceRequirements; Storage() = delete; diff --git a/test/IDE/complete_rdar129024996.swift b/test/IDE/complete_rdar129024996.swift index d3f15c9b853..33d8bb7b93e 100644 --- a/test/IDE/complete_rdar129024996.swift +++ b/test/IDE/complete_rdar129024996.swift @@ -46,4 +46,4 @@ extension P where Self == B { func bar() {} // COMPLETE: Begin completions, 2 items // COMPLETE-DAG: Decl[StaticMethod]/Super/TypeRelation[Convertible]: foo()[#S#]; name=foo() -// COMPLETE-DAG: Decl[StaticMethod]/Super/TypeRelation[Convertible]: qux()[#B#]; name=qux() +// COMPLETE-DAG: Decl[StaticMethod]/Super/Flair[ExprSpecific]/TypeRelation[Convertible]: qux()[#any Q#]; name=qux() diff --git a/test/IDE/complete_rdar94369218.swift b/test/IDE/complete_rdar94369218.swift index 6fe62f46a41..66634170d6e 100644 --- a/test/IDE/complete_rdar94369218.swift +++ b/test/IDE/complete_rdar94369218.swift @@ -34,7 +34,7 @@ func test3() { #^GENERICEXPR^# // GENERICEXPR: Decl[GenericTypeParam]/Local: MyGeneric[#MyGeneric#]; name=MyGeneric // GENERICEXPR: Decl[Constructor]/Local: MyGeneric({#value: String#})[#MyProto#]; name=MyGeneric(value:) -// GENERICEXPR: Decl[Constructor]/Local: MyGeneric({#arg: String#})[#MyStruct#]; name=MyGeneric(arg:) +// GENERICEXPR: Decl[Constructor]/Local: MyGeneric({#arg: String#})[#MyProto#]; name=MyGeneric(arg:) } } } diff --git a/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response b/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response index 255291e893f..59246b35fda 100644 --- a/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response +++ b/test/SourceKit/DocSupport/doc_system_module_underscored.swift.response @@ -1145,6 +1145,16 @@ protocol Other1 { }, { key.kind: source.lang.swift.decl.extension.struct, + key.generic_params: [ + { + key.name: "T" + } + ], + key.generic_requirements: [ + { + key.description: "T == String" + } + ], key.offset: 396, key.length: 98, key.fully_annotated_decl: "extension A",