Skip to content

[NFC] GenericSignatureImpl: Spell conformsToProtocol & getConformsTo in terms of requirements #31734

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions include/swift/AST/GenericSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class GenericSignature {
TypeArrayView<GenericTypeParamType> genericParams,
ArrayRef<Requirement> requirements);
public:
using ConformsToArray = SmallVector<ProtocolDecl *, 2>;
using RequiredProtocols = SmallVector<ProtocolDecl *, 2>;

private:
// Direct comparison is disabled for generic signatures. Canonicalize them
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 2 additions & 5 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3723,11 +3723,8 @@ OpaqueTypeArchetypeType::get(OpaqueTypeDecl *Decl,
superclass = superclass.subst(Substitutions);
}
#endif
SmallVector<ProtocolDecl*, 4> protos;
for (auto proto : signature->getConformsTo(opaqueInterfaceTy)) {
protos.push_back(proto);
}

const auto protos = signature->getRequiredProtocols(opaqueInterfaceTy);

auto mem = ctx.Allocate(
OpaqueTypeArchetypeType::totalSizeToAlloc<ProtocolDecl *, Type, LayoutConstraint>(
protos.size(), superclass ? 1 : 0, layout ? 1 : 0),
Expand Down
9 changes: 5 additions & 4 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<DependentMemberType>())
baseTy = dropProtocolFromAssociatedType(baseDMT);
Expand Down Expand Up @@ -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;
Expand Down
26 changes: 15 additions & 11 deletions lib/AST/GenericSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProtocolDecl *, 2>
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();
Expand All @@ -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<ProtocolDecl *, 2> result;
GenericSignature::RequiredProtocols result;
for (const auto &conforms : equivClass->conformsTo)
result.push_back(conforms.first);

Expand All @@ -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();
Expand All @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/SubstitutionMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
2 changes: 1 addition & 1 deletion lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/Fulfillment.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 5 additions & 5 deletions lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
}
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/LocalTypeData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/MetadataRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [&]() {
Expand Down
3 changes: 1 addition & 2 deletions lib/PrintAsObjC/ModuleContentsWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 2 additions & 3 deletions lib/SIL/Verifier/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2923,9 +2923,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
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();
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion tools/swift-ast-script/ASTScriptEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down