diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h index 381442c632066..4d347fae5b9d8 100644 --- a/include/swift/AST/GenericSignature.h +++ b/include/swift/AST/GenericSignature.h @@ -152,7 +152,7 @@ class GenericSignature { TypeArrayView genericParams, ArrayRef requirements); public: - using ConformsToArray = SmallVector; + using RequiredProtocols = SmallVector; private: // Direct comparison is disabled for generic signatures. Canonicalize them @@ -318,12 +318,13 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final /// Determine the superclass bound on the given dependent type. Type getSuperclassBound(Type type) const; - /// Determine the set of protocols to which the given dependent type - /// must conform. - GenericSignature::ConformsToArray getConformsTo(Type type) const; + /// Determine the set of protocols to which the given type parameter is + /// required to conform. + GenericSignature::RequiredProtocols getRequiredProtocols(Type type) const; - /// Determine whether the given dependent type conforms to this protocol. - bool conformsToProtocol(Type type, ProtocolDecl *proto) const; + /// Determine whether the given type parameter is required to conform to + /// the given protocol. + bool requiresProtocol(Type type, ProtocolDecl *proto) const; /// Determine whether the given dependent type is equal to a concrete type. bool isConcreteType(Type type) const; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0ce969d817d97..9bfeef7665326 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3723,11 +3723,8 @@ OpaqueTypeArchetypeType::get(OpaqueTypeDecl *Decl, superclass = superclass.subst(Substitutions); } #endif - SmallVector protos; - for (auto proto : signature->getConformsTo(opaqueInterfaceTy)) { - protos.push_back(proto); - } - + const auto protos = signature->getRequiredProtocols(opaqueInterfaceTy); + auto mem = ctx.Allocate( OpaqueTypeArchetypeType::totalSizeToAlloc( protos.size(), superclass ? 1 : 0, layout ? 1 : 0), diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 43ed5bc878eec..0ae8ccfa7b2f1 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -2539,8 +2539,9 @@ void ASTMangler::appendGenericSignatureParts( DependentMemberType * ASTMangler::dropProtocolFromAssociatedType(DependentMemberType *dmt) { auto baseTy = dmt->getBase(); - bool unambiguous = (!dmt->getAssocType() || - CurGenericSignature->getConformsTo(baseTy).size() <= 1); + bool unambiguous = + (!dmt->getAssocType() || + CurGenericSignature->getRequiredProtocols(baseTy).size() <= 1); if (auto *baseDMT = baseTy->getAs()) baseTy = dropProtocolFromAssociatedType(baseDMT); @@ -2573,8 +2574,8 @@ void ASTMangler::appendAssociatedTypeName(DependentMemberType *dmt) { // If the base type is known to have a single protocol conformance // in the current generic context, then we don't need to disambiguate the // associated type name by protocol. - if (!OptimizeProtocolNames || !CurGenericSignature - || CurGenericSignature->getConformsTo(dmt->getBase()).size() > 1) { + if (!OptimizeProtocolNames || !CurGenericSignature || + CurGenericSignature->getRequiredProtocols(dmt->getBase()).size() > 1) { appendAnyGenericType(assocTy->getProtocol()); } return; diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp index 05b04cc03bb1a..ade97c2355846 100644 --- a/lib/AST/GenericSignature.cpp +++ b/lib/AST/GenericSignature.cpp @@ -424,10 +424,10 @@ Type GenericSignatureImpl::getSuperclassBound(Type type) const { return equivClass->superclass; } -/// Determine the set of protocols to which the given dependent type -/// must conform. -SmallVector -GenericSignatureImpl::getConformsTo(Type type) const { +/// Determine the set of protocols to which the given type parameter is +/// required to conform. +GenericSignature::RequiredProtocols +GenericSignatureImpl::getRequiredProtocols(Type type) const { if (!type->isTypeParameter()) return { }; auto &builder = *getGenericSignatureBuilder(); @@ -437,12 +437,12 @@ GenericSignatureImpl::getConformsTo(Type type) const { ArchetypeResolutionKind::CompleteWellFormed); if (!equivClass) return { }; - // If this type was mapped to a concrete type, then there are no - // requirements. + // If this type parameter was mapped to a concrete type, then there + // are no requirements. if (equivClass->concreteType) return { }; // Retrieve the protocols to which this type conforms. - SmallVector result; + GenericSignature::RequiredProtocols result; for (const auto &conforms : equivClass->conformsTo) result.push_back(conforms.first); @@ -452,8 +452,8 @@ GenericSignatureImpl::getConformsTo(Type type) const { return result; } -bool GenericSignatureImpl::conformsToProtocol(Type type, - ProtocolDecl *proto) const { +bool GenericSignatureImpl::requiresProtocol(Type type, + ProtocolDecl *proto) const { assert(type->isTypeParameter() && "Expected a type parameter"); auto &builder = *getGenericSignatureBuilder(); @@ -463,7 +463,11 @@ bool GenericSignatureImpl::conformsToProtocol(Type type, ArchetypeResolutionKind::CompleteWellFormed); if (!equivClass) return false; - // FIXME: Deal with concrete conformances here? + // FIXME: Optionally deal with concrete conformances here + // or have a separate method do that additionally? + // + // If this type parameter was mapped to a concrete type, then there + // are no requirements. if (equivClass->concreteType) return false; // Check whether the representative conforms to this protocol. @@ -541,7 +545,7 @@ bool GenericSignatureImpl::isRequirementSatisfied( auto protocol = protocolType->getDecl(); if (canFirstType->isTypeParameter()) - return conformsToProtocol(canFirstType, protocol); + return requiresProtocol(canFirstType, protocol); else return (bool)GSB->lookupConformance(/*dependentType=*/CanType(), canFirstType, protocol); diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp index 026111141f832..61d4695a4d9db 100644 --- a/lib/AST/SubstitutionMap.cpp +++ b/lib/AST/SubstitutionMap.cpp @@ -368,7 +368,7 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const { // If the type doesn't conform to this protocol, the result isn't formed // from these requirements. - if (!genericSig->conformsToProtocol(type, proto)) + if (!genericSig->requiresProtocol(type, proto)) return ProtocolConformanceRef::forInvalid(); auto accessPath = diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 08238b491c2a5..45636b322204a 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -2416,7 +2416,7 @@ bool ClangImporter::Implementation::matchesHashableBound(Type type) { if (auto *generic = genericTy->getDecl()) { auto genericSig = generic->getDeclContext()->getGenericSignatureOfContext(); - if (genericSig && genericSig->getConformsTo(type).empty()) { + if (genericSig && genericSig->getRequiredProtocols(type).empty()) { type = genericSig->getSuperclassBound(type); if (!type) return false; diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index 7d1fb2281c880..6d7e0434eb437 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -2344,7 +2344,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } if (t->isTypeParameter()) { - auto protos = genericSig->getConformsTo(t); + const auto protos = genericSig->getRequiredProtocols(t); if (!protos.empty()) return buildProtocolComposition(protos); } @@ -4729,7 +4729,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer { bool hasExplicitAnyObject = false; if (auto superTy = genericSig->getSuperclassBound(ResultT)) opaqueTypes.push_back(superTy); - for (auto proto : genericSig->getConformsTo(ResultT)) + for (const auto proto : genericSig->getRequiredProtocols(ResultT)) opaqueTypes.push_back(proto->getDeclaredInterfaceType()); if (auto layout = genericSig->getLayoutConstraint(ResultT)) hasExplicitAnyObject = layout->isClass(); diff --git a/lib/IRGen/Fulfillment.h b/lib/IRGen/Fulfillment.h index 6ea5e56d3153d..c43b3b3f39ce2 100644 --- a/lib/IRGen/Fulfillment.h +++ b/lib/IRGen/Fulfillment.h @@ -68,7 +68,7 @@ class FulfillmentMap { virtual bool hasLimitedInterestingConformances(CanType type) const = 0; /// Return the limited interesting conformances for an interesting type. - virtual GenericSignature::ConformsToArray + virtual GenericSignature::RequiredProtocols getInterestingConformances(CanType type) const = 0; /// Return the limited interesting conformances for an interesting type. diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 27a1fbf837a4f..2cb7ba801893d 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -101,8 +101,8 @@ class PolymorphicConvention { FulfillmentMap Fulfillments; - GenericSignature::ConformsToArray getConformsTo(Type t) { - return Generics->getConformsTo(t); + GenericSignature::RequiredProtocols getRequiredProtocols(Type t) { + return Generics->getRequiredProtocols(t); } CanType getSuperclassBound(Type t) { @@ -166,9 +166,9 @@ class PolymorphicConvention { bool hasLimitedInterestingConformances(CanType type) const override { return true; } - GenericSignature::ConformsToArray + GenericSignature::RequiredProtocols getInterestingConformances(CanType type) const override { - return Self.getConformsTo(type); + return Self.getRequiredProtocols(type); } CanType getSuperclassBound(CanType type) const override { return Self.getSuperclassBound(type); @@ -1203,7 +1203,7 @@ class AccessorConformanceInfo : public ConformanceInfo { bool hasLimitedInterestingConformances(CanType type) const override { return false; } - GenericSignature::ConformsToArray + GenericSignature::RequiredProtocols getInterestingConformances(CanType type) const override { llvm_unreachable("no limits"); } diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp index 28d0b71fc7e70..9270cb335ac77 100644 --- a/lib/IRGen/LocalTypeData.cpp +++ b/lib/IRGen/LocalTypeData.cpp @@ -497,7 +497,7 @@ void LocalTypeDataCache::addAbstractForTypeMetadata(IRGenFunction &IGF, bool hasLimitedInterestingConformances(CanType type) const override { return false; } - GenericSignature::ConformsToArray + GenericSignature::RequiredProtocols getInterestingConformances(CanType type) const override { llvm_unreachable("no limits"); } diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 8d89f64ac4b98..5ab92e9dbd286 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -741,7 +741,7 @@ bool irgen::isNominalGenericContextTypeMetadataAccessTrivial( auto allWitnessTablesAreReferenceable = llvm::all_of(environment->getGenericParams(), [&](auto parameter) { auto signature = environment->getGenericSignature(); - auto protocols = signature->getConformsTo(parameter); + const auto protocols = signature->getRequiredProtocols(parameter); auto argument = ((Type *)parameter)->subst(substitutions); auto canonicalType = argument->getCanonicalType(); auto witnessTablesAreReferenceable = [&]() { diff --git a/lib/PrintAsObjC/ModuleContentsWriter.cpp b/lib/PrintAsObjC/ModuleContentsWriter.cpp index d850955c51e4b..a9b36541f31b2 100644 --- a/lib/PrintAsObjC/ModuleContentsWriter.cpp +++ b/lib/PrintAsObjC/ModuleContentsWriter.cpp @@ -71,8 +71,7 @@ class ReferencedTypeFinder : public TypeDeclFinder { if (sig->getSuperclassBound(paramTy)) return true; - auto conformsTo = sig->getConformsTo(paramTy); - return !conformsTo.empty(); + return !sig->getRequiredProtocols(paramTy).empty(); } Action visitBoundGenericType(BoundGenericType *boundGeneric) override { diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index a29afb42d6fae..7c666a3bd0886 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -2923,9 +2923,8 @@ class SILVerifier : public SILVerifierBase { require(selfRequirement && selfRequirement->getKind() == RequirementKind::Conformance, "first non-same-typerequirement should be conformance requirement"); - auto conformsTo = genericSig->getConformsTo(selfGenericParam); - require(std::find(conformsTo.begin(), conformsTo.end(), protocol) - != conformsTo.end(), + const auto protos = genericSig->getRequiredProtocols(selfGenericParam); + require(std::find(protos.begin(), protos.end(), protocol) != protos.end(), "requirement Self parameter must conform to called protocol"); auto lookupType = AMI->getLookupType(); diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index ff85cd7cc4c1b..ccac659fb96f5 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -2750,7 +2750,7 @@ TypeEraserHasViableInitRequest::evaluate(Evaluator &evaluator, ParamDecl *param = *init->getParameters()->begin(); if (param->getArgumentName() != ctx.Id_erasing || !param->getInterfaceType()->isEqual(genericParamType) || - !genericSignature->conformsToProtocol(genericParamType, protocol)) + !genericSignature->requiresProtocol(genericParamType, protocol)) return false; // Allow other constraints as long as the init can be called with any diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index d0c04836216d9..de7e4f2b31ae6 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -3707,7 +3707,7 @@ CheckTypeWitnessResult swift::checkTypeWitness(DeclContext *dc, auto *module = dc->getParentModule(); // Check protocol conformances. - for (auto reqProto : genericSig->getConformsTo(depTy)) { + for (const auto reqProto : genericSig->getRequiredProtocols(depTy)) { if (module->lookupConformance(contextType, reqProto) .isInvalid()) return CheckTypeWitnessResult(reqProto->getDeclaredType()); diff --git a/tools/swift-ast-script/ASTScriptEvaluator.cpp b/tools/swift-ast-script/ASTScriptEvaluator.cpp index 2324fe8d89e2b..a283da486ed61 100644 --- a/tools/swift-ast-script/ASTScriptEvaluator.cpp +++ b/tools/swift-ast-script/ASTScriptEvaluator.cpp @@ -60,7 +60,7 @@ class ASTScriptWalker : public ASTWalker { auto paramResultType = paramFnType->getResult(); if (!paramResultType->isTypeParameter()) continue; auto sig = fn->getGenericSignature(); - if (!sig->conformsToProtocol(paramResultType, ViewProtocol)) continue; + if (!sig->requiresProtocol(paramResultType, ViewProtocol)) continue; // The parameter must not be a @ViewBuilder parameter. if (param->getFunctionBuilderType()) continue;