Skip to content

Commit b00315b

Browse files
committed
[5.1] IRGen: Save the current generic signature before mangling an opaque type decl
It comes with its own generic signature. Explanation: We crash generating the mangling for an opaque type decl. Scope of Issue: Affects code that uses opaque result types. The compiler will crash. Risk: Low. We cache and restore a generic signature before mangling opaque type decls which will introduce their own generic signature. Review: Joe Groff Testing: Swift regression test added. rdar://54824119
1 parent 1880eb0 commit b00315b

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,9 @@ void ASTMangler::appendOpaqueDeclName(const OpaqueTypeDecl *opaqueDecl) {
735735
if (canSymbolicReference(opaqueDecl)) {
736736
appendSymbolicReference(opaqueDecl);
737737
} else if (auto namingDecl = opaqueDecl->getNamingDecl()) {
738+
CanGenericSignature savedSignature = CurGenericSignature;
738739
appendEntity(namingDecl);
740+
CurGenericSignature = savedSignature;
739741
appendOperator("QO");
740742
} else {
741743
llvm_unreachable("todo: independent opaque type decls");
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
public protocol Proto {
2+
associatedtype Assoc : Proto
3+
var value: Assoc { get }
4+
}
5+
6+
extension Never : Proto {}
7+
8+
extension Never {
9+
public typealias Assoc = Never
10+
11+
public var value: Never {
12+
switch self {}
13+
}
14+
}
15+
protocol PrimitiveProto : Proto {}
16+
17+
extension PrimitiveProto {
18+
public var value: Never { valueError() }
19+
}
20+
21+
extension Proto {
22+
func valueError() -> Never {
23+
fatalError("value() should not be called on \(Self.self).")
24+
}
25+
}
26+
27+
public struct EmptyProto : PrimitiveProto {
28+
public init() {}
29+
}
30+
31+
struct M<Content: Proto> : Proto {
32+
var t: Content
33+
34+
init(_ t: Content) {
35+
self.t = t
36+
}
37+
38+
var value: some Proto {
39+
return t.value
40+
}
41+
}
42+
43+
public struct Group<T> {
44+
var t: T
45+
46+
public init(_ t: T) {
47+
self.t = t
48+
}
49+
}
50+
51+
extension Group : Proto, PrimitiveProto where T : Proto {
52+
public typealias Assoc = Never
53+
}
54+
55+
public struct Choice<T, V>{
56+
var v: V
57+
58+
public init(_ t: T, _ v: V) {
59+
self.v = v
60+
}
61+
}
62+
63+
extension Choice : Proto where T: Proto, V: Proto {
64+
public var value: some Proto {
65+
return v.value
66+
}
67+
}
68+
69+
extension Proto {
70+
public func add() -> some Proto {
71+
return M(self)
72+
}
73+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -disable-availability-checking -emit-module -enable-library-evolution -emit-module-path=%t/A.swiftmodule -module-name=A %S/Inputs/mangle-opaque-return-types-A.swift
3+
// RUN: %target-swift-frontend -disable-availability-checking -I %t -emit-ir %s
4+
import A
5+
6+
public struct C<T, Content: Proto> {
7+
let data: T
8+
let content: Content
9+
10+
init(_ t: T, _ c: Content) {
11+
data = t
12+
content = c
13+
}
14+
15+
public var dontCrash : some Proto {
16+
return Group(Choice(content, EmptyProto().add()))
17+
}
18+
}
19+

0 commit comments

Comments
 (0)