Skip to content

Commit 046c204

Browse files
authored
Merge pull request swiftlang#60726 from slavapestov/variadic-generics-bits
AST: Plumbing for pack conformances and a few other variadic generics bits
2 parents 210b39d + 8b9d527 commit 046c204

Some content is hidden

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

67 files changed

+1564
-486
lines changed

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,13 @@ class ASTContext final {
13461346
CanGenericSignature getOpenedExistentialSignature(Type type,
13471347
GenericSignature parentSig);
13481348

1349+
/// Get a generic signature where the generic parameter τ_d_i represents
1350+
/// the element of the pack generic parameter τ_d_i… in \p baseGenericSig.
1351+
///
1352+
/// This drops the @_typeSequence attribute from each generic parameter,
1353+
/// and converts same-element requirements to same-type requirements.
1354+
CanGenericSignature getOpenedElementSignature(CanGenericSignature baseGenericSig);
1355+
13491356
GenericSignature getOverrideGenericSignature(const ValueDecl *base,
13501357
const ValueDecl *derived);
13511358

include/swift/AST/Attr.def

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

6263
// SIL-specific attributes
6364
TYPE_ATTR(block_storage)

include/swift/AST/Attr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,6 +2504,9 @@ class TypeAttributes {
25042504
};
25052505
Optional<OpaqueReturnTypeRef> OpaqueReturnTypeOf;
25062506

2507+
// Force construction of a one-element tuple type.
2508+
bool IsTuple = false;
2509+
25072510
TypeAttributes() {}
25082511

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

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,10 +2344,10 @@ NOTE(protocol_witness_type_conflict,none,
23442344
"candidate has non-matching type %0%1", (Type, StringRef))
23452345
NOTE(protocol_witness_missing_requirement,none,
23462346
"candidate would match if %0 %select{conformed to|subclassed|"
2347-
"was the same type as}2 %1", (Type, Type, unsigned))
2347+
"was the same type as|%error|%error}2 %1", (Type, Type, unsigned))
23482348
NOTE(protocol_type_witness_missing_requirement,none,
23492349
"candidate would match if the conformance required that %0 "
2350-
"%select{conformed to|subclassed|was the same type as}2 %1",
2350+
"%select{conformed to|subclassed|was the same type as|%error|%error}2 %1",
23512351
(Type, Type, unsigned))
23522352

23532353
NOTE(protocol_witness_optionality_conflict,none,

include/swift/AST/PackConformance.h

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//===--- PackConformance.h - Variadic Protocol Conformance ------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the PackConformance structure, which describes the
14+
// conformance of a type pack parameter to a protocol.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
#ifndef SWIFT_AST_PACKCONFORMANCE_H
18+
#define SWIFT_AST_PACKCONFORMANCE_H
19+
20+
#include "swift/AST/ASTAllocated.h"
21+
#include "swift/AST/ProtocolConformanceRef.h"
22+
#include "swift/AST/Type.h"
23+
#include "swift/AST/TypeAlignments.h"
24+
#include "swift/Basic/Compiler.h"
25+
#include "llvm/ADT/ArrayRef.h"
26+
#include "llvm/ADT/FoldingSet.h"
27+
#include "llvm/Support/TrailingObjects.h"
28+
29+
namespace swift {
30+
31+
class PackType;
32+
33+
class alignas(1 << DeclAlignInBits) PackConformance final
34+
: public ASTAllocated<PackConformance>,
35+
public llvm::FoldingSetNode,
36+
private llvm::TrailingObjects<PackConformance, ProtocolConformanceRef> {
37+
friend class ASTContext;
38+
friend TrailingObjects;
39+
40+
/// The pack type conforming to the protocol.
41+
PackType *ConformingType;
42+
43+
/// The conformed-to protocol.
44+
ProtocolDecl *Protocol;
45+
46+
public:
47+
void Profile(llvm::FoldingSetNodeID &ID) const;
48+
static void Profile(llvm::FoldingSetNodeID &ID,
49+
PackType *conformingType,
50+
ProtocolDecl *protocol,
51+
ArrayRef<ProtocolConformanceRef> conformances);
52+
53+
private:
54+
PackConformance(PackType *conformingType,
55+
ProtocolDecl *protocol,
56+
ArrayRef<ProtocolConformanceRef> conformances);
57+
58+
size_t numTrailingObjects(OverloadToken<ProtocolConformanceRef>) const;
59+
60+
public:
61+
static PackConformance *get(PackType *conformingType,
62+
ProtocolDecl *protocol,
63+
ArrayRef<ProtocolConformanceRef> conformances);
64+
65+
PackType *getType() const { return ConformingType; }
66+
67+
ProtocolDecl *getProtocol() const { return Protocol; }
68+
69+
ArrayRef<ProtocolConformanceRef> getPatternConformances() const;
70+
71+
bool isCanonical() const;
72+
73+
PackConformance *getCanonicalConformance() const;
74+
75+
PackType *getAssociatedType(Type assocType) const;
76+
77+
PackConformance *
78+
getAssociatedConformance(Type assocType, ProtocolDecl *protocol) const;
79+
80+
/// The ProtocolConformanceRef either stores a pack conformance, or
81+
/// it is invalid in the case of substitution failure.
82+
ProtocolConformanceRef subst(SubstitutionMap subMap,
83+
SubstOptions options=None) const;
84+
85+
/// The ProtocolConformanceRef either stores a pack conformance, or
86+
/// it is invalid in the case of substitution failure.
87+
ProtocolConformanceRef subst(TypeSubstitutionFn subs,
88+
LookupConformanceFn conformances,
89+
SubstOptions options=None) const;
90+
91+
SWIFT_DEBUG_DUMP;
92+
void dump(llvm::raw_ostream &out, unsigned indent = 0) const;
93+
};
94+
95+
void simple_display(llvm::raw_ostream &out, PackConformance *conformance);
96+
97+
} // end namespace swift
98+
99+
#endif // SWIFT_AST_PACKCONFORMANCE_H

include/swift/AST/Pattern.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,6 @@ class ParenPattern : public Pattern {
260260
///
261261
/// The fully general form of this is something like:
262262
/// label: (pattern) = initexpr
263-
///
264-
/// The Init and DefArgKind fields are only used in argument lists for
265-
/// functions. They are not parsed as part of normal pattern grammar.
266263
class TuplePatternElt {
267264
Identifier Label;
268265
SourceLoc LabelLoc;
@@ -277,10 +274,6 @@ class TuplePatternElt {
277274

278275
Identifier getLabel() const { return Label; }
279276
SourceLoc getLabelLoc() const { return LabelLoc; }
280-
void setLabel(Identifier I, SourceLoc Loc) {
281-
Label = I;
282-
LabelLoc = Loc;
283-
}
284277

285278
Pattern *getPattern() { return ThePattern; }
286279
const Pattern *getPattern() const {

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace swift {
3333

3434
class BuiltinProtocolConformance;
3535
class ConcreteDeclRef;
36+
class PackConformance;
3637
class ProtocolConformance;
3738
enum class EffectKind : uint8_t;
3839

@@ -50,7 +51,9 @@ enum class EffectKind : uint8_t;
5051
/// ProtocolConformanceRef allows the efficient recovery of the protocol
5152
/// even when the conformance is abstract.
5253
class ProtocolConformanceRef {
53-
using UnionType = llvm::PointerUnion<ProtocolDecl*, ProtocolConformance*>;
54+
using UnionType = llvm::PointerUnion<ProtocolDecl *,
55+
ProtocolConformance *,
56+
PackConformance *>;
5457
UnionType Union;
5558

5659
explicit ProtocolConformanceRef(UnionType value) : Union(value) {}
@@ -68,6 +71,12 @@ class ProtocolConformanceRef {
6871
"cannot construct ProtocolConformanceRef with null");
6972
}
7073

74+
/// Create a pack protocol conformance reference.
75+
explicit ProtocolConformanceRef(PackConformance *conf) : Union(conf) {
76+
assert(conf != nullptr &&
77+
"cannot construct ProtocolConformanceRef with null");
78+
}
79+
7180
ProtocolConformanceRef(std::nullptr_t = nullptr)
7281
: Union((ProtocolDecl *)nullptr) {}
7382

@@ -98,6 +107,13 @@ class ProtocolConformanceRef {
98107
return Union.get<ProtocolConformance*>();
99108
}
100109

110+
bool isPack() const {
111+
return !isInvalid() && Union.is<PackConformance*>();
112+
}
113+
PackConformance *getPack() const {
114+
return Union.get<PackConformance*>();
115+
}
116+
101117
bool isAbstract() const {
102118
return !isInvalid() && Union.is<ProtocolDecl*>();
103119
}

include/swift/AST/Requirement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Requirement
5858
Requirement subst(Args &&...args) const {
5959
auto newFirst = getFirstType().subst(std::forward<Args>(args)...);
6060
switch (getKind()) {
61+
case RequirementKind::SameCount:
6162
case RequirementKind::Conformance:
6263
case RequirementKind::Superclass:
6364
case RequirementKind::SameType: {

include/swift/AST/RequirementBase.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ enum class RequirementKind : unsigned {
3636
/// A layout bound T : L, where T is a type that depends on a generic
3737
/// parameter and L is some layout specification that should bound T.
3838
Layout,
39+
/// A same-count requirement T.count == U.count, where T and U are pack
40+
/// parameters.
41+
SameCount
3942

40-
// Note: there is code that packs this enum in a 2-bit bitfield. Audit users
43+
// Note: there is code that packs this enum in a 3-bit bitfield. Audit users
4144
// when adding enumerators.
4245
};
4346

@@ -102,6 +105,7 @@ class RequirementBase {
102105
hash_value(requirement.FirstTypeAndKind.getOpaqueValue());
103106
llvm::hash_code second;
104107
switch (requirement.getKind()) {
108+
case RequirementKind::SameCount:
105109
case RequirementKind::Conformance:
106110
case RequirementKind::Superclass:
107111
case RequirementKind::SameType:
@@ -123,6 +127,7 @@ class RequirementBase {
123127
return false;
124128

125129
switch (lhs.getKind()) {
130+
case RequirementKind::SameCount:
126131
case RequirementKind::Conformance:
127132
case RequirementKind::Superclass:
128133
case RequirementKind::SameType:

include/swift/AST/TypeAlignments.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ namespace swift {
4646
class NormalProtocolConformance;
4747
class OpaqueValueExpr;
4848
class OperatorDecl;
49+
class PackConformance;
4950
class Pattern;
5051
class ProtocolDecl;
5152
class ProtocolConformance;
@@ -133,6 +134,7 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::Expr, swift::ExprAlignInBits)
133134
LLVM_DECLARE_TYPE_ALIGNMENT(swift::CaptureListExpr, swift::ExprAlignInBits)
134135
LLVM_DECLARE_TYPE_ALIGNMENT(swift::AbstractClosureExpr, swift::ExprAlignInBits)
135136
LLVM_DECLARE_TYPE_ALIGNMENT(swift::OpaqueValueExpr, swift::ExprAlignInBits)
137+
LLVM_DECLARE_TYPE_ALIGNMENT(swift::PackConformance, swift::DeclAlignInBits)
136138
LLVM_DECLARE_TYPE_ALIGNMENT(swift::ProtocolConformance, swift::DeclAlignInBits)
137139
LLVM_DECLARE_TYPE_ALIGNMENT(swift::NormalProtocolConformance,
138140
swift::DeclAlignInBits)

0 commit comments

Comments
 (0)