Skip to content

Commit e002d96

Browse files
authored
Merge pull request #85169 from jckarter/builtin-generic-base-class
Add a BuiltinGenericType base class.
2 parents 450fe43 + cf5f7c8 commit e002d96

File tree

11 files changed

+250
-92
lines changed

11 files changed

+250
-92
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,10 @@ class ASTContext final {
16121612
OutputBackend = std::move(OutBackend);
16131613
}
16141614

1615+
private:
1616+
friend class BuiltinGenericType;
1617+
GenericSignature &getCachedBuiltinGenericTypeSignature(TypeKind kind);
1618+
16151619
private:
16161620
friend Decl;
16171621

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,28 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
134134
CanBuiltinUnboundGenericType type2) {
135135
return asImpl().visitDifferentTypeStructure(type1, type2);
136136
}
137-
138-
bool visitBuiltinFixedArrayType(CanBuiltinFixedArrayType type1,
139-
CanBuiltinFixedArrayType type2) {
140-
if (asImpl().visit(type1->getSize(), type2->getSize())) {
137+
138+
bool visitBuiltinGenericType(CanBuiltinGenericType type1,
139+
CanBuiltinGenericType type2) {
140+
if (type1->getBuiltinTypeKind() != type2->getBuiltinTypeKind()) {
141141
return true;
142142
}
143-
return asImpl().visit(type1->getElementType(), type2->getElementType());
143+
144+
auto subs1 = type1->getSubstitutions();
145+
auto subs2 = type2->getSubstitutions();
146+
147+
for (unsigned i : indices(subs1.getReplacementTypes())) {
148+
if (asImpl().visit(CanType(subs1.getReplacementTypes()[i]),
149+
CanType(subs2.getReplacementTypes()[i]))) {
150+
return true;
151+
}
152+
}
153+
for (unsigned i : indices(subs1.getConformances())) {
154+
if (subs1.getConformances()[i] != subs2.getConformances()[i]) {
155+
return true;
156+
}
157+
}
158+
return false;
144159
}
145160

146161
bool visitPackType(CanPackType type1, CanPackType type2) {

include/swift/AST/TypeMatcher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class TypeMatcher {
112112
TRIVIAL_CASE(BuiltinFloatType)
113113
TRIVIAL_CASE(BuiltinVectorType)
114114
TRIVIAL_CASE(BuiltinUnboundGenericType)
115-
TRIVIAL_CASE(BuiltinFixedArrayType)
115+
TRIVIAL_CASE(BuiltinGenericType)
116116
TRIVIAL_CASE(IntegerType)
117117
#define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type)
118118
#include "swift/AST/TypeNodes.def"

include/swift/AST/TypeNodes.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ ABSTRACT_TYPE(Builtin, Type)
141141
BUILTIN_CONCRETE_TYPE(BuiltinDefaultActorStorage, BuiltinType)
142142
BUILTIN_CONCRETE_TYPE(BuiltinNonDefaultDistributedActorStorage, BuiltinType)
143143
BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType)
144-
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinType)
144+
ABSTRACT_TYPE(BuiltinGeneric, BuiltinType)
145+
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinGenericType)
146+
TYPE_RANGE(BuiltinGeneric, BuiltinFixedArray, BuiltinFixedArray)
145147
BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType)
146148
BUILTIN_CONCRETE_TYPE(BuiltinImplicitActor, BuiltinType)
147149
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinImplicitActor)

include/swift/AST/TypeTransform.h

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "swift/AST/GenericEnvironment.h"
2222
#include "swift/AST/SILLayout.h"
2323
#include "swift/AST/LifetimeDependence.h"
24+
#include "swift/AST/SubstitutionMap.h"
25+
#include "llvm/ADT/SmallVector.h"
2426

2527
namespace swift {
2628

@@ -117,29 +119,26 @@ case TypeKind::Id:
117119
case TypeKind::Integer:
118120
return t;
119121

122+
// BuiltinGenericType subclasses
120123
case TypeKind::BuiltinFixedArray: {
121-
auto bfaTy = cast<BuiltinFixedArrayType>(base);
122-
123-
Type transSize = doIt(bfaTy->getSize(),
124-
TypePosition::Invariant);
125-
if (!transSize) {
126-
return Type();
127-
}
128-
129-
Type transElement = doIt(bfaTy->getElementType(),
130-
TypePosition::Invariant);
131-
if (!transElement) {
132-
return Type();
133-
}
134-
135-
CanType canTransSize = transSize->getCanonicalType();
136-
CanType canTransElement = transElement->getCanonicalType();
137-
if (canTransSize != bfaTy->getSize()
138-
|| canTransElement != bfaTy->getElementType()) {
139-
return BuiltinFixedArrayType::get(canTransSize, canTransElement);
124+
auto bgaTy = cast<BuiltinGenericType>(base);
125+
126+
llvm::SmallVector<Type, 2> transReplacements;
127+
128+
for (auto t : bgaTy->getSubstitutions().getReplacementTypes()) {
129+
Type transTy = doIt(t, TypePosition::Invariant);
130+
if (!transTy) {
131+
return Type();
132+
}
133+
transReplacements.push_back(transTy);
140134
}
141-
142-
return bfaTy;
135+
136+
// TODO: translate conformances. No builtin types yet have conformance
137+
// requirements in their generic signatures.
138+
auto transSubs = SubstitutionMap::get(bgaTy->getGenericSignature(),
139+
transReplacements,
140+
ArrayRef<ProtocolConformanceRef>{});
141+
return bgaTy->getWithSubstitutions(transSubs);
143142
}
144143

145144
case TypeKind::PrimaryArchetype:

include/swift/AST/Types.h

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,25 +1780,63 @@ class BuiltinUnboundGenericType : public BuiltinType {
17801780
};
17811781
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinUnboundGenericType, BuiltinType)
17821782

1783+
/// BuiltinGenericType - Base class for builtins that are parameterized by
1784+
/// a generic signature.
1785+
class BuiltinGenericType : public BuiltinType {
1786+
protected:
1787+
1788+
BuiltinGenericType(TypeKind kind, ASTContext &context,
1789+
RecursiveTypeProperties properties)
1790+
: BuiltinType(kind, context, properties)
1791+
{}
1792+
1793+
/// The substitution map is cached here once requested.
1794+
mutable std::optional<SubstitutionMap> CachedSubstitutionMap = std::nullopt;
1795+
1796+
public:
1797+
static bool classof(const TypeBase *T) {
1798+
return T->getKind() >= TypeKind::First_BuiltinGenericType
1799+
&& T->getKind() <= TypeKind::Last_BuiltinGenericType;
1800+
}
1801+
1802+
// Get the generic signature describing the parameterization of types of
1803+
// this class.
1804+
GenericSignature getGenericSignature() const;
1805+
1806+
// Get the substitution map for this particular type.
1807+
SubstitutionMap getSubstitutions() const;
1808+
1809+
// Produce another type of the same class but with different arguments.
1810+
CanTypeWrapper<BuiltinGenericType>
1811+
getWithSubstitutions(SubstitutionMap newSubs) const;
1812+
};
1813+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinGenericType, BuiltinType)
1814+
17831815
/// BuiltinFixedArrayType - The builtin type representing N values stored
17841816
/// inline contiguously.
17851817
///
17861818
/// All elements of a value of this type must be fully initialized any time the
17871819
/// value may be copied, moved, or destroyed.
1788-
class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
1820+
class BuiltinFixedArrayType : public BuiltinGenericType,
1821+
public llvm::FoldingSetNode {
17891822
friend class ASTContext;
17901823

17911824
CanType Size;
17921825
CanType ElementType;
17931826

17941827
BuiltinFixedArrayType(CanType Size, CanType ElementType,
17951828
RecursiveTypeProperties properties)
1796-
: BuiltinType(TypeKind::BuiltinFixedArray, ElementType->getASTContext(),
1797-
properties),
1829+
: BuiltinGenericType(TypeKind::BuiltinFixedArray,
1830+
ElementType->getASTContext(),
1831+
properties),
17981832
Size(Size),
17991833
ElementType(ElementType)
18001834
{}
18011835

1836+
friend BuiltinGenericType;
1837+
/// Get the generic arguments as a substitution map.
1838+
SubstitutionMap buildSubstitutions() const;
1839+
18021840
public:
18031841
/// Arrays with more elements than this are always treated as in-memory values.
18041842
///
@@ -1826,7 +1864,7 @@ class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
18261864

18271865
/// Get the element type.
18281866
CanType getElementType() const { return ElementType; }
1829-
1867+
18301868
void Profile(llvm::FoldingSetNodeID &ID) const {
18311869
Profile(ID, getSize(), getElementType());
18321870
}
@@ -1836,7 +1874,7 @@ class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
18361874
ID.AddPointer(ElementType.getPointer());
18371875
}
18381876
};
1839-
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinType)
1877+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinGenericType)
18401878

18411879
/// BuiltinRawPointerType - The builtin raw (and dangling) pointer type. This
18421880
/// pointer is completely unmanaged and is equivalent to i8* in LLVM IR.

lib/AST/ASTContext.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,13 @@ struct ASTContext::Implementation {
538538
/// Local and closure discriminators per context.
539539
llvm::DenseMap<const DeclContext *, unsigned> NextDiscriminator;
540540

541+
/// Cached generic signatures for generic builtin types.
542+
static const unsigned NumBuiltinGenericTypes
543+
= unsigned(TypeKind::Last_BuiltinGenericType)
544+
- unsigned(TypeKind::First_BuiltinGenericType) + 1;
545+
std::array<GenericSignature, NumBuiltinGenericTypes>
546+
BuiltinGenericTypeSignatures = {};
547+
541548
/// Structure that captures data that is segregated into different
542549
/// arenas.
543550
struct Arena {
@@ -7357,3 +7364,13 @@ AvailabilityDomain ASTContext::getTargetAvailabilityDomain() const {
73577364
// Fall back to the universal domain for triples without a platform.
73587365
return AvailabilityDomain::forUniversal();
73597366
}
7367+
7368+
GenericSignature &
7369+
ASTContext::getCachedBuiltinGenericTypeSignature(TypeKind kind) {
7370+
ASSERT(kind >= TypeKind::First_BuiltinGenericType
7371+
&& kind <= TypeKind::Last_BuiltinGenericType
7372+
&& "not a builtin generic type kind");
7373+
7374+
return getImpl().BuiltinGenericTypeSignatures
7375+
[unsigned(kind) - unsigned(TypeKind::First_BuiltinGenericType)];
7376+
}

0 commit comments

Comments
 (0)