diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index 05faa339c7bcd..e6e9d88ad148d 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -1052,13 +1052,6 @@ class TypeDecoder { return *optError; } - // Unwrap unlabeled one-element tuples. - // - // FIXME: The behavior of one-element labeled tuples is inconsistent throughout - // the different re-implementations of type substitution and pack expansion. - if (elements.size() == 1 && labels[0].empty()) - return elements[0]; - return Builder.createTupleType(elements, labels); } case NodeKind::TupleElement: diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index c1763725e591a..18a96779033c4 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -328,6 +328,17 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, } Type ASTBuilder::createTupleType(ArrayRef eltTypes, ArrayRef labels) { + // Unwrap unlabeled one-element tuples. + // + // FIXME: The behavior of one-element labeled tuples is inconsistent + // throughout the different re-implementations of type substitution + // and pack expansion. + if (eltTypes.size() == 1 && + !eltTypes[0]->is() && + labels[0].empty()) { + return eltTypes[0]; + } + SmallVector elements; elements.reserve(eltTypes.size()); for (unsigned i : indices(eltTypes)) { diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index ada38eaef3b4b..6c63fccd8cd25 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -1965,6 +1965,14 @@ class DecodedMetadataBuilder { TypeLookupErrorOr createTupleType(llvm::ArrayRef elements, llvm::ArrayRef labels) const { + // Unwrap unlabeled one-element tuples. + // + // FIXME: The behavior of one-element labeled tuples is inconsistent + // throughout the different re-implementations of type substitution + // and pack expansion. + if (elements.size() == 1 && labels[0].empty()) + return elements[0]; + for (auto element : elements) { if (!element.isMetadata()) { return TYPE_LOOKUP_ERROR_FMT("Tried to build a tuple type where " diff --git a/test/DebugInfo/variadic-generics.swift b/test/DebugInfo/variadic-generics.swift index 9e44fded24f46..802c8273a4743 100644 --- a/test/DebugInfo/variadic-generics.swift +++ b/test/DebugInfo/variadic-generics.swift @@ -1,5 +1,5 @@ // RUN: %target-swift-frontend -emit-ir %s -g -o - \ -// RUN: -parse-as-library -module-name a | %IRGenFileCheck %s +// RUN: -parse-as-library -module-name a -disable-availability-checking | %IRGenFileCheck %s public func foo(args: repeat each T) { // CHECK: define {{.*}} @"$s1a3foo4argsyxxQp_tRvzlF" @@ -22,3 +22,35 @@ public func foo(args: repeat each T) { // CHECK-DAG: ![[TYPE_PACK_TY]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "$sBpD" } +// Test ASTDemangler round-tripping of various pack expansion types + +public func paramExpansionWithPattern(args: repeat Array) {} + +public func paramExpansionWithMemberType(args: repeat each T, elements: repeat (each T).Element) {} + +public func tupleExpansion(args: (repeat each T)) {} + +public func tupleExpansionWithPattern(args: (repeat Array)) {} + +// FIXME: Crashes due to unrelated bug +// public func tupleExpansionWithMemberType(args: repeat each T, elements: (repeat (each T).Element)) {} + +public func functionExpansion(args: (repeat each T) -> ()) {} + +public func functionExpansionWithPattern(args: (repeat Array) -> ()) {} + +public func functionExpansionWithMemberType(args: repeat each T, elements: (repeat (each T).Element) -> ()) {} + +public struct G {} + +public func nominalExpansion(args: G) {} + +public func nominalExpansionWithPattern(args: G>) {} + +public func nominalExpansionWithMemberType(args: repeat each T, elements: G) {} + +// + +public typealias First = T + +public func concreteExpansion(args: repeat each T, concrete: repeat First) {}