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+
}

lib/AST/ASTDumper.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,11 @@ namespace {
847847
printCommonPost(CD);
848848
}
849849

850+
void visitBuiltinTupleDecl(BuiltinTupleDecl *BTD) {
851+
printCommon(BTD, "builtin_tuple_decl");
852+
printCommonPost(BTD);
853+
}
854+
850855
void visitPatternBindingDecl(PatternBindingDecl *PBD) {
851856
printCommon(PBD, "pattern_binding_decl");
852857

@@ -3800,6 +3805,12 @@ namespace {
38003805
PrintWithColorRAII(OS, ParenthesisColor) << ')';
38013806
}
38023807

3808+
void visitBuiltinTupleType(BuiltinTupleType *T, StringRef label) {
3809+
printCommon(label, "builtin_tuple_type");
3810+
printField("decl", T->getDecl()->printRef());
3811+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3812+
}
3813+
38033814
void visitMetatypeType(MetatypeType *T, StringRef label) {
38043815
printCommon(label, "metatype_type");
38053816
if (T->hasRepresentation())

lib/AST/ASTMangler.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1330,7 +1330,8 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
13301330
case TypeKind::Struct:
13311331
case TypeKind::BoundGenericClass:
13321332
case TypeKind::BoundGenericEnum:
1333-
case TypeKind::BoundGenericStruct: {
1333+
case TypeKind::BoundGenericStruct:
1334+
case TypeKind::BuiltinTuple: {
13341335
GenericTypeDecl *Decl;
13351336
if (auto typeAlias = dyn_cast<TypeAliasType>(type.getPointer()))
13361337
Decl = typeAlias->getDecl();
@@ -2473,6 +2474,9 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
24732474
return;
24742475
}
24752476

2477+
if (nominal && isa<BuiltinTupleDecl>(nominal))
2478+
return appendOperator("BT");
2479+
24762480
appendContextOf(decl);
24772481

24782482
// Always use Clang names for imported Clang declarations, unless they don't
@@ -2554,6 +2558,8 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
25542558
case DeclKind::Struct:
25552559
appendOperator("V");
25562560
break;
2561+
case DeclKind::BuiltinTuple:
2562+
llvm_unreachable("Not implemented");
25572563
}
25582564
}
25592565

lib/AST/ASTPrinter.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,6 +3673,11 @@ void PrintAST::visitProtocolDecl(ProtocolDecl *decl) {
36733673
Options.BracketOptions.shouldCloseNominal(decl));
36743674
}
36753675
}
3676+
3677+
void PrintAST::visitBuiltinTupleDecl(BuiltinTupleDecl *decl) {
3678+
llvm_unreachable("Not implemented");
3679+
}
3680+
36763681
static bool isStructOrClassContext(DeclContext *dc) {
36773682
auto *nominal = dc->getSelfNominalTypeDecl();
36783683
if (nominal == nullptr)
@@ -5563,13 +5568,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
55635568
Printer.callPrintStructurePre(PrintStructureKind::TupleType);
55645569
SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::TupleType); };
55655570

5566-
// Single-element tuples can only appear in SIL mode.
5567-
if (T->getNumElements() == 1 &&
5568-
!T->getElement(0).hasName() &&
5569-
!T->getElementType(0)->is<PackExpansionType>()) {
5570-
Printer << "@tuple ";
5571-
}
5572-
55735571
Printer << "(";
55745572

55755573
auto Fields = T->getElements();
@@ -5587,6 +5585,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
55875585
if (TD.hasName()) {
55885586
Printer.printName(TD.getName(), PrintNameContext::TupleElement);
55895587
Printer << ": ";
5588+
} else if (e == 1 && !EltType->is<PackExpansionType>()) {
5589+
// Unlabeled one-element tuples always print the empty label to
5590+
// distinguish them from the older syntax for ParenType.
5591+
Printer << "_: ";
55905592
}
55915593
visit(EltType);
55925594
}
@@ -6334,6 +6336,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
63346336
}
63356337
}
63366338

6339+
void visitBuiltinTupleType(BuiltinTupleType *T) {
6340+
printQualifiedType(T);
6341+
}
6342+
63376343
void visitLValueType(LValueType *T) {
63386344
Printer << "@lvalue ";
63396345
visit(T->getObjectType());

lib/AST/ASTScopeCreation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ class NodeAdder
331331
VISIT_AND_CREATE_WHOLE_PORTION(OpaqueTypeDecl, OpaqueTypeScope)
332332
#undef VISIT_AND_CREATE_WHOLE_PORTION
333333

334+
ASTScopeImpl *visitBuiltinTupleDecl(BuiltinTupleDecl *btd, ASTScopeImpl *p,
335+
ScopeCreator &scopeCreator) {
336+
llvm_unreachable("BuiltinTupleDecl should never appear in a source file");
337+
}
338+
334339
// This declaration is handled from
335340
// addChildrenForParsedAccessors
336341
ASTScopeImpl *visitAccessorDecl(AccessorDecl *ad, ASTScopeImpl *p,

0 commit comments

Comments
 (0)