Skip to content

Commit 005c9f3

Browse files
authored
Merge pull request #60639 from slavapestov/tuple-conformance-wip
Rough sketch of AST/Sema support for tuple conformances
2 parents 5e739f5 + a57ea86 commit 005c9f3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+557
-138
lines changed

include/swift/AST/ASTContext.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ namespace swift {
6666
enum class Associativity : unsigned char;
6767
class AvailabilityContext;
6868
class BoundGenericType;
69+
class BuiltinTupleDecl;
6970
class ClangModuleLoader;
7071
class ClangNode;
7172
class ClangTypeConverter;
@@ -953,7 +954,7 @@ class ASTContext final {
953954
const CanType TheIEEE80Type; /// 80-bit IEEE floating point
954955
const CanType TheIEEE128Type; /// 128-bit IEEE floating point
955956
const CanType ThePPC128Type; /// 128-bit PowerPC 2xDouble
956-
957+
957958
/// Adds a search path to SearchPathOpts, unless it is already present.
958959
///
959960
/// Does any proper bookkeeping to keep all module loaders up to date as well.
@@ -1421,6 +1422,13 @@ class ASTContext final {
14211422
/// invocation decoder of the given distributed actor.
14221423
FuncDecl *getDistributedActorArgumentDecodingMethod(NominalTypeDecl *);
14231424

1425+
/// The special Builtin.TheTupleType, which parents tuple extensions and
1426+
/// conformances.
1427+
BuiltinTupleDecl *getBuiltinTupleDecl();
1428+
1429+
/// The declared interface type of Builtin.TheTupleType.
1430+
BuiltinTupleType *getBuiltinTupleType();
1431+
14241432
private:
14251433
friend Decl;
14261434

include/swift/AST/Attr.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ TYPE_ATTR(Sendable)
5858
TYPE_ATTR(unchecked)
5959
TYPE_ATTR(_typeSequence)
6060
TYPE_ATTR(_local)
61-
TYPE_ATTR(tuple)
6261

6362
// SIL-specific attributes
6463
TYPE_ATTR(block_storage)

include/swift/AST/Attr.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,9 +2542,6 @@ class TypeAttributes {
25422542
};
25432543
Optional<OpaqueReturnTypeRef> OpaqueReturnTypeOf;
25442544

2545-
// Force construction of a one-element tuple type.
2546-
bool IsTuple = false;
2547-
25482545
TypeAttributes() {}
25492546

25502547
bool isValid() const { return AtLoc.isValid(); }

include/swift/AST/Decl.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4755,6 +4755,48 @@ class ProtocolDecl final : public NominalTypeDecl {
47554755
}
47564756
};
47574757

4758+
/// This is the special singleton Builtin.TheTupleType. It is not directly
4759+
/// visible in the source language, but we use it to attach extensions
4760+
/// and conformances for tuple types.
4761+
///
4762+
/// - The declared interface type is the special TheTupleType singleton.
4763+
/// - The generic parameter list has one pack generic parameter, <Elements...>
4764+
/// - The generic signature has no requirements, <Elements...>
4765+
/// - The self interface type is the tuple type containing a single pack
4766+
/// expansion, (Elements...).
4767+
class BuiltinTupleDecl final : public NominalTypeDecl {
4768+
TupleType *TupleSelfType = nullptr;
4769+
4770+
public:
4771+
BuiltinTupleDecl(Identifier Name, DeclContext *Parent);
4772+
4773+
SourceRange getSourceRange() const {
4774+
return SourceRange();
4775+
}
4776+
4777+
TupleType *getTupleSelfType() const;
4778+
4779+
// Implement isa/cast/dyncast/etc.
4780+
static bool classof(const Decl *D) {
4781+
return D->getKind() == DeclKind::BuiltinTuple;
4782+
}
4783+
static bool classof(const GenericTypeDecl *D) {
4784+
return D->getKind() == DeclKind::BuiltinTuple;
4785+
}
4786+
static bool classof(const NominalTypeDecl *D) {
4787+
return D->getKind() == DeclKind::BuiltinTuple;
4788+
}
4789+
static bool classof(const DeclContext *C) {
4790+
if (auto D = C->getAsDecl())
4791+
return classof(D);
4792+
return false;
4793+
}
4794+
static bool classof(const IterableDeclContext *C) {
4795+
auto NTD = dyn_cast<NominalTypeDecl>(C);
4796+
return NTD && classof(NTD);
4797+
}
4798+
};
4799+
47584800
/// AbstractStorageDecl - This is the common superclass for VarDecl and
47594801
/// SubscriptDecl, representing potentially settable memory locations.
47604802
class AbstractStorageDecl : public ValueDecl {

include/swift/AST/DeclNodes.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ ABSTRACT_DECL(Value, Decl)
151151
NOMINAL_TYPE_DECL(Struct, NominalTypeDecl)
152152
NOMINAL_TYPE_DECL(Class, NominalTypeDecl)
153153
NOMINAL_TYPE_DECL(Protocol, NominalTypeDecl)
154-
DECL_RANGE(NominalType, Enum, Protocol)
154+
NOMINAL_TYPE_DECL(BuiltinTuple, NominalTypeDecl)
155+
DECL_RANGE(NominalType, Enum, BuiltinTuple)
155156
GENERIC_VALUE_DECL(OpaqueType, GenericTypeDecl)
156157
GENERIC_VALUE_DECL(TypeAlias, GenericTypeDecl)
157158
DECL_RANGE(GenericType, Enum, TypeAlias)

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5179,8 +5179,6 @@ ERROR(opened_bad_interface_type,none,
51795179
"@opened interface type %0 is not a type parameter", (Type))
51805180
ERROR(sil_function_input_label,PointsToFirstBadToken,
51815181
"SIL function types cannot have labeled inputs", ())
5182-
ERROR(sil_function_output_label,PointsToFirstBadToken,
5183-
"SIL function types cannot have labeled results", ())
51845182
ERROR(sil_non_coro_yields,PointsToFirstBadToken,
51855183
"non-coroutine SIL function types cannot have @yield results", ())
51865184
ERROR(sil_function_repeat_convention,PointsToFirstBadToken,

include/swift/AST/KnownIdentifiers.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ IDENTIFIER_WITH_NAME(PatternMatchVar, "$match")
7575
IDENTIFIER(dynamicallyCall)
7676
IDENTIFIER(dynamicMember)
7777
IDENTIFIER(Element)
78+
IDENTIFIER(Elements)
7879
IDENTIFIER_(enclosingInstance)
7980
IDENTIFIER(Encodable)
8081
IDENTIFIER(encode)
@@ -313,6 +314,9 @@ IDENTIFIER_WITH_NAME(TypeWrapperProperty, "$_storage")
313314
IDENTIFIER(storageKeyPath)
314315
IDENTIFIER(memberwise)
315316

317+
// The singleton instance of TupleTypeDecl in the Builtin module
318+
IDENTIFIER(TheTupleType)
319+
316320
#undef IDENTIFIER
317321
#undef IDENTIFIER_
318322
#undef IDENTIFIER_WITH_NAME

include/swift/AST/TypeNodes.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ ABSTRACT_TYPE(AnyGeneric, Type)
128128
TYPE(Struct, NominalType)
129129
TYPE(Class, NominalType)
130130
TYPE(Protocol, NominalType)
131-
TYPE_RANGE(Nominal, Enum, Protocol)
131+
TYPE(BuiltinTuple, NominalType)
132+
TYPE_RANGE(Nominal, Enum, BuiltinTuple)
132133
ABSTRACT_TYPE(BoundGeneric, Type)
133134
TYPE(BoundGenericClass, BoundGenericType)
134135
TYPE(BoundGenericEnum, BoundGenericType)

include/swift/AST/Types.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ArgumentList;
5858
class AssociatedTypeDecl;
5959
class ASTContext;
6060
enum BufferPointerTypeKind : unsigned;
61+
class BuiltinTupleDecl;
6162
class ClassDecl;
6263
class ClangModuleLoader;
6364
class DependentMemberType;
@@ -899,20 +900,24 @@ class alignas(1 << TypeAlignInBits) TypeBase
899900
bool satisfiesClassConstraint();
900901

901902
/// Determine whether this type can be used as a base type for AST
902-
/// name lookup, which is the case for nominal types, protocol compositions
903-
/// and archetypes.
903+
/// name lookup, which is the case for nominal types, existential types,
904+
/// archetypes, and tuples.
904905
///
905906
/// Generally, the static vs instance and mutating vs nonmutating distinction
906907
/// is handled elsewhere, so metatypes, lvalue types and inout types are not
907908
/// allowed here.
908909
///
909-
/// Similarly, tuples formally have members, but this does not go through
910-
/// name lookup.
910+
/// Tuples have formal members to project elements by index or by label; these
911+
/// are handled directly by Sema and do not go through name lookup.
912+
///
913+
/// Bona fide members on tuples are defined on extensions of
914+
/// Builtin.TheTupleType.
911915
bool mayHaveMembers() {
912916
return (is<ArchetypeType>() ||
913917
is<ModuleType>() ||
914918
isExistentialType() ||
915-
getAnyNominal());
919+
getAnyNominal() ||
920+
is<TupleType>());
916921
}
917922

918923
/// Checks whether this type may potentially be callable. This returns true
@@ -5489,6 +5494,23 @@ BEGIN_CAN_TYPE_WRAPPER(ExistentialType, Type)
54895494
PROXY_CAN_TYPE_SIMPLE_GETTER(getConstraintType)
54905495
END_CAN_TYPE_WRAPPER(ExistentialType, Type)
54915496

5497+
5498+
/// BuiltinTupleType - A singleton nominal type which serves as the declared
5499+
/// interface type of Builtin.TheTupleType.
5500+
class BuiltinTupleType : public NominalType {
5501+
public:
5502+
// Implement isa/cast/dyncast/etc.
5503+
static bool classof(const TypeBase *T) {
5504+
return T->getKind() == TypeKind::BuiltinTuple;
5505+
}
5506+
5507+
private:
5508+
friend class ASTContext;
5509+
BuiltinTupleType(BuiltinTupleDecl *TheDecl, const ASTContext &Ctx);
5510+
};
5511+
BEGIN_CAN_TYPE_WRAPPER(BuiltinTupleType, NominalType)
5512+
END_CAN_TYPE_WRAPPER(BuiltinTupleType, NominalType)
5513+
54925514
/// LValueType - An l-value is a handle to a physical object. The
54935515
/// type of that object uniquely determines the type of an l-value
54945516
/// for it.

lib/AST/ASTContext.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,12 @@ struct ASTContext::Implementation {
552552

553553
/// Memory allocation arena for the term rewriting system.
554554
std::unique_ptr<rewriting::RewriteContext> TheRewriteContext;
555+
556+
/// The singleton Builtin.TheTupleType.
557+
BuiltinTupleDecl *TheTupleTypeDecl = nullptr;
558+
559+
/// The declared interface type of Builtin.TheTupleType.
560+
BuiltinTupleType *TheTupleType = nullptr;
555561
};
556562

557563
ASTContext::Implementation::Implementation()
@@ -3173,6 +3179,14 @@ PackType *PackType::get(const ASTContext &C, ArrayRef<Type> elements) {
31733179
RecursiveTypeProperties properties;
31743180
bool isCanonical = true;
31753181
for (Type eltTy : elements) {
3182+
assert(!eltTy->isTypeParameter() ||
3183+
!eltTy->getRootGenericParam()->isTypeSequence() &&
3184+
"Pack type parameter outside of a pack expansion");
3185+
assert(!eltTy->is<SequenceArchetypeType>() &&
3186+
"Pack type archetype outside of a pack expansion");
3187+
assert(!eltTy->is<PackType>() &&
3188+
"Cannot have pack directly inside another pack");
3189+
31763190
properties |= eltTy->getRecursiveProperties();
31773191
if (!eltTy->isCanonical())
31783192
isCanonical = false;
@@ -4511,6 +4525,11 @@ Type ExistentialType::get(Type constraint) {
45114525
properties);
45124526
}
45134527

4528+
BuiltinTupleType::BuiltinTupleType(BuiltinTupleDecl *TheDecl,
4529+
const ASTContext &Ctx)
4530+
: NominalType(TypeKind::BuiltinTuple, &Ctx, TheDecl, Type(),
4531+
RecursiveTypeProperties()) { }
4532+
45144533
LValueType *LValueType::get(Type objectTy) {
45154534
assert(!objectTy->is<LValueType>() && !objectTy->is<InOutType>() &&
45164535
"cannot have 'inout' or @lvalue wrapped inside an @lvalue");
@@ -5914,3 +5933,30 @@ bool ASTContext::isASCIIString(StringRef s) const {
59145933
}
59155934
return true;
59165935
}
5936+
5937+
/// The special Builtin.TheTupleType, which parents tuple extensions and
5938+
/// conformances.
5939+
BuiltinTupleDecl *ASTContext::getBuiltinTupleDecl() {
5940+
auto &result = getImpl().TheTupleTypeDecl;
5941+
5942+
if (result)
5943+
return result;
5944+
5945+
result = new (*this) BuiltinTupleDecl(Id_TheTupleType,
5946+
TheBuiltinModule->getFiles()[0]);
5947+
result->setAccess(AccessLevel::Public);
5948+
5949+
return result;
5950+
}
5951+
5952+
/// The declared interface type of Builtin.TheTupleType.
5953+
BuiltinTupleType *ASTContext::getBuiltinTupleType() {
5954+
auto &result = getImpl().TheTupleType;
5955+
5956+
if (result)
5957+
return result;
5958+
5959+
result = new (*this) BuiltinTupleType(getBuiltinTupleDecl(), *this);
5960+
5961+
return result;
5962+
}

0 commit comments

Comments
 (0)