Skip to content

Commit 3a24b53

Browse files
committed
TypeDecoder: Push one-element tuple unwrapping down into createTupleType() implementations
The old behavior was only correct when building substituted types, ie, if createTupleType() was never called with a pack expansion type. This was the case in the runtime's MetadataLookup which applies substitutions to an interface type to ultimately construct metadata for a fully-concrete type, but not in the ASTDemangler, where we actually build interface types. Since TypeDecoder doesn't have any way to query the kind of type it just built, let's just instead make this decision inside the implementation of the type builder concept. Fixes #67322.
1 parent 999b790 commit 3a24b53

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

include/swift/Demangling/TypeDecoder.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,13 +1052,6 @@ class TypeDecoder {
10521052
return *optError;
10531053
}
10541054

1055-
// Unwrap unlabeled one-element tuples.
1056-
//
1057-
// FIXME: The behavior of one-element labeled tuples is inconsistent throughout
1058-
// the different re-implementations of type substitution and pack expansion.
1059-
if (elements.size() == 1 && labels[0].empty())
1060-
return elements[0];
1061-
10621055
return Builder.createTupleType(elements, labels);
10631056
}
10641057
case NodeKind::TupleElement:

lib/AST/ASTDemangler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,17 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl,
328328
}
329329

330330
Type ASTBuilder::createTupleType(ArrayRef<Type> eltTypes, ArrayRef<StringRef> labels) {
331+
// Unwrap unlabeled one-element tuples.
332+
//
333+
// FIXME: The behavior of one-element labeled tuples is inconsistent
334+
// throughout the different re-implementations of type substitution
335+
// and pack expansion.
336+
if (eltTypes.size() == 1 &&
337+
!eltTypes[0]->is<PackExpansionType>() &&
338+
labels[0].empty()) {
339+
return eltTypes[0];
340+
}
341+
331342
SmallVector<TupleTypeElt, 4> elements;
332343
elements.reserve(eltTypes.size());
333344
for (unsigned i : indices(eltTypes)) {

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,14 @@ class DecodedMetadataBuilder {
19651965
TypeLookupErrorOr<BuiltType>
19661966
createTupleType(llvm::ArrayRef<BuiltType> elements,
19671967
llvm::ArrayRef<StringRef> labels) const {
1968+
// Unwrap unlabeled one-element tuples.
1969+
//
1970+
// FIXME: The behavior of one-element labeled tuples is inconsistent
1971+
// throughout the different re-implementations of type substitution
1972+
// and pack expansion.
1973+
if (elements.size() == 1 && labels[0].empty())
1974+
return elements[0];
1975+
19681976
for (auto element : elements) {
19691977
if (!element.isMetadata()) {
19701978
return TYPE_LOOKUP_ERROR_FMT("Tried to build a tuple type where "

test/DebugInfo/variadic-generics.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %target-swift-frontend -emit-ir %s -g -o - \
2-
// RUN: -parse-as-library -module-name a | %IRGenFileCheck %s
2+
// RUN: -parse-as-library -module-name a -disable-availability-checking | %IRGenFileCheck %s
33

44
public func foo<each T>(args: repeat each T) {
55
// CHECK: define {{.*}} @"$s1a3foo4argsyxxQp_tRvzlF"
@@ -22,3 +22,35 @@ public func foo<each T>(args: repeat each T) {
2222
// CHECK-DAG: ![[TYPE_PACK_TY]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "$sBpD"
2323
}
2424

25+
// Test ASTDemangler round-tripping of various pack expansion types
26+
27+
public func paramExpansionWithPattern<each T>(args: repeat Array<each T>) {}
28+
29+
public func paramExpansionWithMemberType<each T: Sequence>(args: repeat each T, elements: repeat (each T).Element) {}
30+
31+
public func tupleExpansion<each T>(args: (repeat each T)) {}
32+
33+
public func tupleExpansionWithPattern<each T>(args: (repeat Array<each T>)) {}
34+
35+
// FIXME: Crashes due to unrelated bug
36+
// public func tupleExpansionWithMemberType<each T: Sequence>(args: repeat each T, elements: (repeat (each T).Element)) {}
37+
38+
public func functionExpansion<each T>(args: (repeat each T) -> ()) {}
39+
40+
public func functionExpansionWithPattern<each T>(args: (repeat Array<each T>) -> ()) {}
41+
42+
public func functionExpansionWithMemberType<each T: Sequence>(args: repeat each T, elements: (repeat (each T).Element) -> ()) {}
43+
44+
public struct G<each T> {}
45+
46+
public func nominalExpansion<each T>(args: G<repeat each T>) {}
47+
48+
public func nominalExpansionWithPattern<each T>(args: G<repeat Array<each T>>) {}
49+
50+
public func nominalExpansionWithMemberType<each T: Sequence>(args: repeat each T, elements: G<repeat (each T).Element>) {}
51+
52+
//
53+
54+
public typealias First<T, U> = T
55+
56+
public func concreteExpansion<each T>(args: repeat each T, concrete: repeat First<Int, each T>) {}

0 commit comments

Comments
 (0)