Skip to content

Commit 6f043e0

Browse files
committed
AST: Introduce TupleType::getNumScalarElements()
1 parent 30d4d7b commit 6f043e0

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

include/swift/AST/Types.h

Lines changed: 7 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()};

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/ParameterPack.cpp

Lines changed: 10 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>())

0 commit comments

Comments
 (0)