Skip to content

Commit 024efd2

Browse files
committed
SILGen: Don't emit key path property descriptors for properties in or of noncopyable types.
Key paths don't support them yet, and the current component representation is inadequate to handle them without requiring internal copying in all cases, so let's avoid generating invalid property descriptors for them today. rdar://111171284
1 parent 8f30a00 commit 024efd2

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

lib/SIL/IR/SIL.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,21 @@ bool AbstractStorageDecl::exportsPropertyDescriptor() const {
300300
// The storage needs a descriptor if it sits at a module's ABI boundary,
301301
// meaning it has public linkage.
302302

303+
// Noncopyable types aren't supported by key paths in their current form.
304+
// They would also need a new ABI that's yet to be implemented in order to
305+
// be properly supported, so let's suppress the descriptor for now if either
306+
// the container or storage type of the declaration is non-copyable.
307+
if (getValueInterfaceType()->isPureMoveOnly()) {
308+
return false;
309+
}
310+
if (!isStatic()) {
311+
if (auto contextTy = getDeclContext()->getDeclaredTypeInContext()) {
312+
if (contextTy->isPureMoveOnly()) {
313+
return false;
314+
}
315+
}
316+
}
317+
303318
// TODO: Global and static properties ought to eventually be referenceable
304319
// as key paths from () or T.Type too.
305320
if (!getDeclContext()->isTypeContext() || isStatic())
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-emit-silgen %s > %t/fragile-out.sil
3+
// %FileCheck --check-prefix=POS %s < %t/fragile-out.sil
4+
// %FileCheck --check-prefix=NEG %s < %t/fragile-out.sil
5+
// RUN: %target-swift-emit-silgen -enable-library-evolution %s > %t/resilient-out.sil
6+
// %FileCheck --check-prefix=POS %s < %t/resilient-out.sil
7+
// %FileCheck --check-prefix=NEG %s < %t/resilient-out.sil
8+
9+
@frozen
10+
public struct IsCopyable {
11+
public init() {}
12+
13+
// Shouldn't get a property descriptor since property type is noncopyable
14+
// NEG-NOT: sil_property #IsCopyable.noncopyable
15+
public var noncopyable: IsntCopyable {
16+
get { IsntCopyable() }
17+
set { }
18+
}
19+
20+
// Should get a property descriptor, copyable container and property
21+
// POS: sil_property #IsCopyable.copyable
22+
public var copyable: IsCopyable {
23+
get { IsCopyable() }
24+
set { }
25+
}
26+
27+
// Shouldn't get a property descriptor since it's static
28+
// NEG-NOT: sil_property #IsCopyable.staticCopyable
29+
public static var staticCopyable: IsCopyable = IsCopyable()
30+
31+
// Shouldn't get a property descriptor since it's static
32+
// NEG-NOT: sil_property #IsCopyable.staticNoncopyable
33+
public static var staticNoncopyable: IsntCopyable = IsntCopyable()
34+
}
35+
36+
@frozen
37+
public struct IsntCopyable: ~Copyable {
38+
public init() {}
39+
40+
// Shouldn't get a property descriptor since container and property type are both noncopyable
41+
// NEG-NOT: sil_property #IsntCopyable.noncopyable
42+
public var noncopyable: IsntCopyable {
43+
get { IsntCopyable() }
44+
set { }
45+
}
46+
47+
// Shouldn't get a property descriptor since container type is noncopyable
48+
// NEG-NOT: sil_property #IsntCopyable.copyable
49+
public var copyable: IsCopyable {
50+
get { IsCopyable() }
51+
set { }
52+
}
53+
54+
// Shouldn't get a property descriptor since it's static
55+
// NEG-NOT: sil_property #IsntCopyable.staticCopyable
56+
public static var staticCopyable: IsCopyable = IsCopyable()
57+
58+
// Shouldn't get a property descriptor since it's static
59+
// NEG-NOT: sil_property #IsntCopyable.staticNoncopyable
60+
public static var staticNoncopyable: IsntCopyable = IsntCopyable()
61+
}
62+
63+
// Shouldn't get a property descriptor since it's global
64+
// NEG-NOT: sil_property #{{.*}}globalCopyable
65+
public var globalCopyable: IsCopyable = IsCopyable()
66+
67+
// Shouldn't get a property descriptor since it's global
68+
// NEG-NOT: sil_property #{{.*}}globalNoncopyable
69+
public var globalNoncopyable: IsntCopyable = IsntCopyable()

0 commit comments

Comments
 (0)