Skip to content

Commit aaa800f

Browse files
DougGregorjckarter
authored andcommitted
[Opaque result types] Fix mangling issues with opaque result types.
Fix a trio of issues involving mangling for opaque result types: * Symbolic references to opaque type descriptors are not substitutions * Mangle protocol extension contexts correctly * Mangle generic arguments for opaque result types of generic functions The (de-)serialization of generic parameter lists for opaque type declarations is important for the last bullet, to ensure that the mangling of generic arguments of opaque result types works across module boundaries. Fixes the rest of rdar://problem/50038754.
1 parent b8915f6 commit aaa800f

File tree

8 files changed

+36
-7
lines changed

8 files changed

+36
-7
lines changed

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 486; // Last change: Opaque result types
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 487; // Last change: Opaque result types generic params
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1103,6 +1103,7 @@ namespace decls_block {
11031103
TypeIDField, // interface type for opaque type
11041104
GenericEnvironmentIDField, // generic environment
11051105
SubstitutionMapIDField // optional substitution map for underlying type
1106+
// trailed by generic parameters
11061107
>;
11071108

11081109
// TODO: remove the unnecessary FuncDecl components here

lib/AST/ASTMangler.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ void ASTMangler::appendType(Type type, const ValueDecl *forDecl) {
985985
// Use the fully elaborated explicit mangling.
986986
appendOpaqueDeclName(opaqueDecl);
987987
bool isFirstArgList = true;
988-
appendBoundGenericArgs(opaqueDecl->getInnermostDeclContext(),
988+
appendBoundGenericArgs(opaqueDecl,
989989
opaqueType->getSubstitutions(),
990990
isFirstArgList);
991991
appendRetroactiveConformances(opaqueType->getSubstitutions(),
@@ -1168,7 +1168,9 @@ unsigned ASTMangler::appendBoundGenericArgs(DeclContext *dc,
11681168
auto decl = dc->getInnermostDeclarationDeclContext();
11691169
if (!decl) return 0;
11701170

1171-
// For an extension declaration, use the nominal type declaration instead.
1171+
// For a non-protocol extension declaration, use the nominal type declaration
1172+
// instead.
1173+
//
11721174
// This is important when extending a nested type, because the generic
11731175
// parameters will line up with the (semantic) nesting of the nominal type.
11741176
if (auto ext = dyn_cast<ExtensionDecl>(decl))

lib/Demangling/Demangler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,8 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind,
690690
return nullptr;
691691

692692
// Types register as substitutions even when symbolically referenced.
693-
if (kind == SymbolicReferenceKind::Context)
693+
if (kind == SymbolicReferenceKind::Context &&
694+
resolved->getKind() != Node::Kind::OpaqueTypeDescriptorSymbolicReference)
694695
addSubstitution(resolved);
695696
return resolved;
696697
}

lib/Serialization/Deserialization.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,9 @@ class swift::DeclDeserializer {
31363136
sig, interfaceType);
31373137
declOrOffset = opaqueDecl;
31383138

3139+
if (auto genericParams = MF.maybeReadGenericParams(opaqueDecl))
3140+
opaqueDecl->setGenericParams(genericParams);
3141+
31393142
auto genericEnv = MF.getGenericEnvironment(genericEnvID);
31403143
opaqueDecl->setGenericEnvironment(genericEnv);
31413144
if (underlyingTypeID)

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,6 +3437,7 @@ void Serializer::writeDecl(const Decl *D) {
34373437
contextID, namingDeclID, interfaceSigID,
34383438
interfaceTypeID, genericEnvID,
34393439
underlyingTypeID);
3440+
writeGenericParams(opaqueDecl->getGenericParams());
34403441
break;
34413442
}
34423443

test/Interpreter/opaque_return_type_protocol_ext.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ protocol P {
66
func foo() -> AT
77
}
88

9+
struct Adapter<T: P>: P {
10+
var inner: T
11+
func foo() -> some P {
12+
return inner
13+
}
14+
}
15+
916
extension P {
1017
func foo() -> some P {
11-
return self
18+
return Adapter(inner: self)
1219
}
1320
}
1421

@@ -18,5 +25,5 @@ func getPAT<T: P>(_: T.Type) -> Any.Type {
1825

1926
extension Int: P { }
2027

21-
// CHECK: Int
28+
// CHECK: Adapter<Int>
2229
print(getPAT(Int.self))

test/Serialization/Inputs/OpaqueCrossFileB.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ public struct Subscript {
1919
return FooImpl()
2020
}
2121
}
22+
23+
extension Foo {
24+
public func identity<T>(_: T) -> some Foo {
25+
return self
26+
}
27+
}
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module-path %t/OpaqueCrossFileB.swiftmodule -module-name OpaqueCrossFileB %S/Inputs/OpaqueCrossFileB.swift
3-
// RUN: %target-swift-frontend -I %t -emit-ir -verify %s
3+
// RUN: %target-swift-frontend -I %t -emit-ir -verify %s | %FileCheck %s
44

55
import OpaqueCrossFileB
66

77
dump(anyFoo())
88
dump(anyFooProp)
99
dump(Subscript()[])
1010

11+
public struct UsesAdapterMethod: Foo {
12+
// Ensure that the mangling of the result type of adaptFoo correctly captures
13+
// both the Self type and the parameter type.
14+
// CHECK: @"symbolic _____y______SdQo_ 16OpaqueCrossFileB3FooPAAE8identityyQrqd__lFQO 17opaque_cross_file17UsesAdapterMethodV" =
15+
public func adaptFoo(_ d: Double) -> some Foo {
16+
return identity(d)
17+
}
18+
}

0 commit comments

Comments
 (0)