Skip to content

AST: Simplify ProtocolConformanceRef operations a little bit #80482

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 16 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
8b1514c
AST: Remove origType parameter from ProtocolConformanceRef::getAssoci…
slavapestov Apr 1, 2025
1828c7e
AST: Build the right kind of ErrorType inside subst() instead of getT…
slavapestov Apr 1, 2025
9150371
AST: Remove origType parameter from ProtocolConformanceRef::getTypeWi…
slavapestov Apr 1, 2025
00766f7
AST: Remove type parameter from ProtocolConformanceRef::getTypeWitnes…
slavapestov Apr 1, 2025
26543d1
AST: Preserve sugar in getIdentitySubstitutionMap()
slavapestov Apr 2, 2025
7399eeb
AST: Remove type parameter from ProtocolConformanceRef::getWitnessByN…
slavapestov Apr 1, 2025
a209ff8
AST: Remove origType parameter from ProtocolConformanceRef::subst()
slavapestov Apr 1, 2025
0616333
AST: Remove origType parameter from ProtocolConformanceRef::getAssoci…
slavapestov Apr 1, 2025
ec0dfc8
AST: Add new form of SubstitutionMap::getProtocolSubstitutions()
slavapestov Apr 2, 2025
ea05708
AST: Eliminate GenericEnvironment::mapConformanceRefIntoContext()
slavapestov Apr 1, 2025
a06a421
AST: Remove origType parameter from substOpaqueTypesWithUnderlyingTyp…
slavapestov Apr 2, 2025
ba6ff41
AST: Remove getAssociatedType() call from PackConformance
slavapestov Apr 3, 2025
f455898
IRGen: Remove calls to ProtocolConformanceRef::getAssociatedType()
slavapestov Apr 3, 2025
44b73b9
SILGen: Remove a usage of ProtocolConformanceRef::getAssociatedType()
slavapestov Apr 3, 2025
cea72e3
AST: Remove ProtocolConformanceRef::getAssociatedType()
slavapestov Apr 3, 2025
e475b08
AST: Remove AssociatedType
slavapestov Apr 3, 2025
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: 0 additions & 13 deletions include/swift/AST/GenericEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,19 +325,6 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
/// abstraction level of their associated type requirements.
SILType mapTypeIntoContext(SILModule &M, SILType type) const;

/// Map an interface type's protocol conformance into the corresponding
/// conformance for the contextual type.
static std::pair<Type, ProtocolConformanceRef>
mapConformanceRefIntoContext(GenericEnvironment *genericEnv,
Type conformingType,
ProtocolConformanceRef conformance);

/// Map an interface type's protocol conformance into the corresponding
/// conformance for the contextual type.
std::pair<Type, ProtocolConformanceRef>
mapConformanceRefIntoContext(Type conformingType,
ProtocolConformanceRef conformance) const;

/// Returns a substitution map that sends every generic parameter to its
/// corresponding archetype in this generic environment.
SubstitutionMap getForwardingSubstitutionMap() const;
Expand Down
63 changes: 0 additions & 63 deletions include/swift/AST/ProtocolAssociations.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -147,24 +102,6 @@ class AssociatedConformance {
} // 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();
Expand Down
4 changes: 0 additions & 4 deletions include/swift/AST/ProtocolConformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,6 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
/// Retrieve the protocol conformance for the inherited protocol.
ProtocolConformance *getInheritedConformance(ProtocolDecl *protocol) const;

/// Given a dependent type expressed in terms of the self parameter,
/// map it into the context of this conformance.
Type getAssociatedType(Type assocType) const;

/// Given that the requirement signature of the protocol directly states
/// that the given dependent type must conform to the given protocol,
/// return its associated conformance.
Expand Down
18 changes: 8 additions & 10 deletions include/swift/AST/ProtocolConformanceRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,38 +185,36 @@ class ProtocolConformanceRef {
ProtocolDecl *getProtocol() const;

/// Apply a substitution to the conforming type.
ProtocolConformanceRef subst(Type origType, SubstitutionMap subMap,
ProtocolConformanceRef subst(SubstitutionMap subMap,
SubstOptions options = std::nullopt) const;

/// Apply a substitution to the conforming type.
ProtocolConformanceRef subst(Type origType, TypeSubstitutionFn subs,
ProtocolConformanceRef subst(TypeSubstitutionFn subs,
LookupConformanceFn conformances,
SubstOptions options = std::nullopt) const;

/// Apply a substitution to the conforming type.
///
/// This function should generally not be used outside of the substitution
/// subsystem.
ProtocolConformanceRef subst(Type origType,
InFlightSubstitution &IFS) const;
ProtocolConformanceRef subst(InFlightSubstitution &IFS) const;

/// Map contextual types to interface types in the conformance.
ProtocolConformanceRef mapConformanceOutOfContext() const;

/// Look up the type witness for an associated type declaration in this
/// conformance.
Type getTypeWitness(Type origType, AssociatedTypeDecl *assocType,
Type getTypeWitness(AssociatedTypeDecl *assocType,
SubstOptions options = std::nullopt) const;

/// Given a dependent type (expressed in terms of this conformance's
/// protocol), follow it from the conforming type.
Type getAssociatedType(Type origType, Type dependentType) const;
Type getAssociatedType(Type dependentType) const;

/// Given a dependent type (expressed in terms of this conformance's
/// protocol) and conformance, follow it from the conforming type.
ProtocolConformanceRef
getAssociatedConformance(Type origType, Type dependentType,
ProtocolDecl *requirement) const;
getAssociatedConformance(Type dependentType, ProtocolDecl *requirement) const;

SWIFT_DEBUG_DUMP;
void dump(llvm::raw_ostream &out, unsigned indent = 0,
Expand All @@ -235,15 +233,15 @@ class ProtocolConformanceRef {
return llvm::hash_value(conformance.Union.getOpaqueValue());
}

Type getTypeWitnessByName(Type type, Identifier name) const;
Type getTypeWitnessByName(Identifier name) const;

/// Find a particular named function witness for a type that conforms to
/// the given protocol.
///
/// \param type The conforming type.
///
/// \param name The name of the requirement.
ConcreteDeclRef getWitnessByName(Type type, DeclName name) const;
ConcreteDeclRef getWitnessByName(DeclName name) const;

/// Determine whether this conformance is canonical.
bool isCanonical() const;
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/SubstitutionMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ class SubstitutionMap {
SubstitutionMap mapIntoTypeExpansionContext(
TypeExpansionContext context) const;

/// Create a substitution map for a protocol conformance.
static SubstitutionMap
getProtocolSubstitutions(ProtocolConformanceRef conformance);

/// Create a substitution map for a protocol conformance.
static SubstitutionMap
getProtocolSubstitutions(ProtocolDecl *protocol,
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -5026,7 +5026,7 @@ class SILFunctionConventions;
CanType substOpaqueTypesWithUnderlyingTypes(CanType type,
TypeExpansionContext context);
ProtocolConformanceRef
substOpaqueTypesWithUnderlyingTypes(ProtocolConformanceRef ref, Type origType,
substOpaqueTypesWithUnderlyingTypes(ProtocolConformanceRef ref,
TypeExpansionContext context);
namespace Lowering {
class TypeConverter;
Expand Down
4 changes: 2 additions & 2 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
if (Functor.hasLocalArchetypes())
options |= SubstFlags::SubstituteLocalArchetypes;

C = C.subst(Ty, Functor, Functor, options);
C = C.subst(Functor, Functor, options);
if (asImpl().shouldSubstOpaqueArchetypes())
Ty = Ty.subst(Functor, Functor, options);
}
Expand All @@ -576,7 +576,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
!context.shouldLookThroughOpaqueTypeArchetypes())
return C;

return substOpaqueTypesWithUnderlyingTypes(C, Ty, context);
return substOpaqueTypesWithUnderlyingTypes(C, context);
}

return C;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/SIL/SILWitnessVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
// 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())
Expand Down
4 changes: 2 additions & 2 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1678,7 +1678,7 @@ ASTContext::getBuiltinInitDecl(NominalTypeDecl *decl,
}

auto *ctx = const_cast<ASTContext *>(this);
witness = builtinConformance.getWitnessByName(type, initName(*ctx));
witness = builtinConformance.getWitnessByName(initName(*ctx));
if (!witness) {
assert(false && "Missing required witness");
witness = ConcreteDeclRef();
Expand Down Expand Up @@ -6486,7 +6486,7 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type,
*bridgedValueType = type;

// Find the Objective-C class type we bridge to.
Type witnessTy = conformance.getTypeWitnessByName(type, Id_ObjectiveCType);
Type witnessTy = conformance.getTypeWitnessByName(Id_ObjectiveCType);
// If Objective-C import is broken, witness type would be a dependent member
// with `<<error type>>` base.
return (witnessTy && !witnessTy->hasError()) ? witnessTy : Type();
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ActorIsolation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ ActorIsolation::forActorInstanceParameter(Expr *actor,
if (auto globalActor = ctx.getProtocol(KnownProtocolKind::GlobalActor)) {
auto conformance = checkConformance(baseType, globalActor);
if (conformance &&
conformance.getWitnessByName(baseType, ctx.Id_shared) == declRef) {
conformance.getWitnessByName(ctx.Id_shared) == declRef) {
return ActorIsolation::forGlobalActor(baseType);
}
}
Expand Down
12 changes: 5 additions & 7 deletions lib/AST/DistributedDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ Type swift::getDistributedActorSystemType(NominalTypeDecl *actor) {
// Dig out the actor system type.
Type selfType = actor->getSelfInterfaceType();
auto conformance = lookupConformance(selfType, DA);
return conformance.getTypeWitnessByName(selfType, C.Id_ActorSystem);
return conformance.getTypeWitnessByName(C.Id_ActorSystem);
}

Type swift::getDistributedActorIDType(NominalTypeDecl *actor) {
Expand All @@ -220,7 +220,7 @@ static Type getTypeWitnessByName(NominalTypeDecl *type, ProtocolDecl *protocol,
auto conformance = lookupConformance(selfType, protocol);
if (!conformance || conformance.isInvalid())
return Type();
return conformance.getTypeWitnessByName(selfType, member);
return conformance.getTypeWitnessByName(member);
}

Type swift::getDistributedActorSerializationType(
Expand Down Expand Up @@ -301,8 +301,7 @@ Type swift::getDistributedSerializationRequirementType(
if (conformance.isInvalid())
return Type();

return conformance.getTypeWitnessByName(selfType,
ctx.Id_SerializationRequirement);
return conformance.getTypeWitnessByName(ctx.Id_SerializationRequirement);
}

AbstractFunctionDecl *
Expand Down Expand Up @@ -365,11 +364,10 @@ Type swift::getAssociatedTypeOfDistributedSystemOfActor(
auto actorConformance =
lookupConformance(
actorType->getDeclaredInterfaceType(), actorProtocol);
if (!actorConformance || actorConformance.isInvalid())
if (actorConformance.isInvalid())
return Type();

auto subs = SubstitutionMap::getProtocolSubstitutions(
actorProtocol, actorType->getDeclaredInterfaceType(), actorConformance);
auto subs = SubstitutionMap::getProtocolSubstitutions(actorConformance);

memberTy = memberTy.subst(subs);

Expand Down
22 changes: 0 additions & 22 deletions lib/AST/GenericEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,28 +752,6 @@ SubstitutionMap GenericEnvironment::getForwardingSubstitutionMap() const {
MakeAbstractConformanceForGenericType());
}

std::pair<Type, ProtocolConformanceRef>
GenericEnvironment::mapConformanceRefIntoContext(GenericEnvironment *genericEnv,
Type conformingType,
ProtocolConformanceRef conformance) {
if (!genericEnv)
return {conformingType, conformance};

return genericEnv->mapConformanceRefIntoContext(conformingType, conformance);
}

std::pair<Type, ProtocolConformanceRef>
GenericEnvironment::mapConformanceRefIntoContext(
Type conformingInterfaceType,
ProtocolConformanceRef conformance) const {
auto contextConformance = conformance.subst(conformingInterfaceType,
QueryInterfaceTypeSubstitutions(this),
LookUpConformanceInModule());

auto contextType = mapTypeIntoContext(conformingInterfaceType);
return {contextType, contextConformance};
}

OpenedElementContext
OpenedElementContext::createForContextualExpansion(ASTContext &ctx,
CanPackExpansionType expansionType) {
Expand Down
35 changes: 13 additions & 22 deletions lib/AST/PackConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,15 @@ PackType *PackConformance::getTypeWitness(
// conformance.
if (auto *packExpansion = packElement->getAs<PackExpansionType>()) {
auto assocTypePattern =
conformances[i].getTypeWitness(packExpansion->getPatternType(),
assocType, options);
conformances[i].getTypeWitness(assocType, options);

packElements.push_back(PackExpansionType::get(
assocTypePattern, packExpansion->getCountType()));

// If the pack element is a scalar type, replace the scalar type with
// the associated type witness from the pattern conformance.
} else {
auto assocTypeScalar =
conformances[i].getTypeWitness(packElement, assocType, options);
auto assocTypeScalar = conformances[i].getTypeWitness(assocType, options);
packElements.push_back(assocTypeScalar);
}
}
Expand All @@ -144,24 +142,20 @@ PackConformance *PackConformance::getAssociatedConformance(
auto packElement = ConformingType->getElementType(i);

if (auto *packExpansion = packElement->getAs<PackExpansionType>()) {
auto assocTypePattern =
conformances[i].getAssociatedType(packExpansion->getPatternType(),
assocType);
packElements.push_back(PackExpansionType::get(
assocTypePattern, packExpansion->getCountType()));

auto assocConformancePattern =
conformances[i].getAssociatedConformance(packExpansion->getPatternType(),
assocType, protocol);
conformances[i].getAssociatedConformance(assocType, protocol);
packConformances.push_back(assocConformancePattern);
} else {
auto assocTypeScalar =
conformances[i].getAssociatedType(packElement, assocType);
packElements.push_back(assocTypeScalar);

auto assocTypePattern = assocConformancePattern.getType();
packElements.push_back(PackExpansionType::get(
assocTypePattern, packExpansion->getCountType()));
} else {
auto assocConformanceScalar =
conformances[i].getAssociatedConformance(packElement, assocType, protocol);
conformances[i].getAssociatedConformance(assocType, protocol);
packConformances.push_back(assocConformanceScalar);

auto assocTypeScalar = assocConformanceScalar.getType();
packElements.push_back(assocTypeScalar);
}
}

Expand Down Expand Up @@ -202,15 +196,12 @@ PackConformance::subst(InFlightSubstitution &IFS) const {
// Just substitute the conformance. We don't directly represent
// pack expansion conformances here; it's sort of implicit in the
// corresponding pack element type.
substConformances.push_back(
origConformances[i].subst(origExpansion->getPatternType(), IFS));
substConformances.push_back(origConformances[i].subst(IFS));
});
} else {
// Substitute a scalar element of the original pack.
substElementTypes.push_back(origElementType.subst(IFS));

substConformances.push_back(
origConformances[i].subst(origElementType, IFS));
substConformances.push_back(origConformances[i].subst(IFS));
}
}

Expand Down
Loading