Skip to content

Commit 31952cc

Browse files
authored
Merge pull request #66860 from jckarter/no-moveonly-property-descriptors
SILGen: Don't emit key path property descriptors for properties in or of noncopyable types.
2 parents 9da65ca + 024efd2 commit 31952cc

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)