AST: Remove AssociatedType

This commit is contained in:
Slava Pestov
2025-04-03 11:40:47 -04:00
parent cea72e35a9
commit e475b08011
15 changed files with 58 additions and 128 deletions

View File

@@ -23,51 +23,6 @@
namespace swift {
/// A type associated with a protocol.
///
/// This struct exists largely so that we can maybe eventually
/// generalize it to an arbitrary path.
class AssociatedType {
AssociatedTypeDecl *Association;
using AssociationInfo = llvm::DenseMapInfo<AssociatedTypeDecl*>;
struct SpecialValue {};
explicit AssociatedType(SpecialValue _, AssociatedTypeDecl *specialValue)
: Association(specialValue) {}
public:
explicit AssociatedType(AssociatedTypeDecl *association)
: Association(association) {
assert(association);
}
ProtocolDecl *getSourceProtocol() const {
return Association->getProtocol();
}
AssociatedTypeDecl *getAssociation() const {
return Association;
}
friend bool operator==(AssociatedType lhs, AssociatedType rhs) {
return lhs.Association == rhs.Association;
}
friend bool operator!=(AssociatedType lhs, AssociatedType rhs) {
return !(lhs == rhs);
}
unsigned getHashValue() const {
return llvm::hash_value(Association);
}
static AssociatedType getEmptyKey() {
return AssociatedType(SpecialValue(), AssociationInfo::getEmptyKey());
}
static AssociatedType getTombstoneKey() {
return AssociatedType(SpecialValue(), AssociationInfo::getTombstoneKey());
}
};
/// A base conformance of a protocol.
class BaseConformance {
ProtocolDecl *Source;
@@ -147,24 +102,6 @@ public:
} // end namespace swift
namespace llvm {
template <> struct DenseMapInfo<swift::AssociatedType> {
static inline swift::AssociatedType getEmptyKey() {
return swift::AssociatedType::getEmptyKey();
}
static inline swift::AssociatedType getTombstoneKey() {
return swift::AssociatedType::getTombstoneKey();
}
static unsigned getHashValue(swift::AssociatedType val) {
return val.getHashValue();
}
static bool isEqual(swift::AssociatedType lhs, swift::AssociatedType rhs) {
return lhs == rhs;
}
};
template <> struct DenseMapInfo<swift::AssociatedConformance> {
static inline swift::AssociatedConformance getEmptyKey() {
return swift::AssociatedConformance::getEmptyKey();

View File

@@ -100,7 +100,7 @@ public:
// If this is a new associated type (which does not override an
// existing associated type), add it.
if (associatedType->getOverriddenDecls().empty())
asDerived().addAssociatedType(AssociatedType(associatedType));
asDerived().addAssociatedType(associatedType);
}
if (asDerived().shouldVisitRequirementSignatureOnly())

View File

@@ -103,10 +103,10 @@ irgen::emitArchetypeTypeMetadataRef(IRGenFunction &IGF,
auto parent = cast<ArchetypeType>(
archetype->getGenericEnvironment()->mapTypeIntoContext(
member->getBase())->getCanonicalType());
AssociatedType association(member->getAssocType());
auto *assocType = member->getAssocType();
MetadataResponse response =
emitAssociatedTypeMetadataRef(IGF, parent, association, request);
emitAssociatedTypeMetadataRef(IGF, parent, assocType, request);
setTypeMetadataName(IGF.IGM, response.getMetadata(), archetype);
@@ -321,11 +321,11 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF,
MetadataResponse
irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
CanArchetypeType origin,
AssociatedType association,
AssociatedTypeDecl *assocType,
DynamicMetadataRequest request) {
// Find the conformance of the origin to the associated type's protocol.
llvm::Value *wtable = emitArchetypeWitnessTableRef(IGF, origin,
association.getSourceProtocol());
assocType->getProtocol());
// Find the origin's type metadata.
llvm::Value *originMetadata =
@@ -333,7 +333,7 @@ irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
.getMetadata();
return emitAssociatedTypeMetadataRef(IGF, originMetadata, wtable,
association, request);
assocType, request);
}
const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {

View File

@@ -25,7 +25,7 @@ namespace llvm {
}
namespace swift {
class AssociatedType;
class AssociatedTypeDecl;
class ProtocolDecl;
class SILType;
@@ -51,7 +51,7 @@ namespace irgen {
/// Emit a metadata reference for an associated type of an archetype.
MetadataResponse emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
CanArchetypeType origin,
AssociatedType association,
AssociatedTypeDecl *assocType,
DynamicMetadataRequest request);
/// Emit a dynamic metatype lookup for the given archetype.

View File

@@ -953,8 +953,7 @@ namespace {
auto flags = Flags(Flags::Kind::AssociatedTypeAccessFunction);
if (auto &schema = IGM.getOptions().PointerAuth
.ProtocolAssociatedTypeAccessFunctions) {
addDiscriminator(flags, schema,
AssociatedType(entry.getAssociatedType()));
addDiscriminator(flags, schema, entry.getAssociatedType());
}
// Look for a default witness.

View File

@@ -160,7 +160,7 @@ struct IRGenModule::PointerAuthCachesType {
llvm::DenseMap<SILDeclRef, llvm::ConstantInt*> Decls;
llvm::DenseMap<CanType, llvm::ConstantInt*> Types;
llvm::DenseMap<CanType, llvm::ConstantInt*> YieldTypes;
llvm::DenseMap<AssociatedType, llvm::ConstantInt*> AssociatedTypes;
llvm::DenseMap<AssociatedTypeDecl *, llvm::ConstantInt*> AssociatedTypes;
llvm::DenseMap<AssociatedConformance, llvm::ConstantInt*> AssociatedConformances;
};
@@ -336,9 +336,9 @@ static llvm::ConstantInt *getDiscriminatorForString(IRGenModule &IGM,
return getDiscriminatorForHash(IGM, rawHash);
}
static std::string mangle(AssociatedType association) {
return IRGenMangler(association.getAssociation()->getASTContext())
.mangleAssociatedTypeAccessFunctionDiscriminator(association);
static std::string mangle(AssociatedTypeDecl *assocType) {
return IRGenMangler(assocType->getASTContext())
.mangleAssociatedTypeAccessFunctionDiscriminator(assocType);
}
static std::string mangle(const AssociatedConformance &association) {
@@ -430,7 +430,7 @@ PointerAuthEntity::getDeclDiscriminator(IRGenModule &IGM) const {
}
case Kind::AssociatedType: {
auto association = Storage.get<AssociatedType>(StoredKind);
auto association = Storage.get<AssociatedTypeDecl *>(StoredKind);
llvm::ConstantInt *&cache =
IGM.getPointerAuthCaches().AssociatedTypes[association];
if (cache) return cache;

View File

@@ -86,7 +86,7 @@ private:
using Members = ExternalUnionMembers<void,
Special,
ValueWitness,
AssociatedType,
AssociatedTypeDecl *,
AssociatedConformance,
CanSILFunctionType,
SILDeclRef,
@@ -105,7 +105,7 @@ private:
case Kind::SILDeclRef:
return Members::indexOf<SILDeclRef>();
case Kind::AssociatedType:
return Members::indexOf<AssociatedType>();
return Members::indexOf<AssociatedTypeDecl *>();
case Kind::AssociatedConformance:
return Members::indexOf<AssociatedConformance>();
case Kind::SILFunction:
@@ -139,9 +139,9 @@ public:
assert(isValueWitnessFunction(witness));
Storage.emplace<ValueWitness>(StoredKind, witness);
}
PointerAuthEntity(AssociatedType association)
PointerAuthEntity(AssociatedTypeDecl *assocType)
: StoredKind(Kind::AssociatedType) {
Storage.emplaceAggregate<AssociatedType>(StoredKind, association);
Storage.emplaceAggregate<AssociatedTypeDecl *>(StoredKind, assocType);
}
PointerAuthEntity(const AssociatedConformance &association)
: StoredKind(Kind::AssociatedConformance) {

View File

@@ -946,11 +946,11 @@ namespace {
}
}
void addAssociatedType(AssociatedType requirement) {
void addAssociatedType(AssociatedTypeDecl *assocType) {
// In Embedded Swift witness tables don't have associated-types entries.
if (requirement.getAssociation()->getASTContext().LangOpts.hasFeature(Feature::Embedded))
if (assocType->getASTContext().LangOpts.hasFeature(Feature::Embedded))
return;
Entries.push_back(WitnessTableEntry::forAssociatedType(requirement));
Entries.push_back(WitnessTableEntry::forAssociatedType(assocType));
}
void addAssociatedConformance(const AssociatedConformance &req) {
@@ -1330,8 +1330,8 @@ mapConformanceIntoContext(const RootProtocolConformance *conf) {
WitnessIndex ProtocolInfo::getAssociatedTypeIndex(
IRGenModule &IGM,
AssociatedType assocType) const {
assert(!IGM.isResilient(assocType.getSourceProtocol(),
AssociatedTypeDecl *assocType) const {
assert(!IGM.isResilient(assocType->getProtocol(),
ResilienceExpansion::Maximal) &&
"Cannot ask for the associated type index of non-resilient protocol");
for (auto &witness : getWitnessEntries()) {
@@ -1707,7 +1707,7 @@ public:
llvm_unreachable("cannot emit a witness table with placeholders in it");
}
void addAssociatedType(AssociatedType requirement) {
void addAssociatedType(AssociatedTypeDecl *assocType) {
auto &entry = SILEntries.front();
SILEntries = SILEntries.slice(1);
@@ -1718,10 +1718,9 @@ public:
#ifndef NDEBUG
assert(entry.getKind() == SILWitnessTable::AssociatedType
&& "sil witness table does not match protocol");
assert(entry.getAssociatedTypeWitness().Requirement
== requirement.getAssociation()
assert(entry.getAssociatedTypeWitness().Requirement == assocType
&& "sil witness table does not match protocol");
auto piIndex = PI.getAssociatedTypeIndex(IGM, requirement);
auto piIndex = PI.getAssociatedTypeIndex(IGM, assocType);
assert((size_t)piIndex.getValue() ==
Table.size() - WitnessTableFirstRequirementOffset &&
"offset doesn't match ProtocolInfo layout");
@@ -1729,23 +1728,22 @@ public:
(void)entry;
#endif
auto associate =
Conformance.getTypeWitness(requirement.getAssociation());
llvm::Constant *witness =
auto typeWitness = Conformance.getTypeWitness(assocType);
llvm::Constant *typeWitnessAddr =
IGM.getAssociatedTypeWitness(
associate,
typeWitness,
Conformance.getDeclContext()->getGenericSignatureOfContext(),
/*inProtocolContext=*/false);
witness = llvm::ConstantExpr::getBitCast(witness, IGM.Int8PtrTy);
typeWitnessAddr = llvm::ConstantExpr::getBitCast(typeWitnessAddr, IGM.Int8PtrTy);
if (isRelative) {
Table.addRelativeAddress(witness);
Table.addRelativeAddress(typeWitnessAddr);
return;
}
auto &schema = IGM.getOptions().PointerAuth
.ProtocolAssociatedTypeAccessFunctions;
Table.addSignedPointer(witness, schema, requirement);
Table.addSignedPointer(typeWitnessAddr, schema, assocType);
}
void addAssociatedConformance(AssociatedConformance requirement) {
@@ -3513,7 +3511,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
SubstitutionMap::getProtocolSubstitutions(sourceConformance))
->getCanonicalType();
if (auto archetypeType = dyn_cast<ArchetypeType>(baseSubstType)) {
AssociatedType baseAssocType(depMemType->getAssocType());
auto *baseAssocType = depMemType->getAssocType();
MetadataResponse response =
emitAssociatedTypeMetadataRef(IGF, archetypeType, baseAssocType,
@@ -4538,18 +4536,18 @@ MetadataResponse
irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
llvm::Value *parentMetadata,
llvm::Value *wtable,
AssociatedType associatedType,
AssociatedTypeDecl *assocType,
DynamicMetadataRequest request) {
auto &IGM = IGF.IGM;
// Extract the requirements base descriptor.
auto reqBaseDescriptor =
IGM.getAddrOfProtocolRequirementsBaseDescriptor(
associatedType.getSourceProtocol());
assocType->getProtocol());
// Extract the associated type descriptor.
auto assocTypeDescriptor =
IGM.getAddrOfAssociatedTypeDescriptor(associatedType.getAssociation());
IGM.getAddrOfAssociatedTypeDescriptor(assocType);
// Call swift_getAssociatedTypeWitness().
auto call =
IGF.IGM.IRGen.Opts.UseRelativeProtocolWitnessTables ?

View File

@@ -29,7 +29,7 @@ namespace llvm {
namespace swift {
class AssociatedConformance;
class AssociatedType;
class AssociatedTypeDecl;
class CanType;
class FuncDecl;
enum class MetadataState : size_t;
@@ -90,11 +90,11 @@ namespace irgen {
///
/// \param parentMetadata - the type metadata for T
/// \param wtable - the witness table witnessing the conformance of T to P
/// \param associatedType - the declaration of X; a member of P
/// \param assocType - the declaration of X; a member of P
MetadataResponse emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
llvm::Value *parentMetadata,
llvm::Value *wtable,
AssociatedType associatedType,
AssociatedTypeDecl *assocType,
DynamicMetadataRequest request);
// Return the offset one should do on a witness table pointer to retrieve the

View File

@@ -435,10 +435,10 @@ public:
}
std::string
mangleAssociatedTypeAccessFunctionDiscriminator(AssociatedType association) {
mangleAssociatedTypeAccessFunctionDiscriminator(AssociatedTypeDecl *assocDecl) {
beginMangling();
appendAnyGenericType(association.getSourceProtocol());
appendIdentifier(association.getAssociation()->getNameStr());
appendAnyGenericType(assocDecl->getProtocol());
appendIdentifier(assocDecl->getNameStr());
return finalize();
}

View File

@@ -187,9 +187,8 @@ static void checkPointerAuthAssociatedTypeDiscriminator(IRGenModule &IGM, ArrayR
auto &schema = IGM.getOptions().PointerAuth.ProtocolAssociatedTypeAccessFunctions;
if (!schema.isEnabled()) return;
auto decl = dyn_cast_or_null<AssociatedTypeDecl>(lookupSimple(IGM.getSwiftModule(), declPath));
assert(decl && "decl not found");
auto discriminator = PointerAuthInfo::getOtherDiscriminator(IGM, schema, AssociatedType(decl));
auto decl = cast<AssociatedTypeDecl>(lookupSimple(IGM.getSwiftModule(), declPath));
auto discriminator = PointerAuthInfo::getOtherDiscriminator(IGM, schema, decl);
assert(discriminator->getZExtValue() == expected && "discriminator value doesn't match");
}

View File

@@ -92,7 +92,6 @@ namespace clang {
namespace swift {
class GenericSignature;
class AssociatedConformance;
class AssociatedType;
class ASTContext;
class BaseConformance;
class BraceStmt;

View File

@@ -124,9 +124,9 @@ public:
return MethodEntry.Witness;
}
static WitnessTableEntry forAssociatedType(AssociatedType ty) {
static WitnessTableEntry forAssociatedType(AssociatedTypeDecl *assocType) {
WitnessTableEntry entry(WitnessKind::AssociatedTypeKind);
entry.AssociatedTypeEntry = {ty.getAssociation()};
entry.AssociatedTypeEntry = {assocType};
return entry;
}
@@ -134,9 +134,8 @@ public:
return Kind == WitnessKind::AssociatedTypeKind;
}
bool matchesAssociatedType(AssociatedType assocType) const {
return isAssociatedType() &&
AssociatedTypeEntry.Association == assocType.getAssociation();
bool matchesAssociatedType(AssociatedTypeDecl *assocType) const {
return isAssociatedType() && AssociatedTypeEntry.Association == assocType;
}
AssociatedTypeDecl *getAssociatedType() const {
@@ -293,7 +292,7 @@ public:
/// Return the witness index for the type metadata access function
/// for the given associated type.
WitnessIndex getAssociatedTypeIndex(IRGenModule &IGM,
AssociatedType assocType) const;
AssociatedTypeDecl *assocType) const;
/// Return the witness index for the protocol witness table access
/// function for the given associated protocol conformance.

View File

@@ -852,8 +852,8 @@ public:
}
}
void addAssociatedType(AssociatedType associatedType) {
Visitor.addAssociatedTypeDescriptor(associatedType.getAssociation());
void addAssociatedType(AssociatedTypeDecl *assocType) {
Visitor.addAssociatedTypeDescriptor(assocType);
}
void addProtocolConformanceDescriptor() {

View File

@@ -678,13 +678,12 @@ public:
SILWitnessTable::MethodWitness{requirementRef, witnessFn});
}
void addAssociatedType(AssociatedType requirement) {
void addAssociatedType(AssociatedTypeDecl *assocType) {
// Find the substitution info for the witness type.
auto td = requirement.getAssociation();
Type witness = Conformance->getTypeWitness(td);
Type witness = Conformance->getTypeWitness(assocType);
// Emit the record for the type itself.
Entries.push_back(SILWitnessTable::AssociatedTypeWitness{td,
Entries.push_back(SILWitnessTable::AssociatedTypeWitness{assocType,
witness->getCanonicalType()});
}
@@ -1028,7 +1027,7 @@ public:
void addAssociatedConformance(AssociatedConformance conformance) {
llvm_unreachable("associated conformances not supported in self-conformance");
}
void addAssociatedType(AssociatedType type) {
void addAssociatedType(AssociatedTypeDecl *assocType) {
llvm_unreachable("associated types not supported in self-conformance");
}
void addPlaceholder(MissingMemberDecl *placeholder) {
@@ -1106,14 +1105,14 @@ public:
DefaultWitnesses.push_back(entry);
}
void addAssociatedType(AssociatedType req) {
Type witness = Proto->getDefaultTypeWitness(req.getAssociation());
void addAssociatedType(AssociatedTypeDecl *assocType) {
Type witness = Proto->getDefaultTypeWitness(assocType);
if (!witness)
return addMissingDefault();
Type witnessInContext = Proto->mapTypeIntoContext(witness);
auto entry = SILWitnessTable::AssociatedTypeWitness{
req.getAssociation(),
assocType,
witnessInContext->getCanonicalType()};
DefaultWitnesses.push_back(entry);
}