Skip to content

Commit b6d32c0

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 2211b2c commit b6d32c0

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
@@ -1960,6 +1960,14 @@ class DecodedMetadataBuilder {
19601960
TypeLookupErrorOr<BuiltType>
19611961
createTupleType(llvm::ArrayRef<BuiltType> elements,
19621962
llvm::ArrayRef<StringRef> labels) const {
1963+
// Unwrap unlabeled one-element tuples.
1964+
//
1965+
// FIXME: The behavior of one-element labeled tuples is inconsistent
1966+
// throughout the different re-implementations of type substitution
1967+
// and pack expansion.
1968+
if (elements.size() == 1 && labels[0].empty())
1969+
return elements[0];
1970+
19631971
for (auto element : elements) {
19641972
if (!element.isMetadata()) {
19651973
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"
@@ -21,3 +21,35 @@ public func foo<each T>(args: repeat each T) {
2121
// CHECK-DAG: ![[TYPE_PACK_TY]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "$sBpD"
2222
}
2323

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

0 commit comments

Comments
 (0)