Skip to content

Commit a3decc1

Browse files
authored
Merge pull request #64684 from slavapestov/variadic-generics-cherry-picks-5.9
[5.9] Variadic generics cherry-picks
2 parents 665ef46 + 6220bc9 commit a3decc1

Some content is hidden

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

42 files changed

+786
-491
lines changed

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,26 @@ public enum ArgumentConvention {
122122
/// guarantees its validity for the entirety of the call.
123123
case directGuaranteed
124124

125+
/// This argument is a value pack of mutable references to storage,
126+
/// which the function is being given exclusive access to. The elements
127+
/// must be passed indirectly.
128+
case packInout
129+
130+
/// This argument is a value pack, and ownership of the elements is being
131+
/// transferred into this function. Whether the elements are passed
132+
/// indirectly is recorded in the pack type.
133+
case packOwned
134+
135+
/// This argument is a value pack, and ownership of the elements is not
136+
/// being transferred into this function. Whether the elements are passed
137+
/// indirectly is recorded in the pack type.
138+
case packGuaranteed
139+
125140
public var isIndirect: Bool {
126141
switch self {
127142
case .indirectIn, .indirectInGuaranteed,
128-
.indirectInout, .indirectInoutAliasable, .indirectOut:
143+
.indirectInout, .indirectInoutAliasable, .indirectOut,
144+
.packInout, .packOwned, .packGuaranteed:
129145
return true
130146
case .directOwned, .directUnowned, .directGuaranteed:
131147
return false
@@ -134,20 +150,23 @@ public enum ArgumentConvention {
134150

135151
public var isIndirectIn: Bool {
136152
switch self {
137-
case .indirectIn, .indirectInGuaranteed:
153+
case .indirectIn, .indirectInGuaranteed,
154+
.packOwned, .packGuaranteed:
138155
return true
139156
case .directOwned, .directUnowned, .directGuaranteed,
140-
.indirectInout, .indirectInoutAliasable, .indirectOut:
157+
.indirectInout, .indirectInoutAliasable, .indirectOut,
158+
.packInout:
141159
return false
142160
}
143161
}
144162

145163
public var isGuaranteed: Bool {
146164
switch self {
147-
case .indirectInGuaranteed, .directGuaranteed:
165+
case .indirectInGuaranteed, .directGuaranteed, .packGuaranteed:
148166
return true
149167
case .indirectIn, .directOwned, .directUnowned,
150-
.indirectInout, .indirectInoutAliasable, .indirectOut:
168+
.indirectInout, .indirectInoutAliasable, .indirectOut,
169+
.packInout, .packOwned:
151170
return false
152171
}
153172
}
@@ -157,7 +176,10 @@ public enum ArgumentConvention {
157176
case .indirectIn,
158177
.indirectOut,
159178
.indirectInGuaranteed,
160-
.indirectInout:
179+
.indirectInout,
180+
.packInout,
181+
.packOwned,
182+
.packGuaranteed:
161183
return true
162184

163185
case .indirectInoutAliasable,
@@ -171,15 +193,18 @@ public enum ArgumentConvention {
171193
public var isInout: Bool {
172194
switch self {
173195
case .indirectInout,
174-
.indirectInoutAliasable:
196+
.indirectInoutAliasable,
197+
.packInout:
175198
return true
176199

177200
case .indirectIn,
178201
.indirectOut,
179202
.indirectInGuaranteed,
180203
.directUnowned,
181204
.directGuaranteed,
182-
.directOwned:
205+
.directOwned,
206+
.packOwned,
207+
.packGuaranteed:
183208
return false
184209
}
185210
}
@@ -204,6 +229,9 @@ extension BridgedArgumentConvention {
204229
case .Direct_Owned: return .directOwned
205230
case .Direct_Unowned: return .directUnowned
206231
case .Direct_Guaranteed: return .directGuaranteed
232+
case .Pack_Inout: return .packInout
233+
case .Pack_Owned: return .packOwned
234+
case .Pack_Guaranteed: return .packGuaranteed
207235
default:
208236
fatalError("unsupported argument convention")
209237
}

SwiftCompilerSources/Sources/SIL/Effects.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,12 +541,12 @@ public struct SideEffects : CustomStringConvertible, NoReflectionChildren {
541541
result.ownership = SideEffects.Ownership()
542542
}
543543
switch convention {
544-
case .indirectIn:
544+
case .indirectIn, .packOwned:
545545
result.memory.write = false
546-
case .indirectInGuaranteed:
546+
case .indirectInGuaranteed, .packGuaranteed:
547547
result.memory.write = false
548548
result.ownership.destroy = false
549-
case .indirectOut:
549+
case .indirectOut, .packInout:
550550
result.memory.read = false
551551
result.ownership.copy = false
552552
result.ownership.destroy = false

include/swift/AST/Types.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Identifier;
7171
class InOutType;
7272
class OpaqueTypeDecl;
7373
class OpenedArchetypeType;
74+
class PackExpansionType;
7475
class PackType;
7576
enum class ParamSpecifier : uint8_t;
7677
class PlaceholderTypeRepr;
@@ -2414,6 +2415,12 @@ class TupleType final : public TypeBase, public llvm::FoldingSetNode,
24142415

24152416
unsigned getNumElements() const { return Bits.TupleType.Count; }
24162417

2418+
/// Returns the number of non-PackExpansionType elements. This is the
2419+
/// minimum length of the tuple after substitution; a tuple with
2420+
/// zero or one scalar elements is unwrapped if it would otherwise be
2421+
/// a one-element tuple after substitution.
2422+
unsigned getNumScalarElements() const;
2423+
24172424
/// getElements - Return the elements of this tuple.
24182425
ArrayRef<TupleTypeElt> getElements() const {
24192426
return {getTrailingObjects<TupleTypeElt>(), getNumElements()};
@@ -6838,6 +6845,8 @@ class PackType final : public TypeBase, public llvm::FoldingSetNode,
68386845

68396846
bool containsPackExpansionType() const;
68406847

6848+
PackExpansionType *unwrapSingletonPackExpansion() const;
6849+
68416850
CanTypeWrapper<PackType> getReducedShape();
68426851

68436852
public:
@@ -6876,6 +6885,8 @@ BEGIN_CAN_TYPE_WRAPPER(PackType, Type)
68766885
CanTypeArrayRef getElementTypes() const {
68776886
return CanTypeArrayRef(getPointer()->getElementTypes());
68786887
}
6888+
6889+
CanTypeWrapper<PackExpansionType> unwrapSingletonPackExpansion() const;
68796890
END_CAN_TYPE_WRAPPER(PackType, Type)
68806891

68816892
inline CanPackType CanTupleType::getInducedPackType() const {
@@ -6964,6 +6975,13 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69646975
}
69656976
END_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69666977

6978+
6979+
inline CanTypeWrapper<PackExpansionType>
6980+
CanPackType::unwrapSingletonPackExpansion() const {
6981+
return CanPackExpansionType(
6982+
getPointer()->unwrapSingletonPackExpansion());
6983+
}
6984+
69676985
/// getASTContext - Return the ASTContext that this type belongs to.
69686986
inline ASTContext &TypeBase::getASTContext() const {
69696987
// If this type is canonical, it has the ASTContext in it.

include/swift/IRGen/GenericRequirement.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ class GenericRequirement {
7676
}
7777

7878
static GenericRequirement forShape(CanType type) {
79-
assert(!isa<PackType>(type));
8079
assert(type->isParameterPack() || isa<PackArchetypeType>(type));
8180
return GenericRequirement(Kind::Shape, type, nullptr);
8281
}
@@ -92,7 +91,6 @@ class GenericRequirement {
9291
}
9392

9493
static GenericRequirement forMetadata(CanType type) {
95-
assert(!isa<PackType>(type));
9694
auto kind = ((type->isParameterPack() ||
9795
isa<PackArchetypeType>(type))
9896
? Kind::MetadataPack : Kind::Metadata);
@@ -110,7 +108,6 @@ class GenericRequirement {
110108
}
111109

112110
static GenericRequirement forWitnessTable(CanType type, ProtocolDecl *proto) {
113-
assert(!isa<PackType>(type));
114111
auto kind = ((type->isParameterPack() ||
115112
isa<PackArchetypeType>(type))
116113
? Kind::WitnessTablePack

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,28 @@ FUNCTION(CompareProtocolConformanceDescriptors,
10081008
ATTRS(NoUnwind, ReadNone, WillReturn),
10091009
EFFECT(NoEffect)) // ?
10101010

1011+
// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
1012+
// const Metadata * const *
1013+
// swift_allocateMetadataPack(const Metadata * const *ptr, size_t count);
1014+
FUNCTION(AllocateMetadataPack,
1015+
swift_allocateMetadataPack, SwiftCC,
1016+
AlwaysAvailable, // FIXME
1017+
RETURNS(TypeMetadataPtrPtrTy),
1018+
ARGS(TypeMetadataPtrPtrTy, SizeTy),
1019+
ATTRS(NoUnwind, WillReturn),
1020+
EFFECT(MetaData)) // ?
1021+
1022+
// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
1023+
// const WitnessTable * const *
1024+
// swift_allocateWitnessTablePack(const WitnessTable * const *ptr, size_t count);
1025+
FUNCTION(AllocateWitnessTablePack,
1026+
swift_allocateWitnessTablePack, SwiftCC,
1027+
AlwaysAvailable, // FIXME
1028+
RETURNS(WitnessTablePtrPtrTy),
1029+
ARGS(WitnessTablePtrPtrTy, SizeTy),
1030+
ATTRS(NoUnwind, WillReturn),
1031+
EFFECT(MetaData)) // ?
1032+
10111033
// Metadata *swift_getMetatypeMetadata(Metadata *instanceTy);
10121034
FUNCTION(GetMetatypeMetadata, swift_getMetatypeMetadata, C_CC, AlwaysAvailable,
10131035
RETURNS(TypeMetadataPtrTy),

include/swift/SIL/SILCloner.h

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -279,34 +279,22 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
279279
if (type->getNumElements() == 0) return false;
280280

281281
// Do a first pass over the tuple elements to check out the
282-
// non-expansions. If there's more than one of them, or any of them
283-
// is labeled, we definitely stay a tuple and don't need to substitute
284-
// any of the expansions.
285-
unsigned numScalarElements = 0;
286-
for (auto index : indices(type->getElements())) {
287-
auto eltType = type.getElementType(index);
288-
// Ignore pack expansions in this pass.
289-
if (isa<PackExpansionType>(eltType)) continue;
290-
291-
// If there's a labeled scalar element, we'll stay a tuple.
292-
if (type->getElement(index).hasName()) return false;
293-
294-
// If there are multiple scalar elements, we'll stay a tuple.
295-
if (++numScalarElements > 1) return false;
296-
}
297-
298-
assert(numScalarElements <= 1);
299-
300-
// We must have expansions if we got here: if all the elements were
301-
// scalar, and none of them were labelled, and there wasn't more than
302-
// one of them, and there was at least one of them, then somehow
303-
// we had a tuple with a single unlabeled element.
282+
// non-expansions. If there's more than one of them we definitely
283+
// stay a tuple and don't need to substitute any of the expansions.
284+
unsigned numScalarElements = type->getNumScalarElements();
285+
if (numScalarElements > 1)
286+
return false;
304287

305288
// Okay, we need to substitute the count types for the expansions.
306289
for (auto index : indices(type->getElements())) {
307290
// Ignore non-expansions because we've already counted them.
308291
auto expansion = dyn_cast<PackExpansionType>(type.getElementType(index));
309-
if (!expansion) continue;
292+
if (!expansion) {
293+
// If we have a non-expansion with a label, we stay a tuple.
294+
if (type->getElement(index).hasName())
295+
return false;
296+
continue;
297+
}
310298

311299
// Substitute the shape class of the expansion.
312300
auto newShapeClass = getOpASTType(expansion.getCountType());

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3781,6 +3781,9 @@ ParameterizedProtocolType *ParameterizedProtocolType::get(const ASTContext &C,
37813781

37823782
auto size = totalSizeToAlloc<Type>(args.size());
37833783
auto mem = C.Allocate(size, alignof(ParameterizedProtocolType), arena);
3784+
3785+
properties |= RecursiveTypeProperties::HasParameterizedExistential;
3786+
37843787
auto paramTy = new (mem) ParameterizedProtocolType(
37853788
isCanonical ? &C : nullptr, baseTy, args, properties);
37863789
C.getImpl().getArena(arena).ParameterizedProtocolTypes.InsertNode(
@@ -3871,8 +3874,6 @@ ExistentialMetatypeType::get(Type T, Optional<MetatypeRepresentation> repr,
38713874
T = existential->getConstraintType();
38723875

38733876
auto properties = T->getRecursiveProperties();
3874-
if (T->is<ParameterizedProtocolType>())
3875-
properties |= RecursiveTypeProperties::HasParameterizedExistential;
38763877
auto arena = getArena(properties);
38773878

38783879
unsigned reprKey;
@@ -4742,8 +4743,6 @@ Type ExistentialType::get(Type constraint) {
47424743
printWithAny = false;
47434744

47444745
auto properties = constraint->getRecursiveProperties();
4745-
if (constraint->is<ParameterizedProtocolType>())
4746-
properties |= RecursiveTypeProperties::HasParameterizedExistential;
47474746
auto arena = getArena(properties);
47484747

47494748
auto &entry = C.getImpl().getArena(arena).ExistentialTypes[constraint];

lib/AST/ASTDemangler.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,7 @@ Type ASTBuilder::createConstrainedExistentialType(
674674

675675
case RequirementKind::SameType:
676676
if (auto *DMT = req.getFirstType()->getAs<DependentMemberType>())
677-
if (baseDecl->getAssociatedType(DMT->getName()))
678-
cmap[DMT->getName()] = req.getSecondType();
677+
cmap[DMT->getName()] = req.getSecondType();
679678
}
680679
}
681680
llvm::SmallVector<Type, 4> args;

lib/AST/ASTMangler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,14 +1411,18 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
14111411
}
14121412

14131413
case TypeKind::ProtocolComposition: {
1414+
auto *PCT = cast<ProtocolCompositionType>(tybase);
1415+
if (PCT->hasParameterizedExistential())
1416+
return appendConstrainedExistential(PCT, sig, forDecl);
1417+
14141418
// We mangle ProtocolType and ProtocolCompositionType using the
14151419
// same production:
1416-
auto layout = type->getExistentialLayout();
1420+
auto layout = PCT->getExistentialLayout();
14171421
return appendExistentialLayout(layout, sig, forDecl);
14181422
}
14191423

14201424
case TypeKind::ParameterizedProtocol:
1421-
llvm_unreachable("Handled by generalized existential mangling!");
1425+
return appendConstrainedExistential(tybase, sig, forDecl);
14221426

14231427
case TypeKind::Existential: {
14241428
auto *ET = cast<ExistentialType>(tybase);

lib/AST/ParameterPack.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ CanType PackExpansionType::getReducedShape() {
102102
return CanType(PackExpansionType::get(reducedShape, reducedShape));
103103
}
104104

105+
unsigned TupleType::getNumScalarElements() const {
106+
unsigned n = 0;
107+
for (auto elt : getElements()) {
108+
if (!elt.getType()->is<PackExpansionType>())
109+
++n;
110+
}
111+
112+
return n;
113+
}
114+
105115
bool TupleType::containsPackExpansionType() const {
106116
for (auto elt : getElements()) {
107117
if (elt.getType()->is<PackExpansionType>())
@@ -290,6 +300,18 @@ CanPackType CanPackType::getSingletonPackExpansion(CanType param) {
290300
return CanPackType(PackType::getSingletonPackExpansion(param));
291301
}
292302

303+
PackExpansionType *PackType::unwrapSingletonPackExpansion() const {
304+
if (getNumElements() == 1) {
305+
if (auto expansion = getElementTypes()[0]->getAs<PackExpansionType>()) {
306+
auto pattern = expansion->getPatternType();
307+
if (pattern->isParameterPack() || pattern->is<PackArchetypeType>())
308+
return expansion;
309+
}
310+
}
311+
312+
return nullptr;
313+
}
314+
293315
bool SILPackType::containsPackExpansionType() const {
294316
for (auto type : getElementTypes()) {
295317
if (isa<PackExpansionType>(type))

lib/Demangling/NodePrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ class NodePrinter {
310310
case Node::Kind::Pack:
311311
case Node::Kind::SILPackDirect:
312312
case Node::Kind::SILPackIndirect:
313-
case Node::Kind::ConstrainedExistential:
314313
case Node::Kind::ConstrainedExistentialRequirementList:
315314
case Node::Kind::ConstrainedExistentialSelf:
316315
case Node::Kind::Protocol:
@@ -340,6 +339,7 @@ class NodePrinter {
340339
case Node::Kind::ProtocolListWithAnyObject:
341340
return Node->getChild(0)->getChild(0)->getNumChildren() == 0;
342341

342+
case Node::Kind::ConstrainedExistential:
343343
case Node::Kind::PackExpansion:
344344
case Node::Kind::ProtocolListWithClass:
345345
case Node::Kind::AccessorAttachedMacroExpansion:

0 commit comments

Comments
 (0)