Skip to content

Commit fb388fb

Browse files
authored
Merge pull request #31059 from slavapestov/fix-property-wrapper-vtable-layout-with-subclass-5.2
Sema: Force property wrappers in EmittedMembersRequest::evaluate() [5.2]
2 parents 029130b + 12f15b6 commit fb388fb

File tree

6 files changed

+93
-1
lines changed

6 files changed

+93
-1
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,6 +2374,14 @@ EmittedMembersRequest::evaluate(Evaluator &evaluator,
23742374
forceConformance(Context.getProtocol(KnownProtocolKind::Encodable));
23752375
forceConformance(Context.getProtocol(KnownProtocolKind::Hashable));
23762376

2377+
// The projected storage wrapper ($foo) might have dynamically-dispatched
2378+
// accessors, so force them to be synthesized.
2379+
for (auto *member : CD->getMembers()) {
2380+
if (auto *var = dyn_cast<VarDecl>(member))
2381+
if (var->hasAttachedPropertyWrapper())
2382+
(void) var->getPropertyWrapperBackingProperty();
2383+
}
2384+
23772385
return CD->getMembers();
23782386
}
23792387

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
public class MyClass {
2+
public init() { }
3+
4+
@PropertyWrapper()
5+
public var instanceProperty: Bool
6+
}
7+
8+
@propertyWrapper
9+
public struct PropertyWrapper {
10+
public init() { }
11+
12+
public var projectedValue: PropertyWrapper {
13+
get {
14+
return self
15+
}
16+
set {
17+
self = newValue
18+
}
19+
}
20+
21+
public var wrappedValue: Bool {
22+
return false
23+
}
24+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-emit-silgen -primary-file %s %S/Inputs/property_wrappers_multifile_other.swift | %FileCheck %s
2+
3+
public class YourClass : MyClass {}
4+
5+
// CHECK-LABEL: sil_vtable [serialized] YourClass {
6+
// CHECK-NEXT: #MyClass.init!allocator.1: (MyClass.Type) -> () -> MyClass : @$s27property_wrappers_multifile9YourClassCACycfC [override]
7+
// CHECK-NEXT: #MyClass.instanceProperty!getter.1: (MyClass) -> () -> Bool : @$s27property_wrappers_multifile7MyClassC16instancePropertySbvg [inherited]
8+
// CHECK-NEXT: #MyClass.$instanceProperty!getter.1: (MyClass) -> () -> PropertyWrapper : @$s27property_wrappers_multifile7MyClassC17$instancePropertyAA0G7WrapperVvg [inherited]
9+
// CHECK-NEXT: #MyClass.$instanceProperty!setter.1: (MyClass) -> (PropertyWrapper) -> () : @$s27property_wrappers_multifile7MyClassC17$instancePropertyAA0G7WrapperVvs [inherited]
10+
// CHECK-NEXT: #MyClass.$instanceProperty!modify.1: (MyClass) -> () -> () : @$s27property_wrappers_multifile7MyClassC17$instancePropertyAA0G7WrapperVvM [inherited]
11+
// CHECK-NEXT: #YourClass.deinit!deallocator.1: @$s27property_wrappers_multifile9YourClassCfD
12+
// CHECK-NEXT: }
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
public class MyClass {
2+
public init() { }
3+
4+
@PropertyWrapper(defaultValue: false)
5+
public var wrappedProperty: Bool
6+
7+
public func check() {
8+
let foo = $wrappedProperty
9+
$wrappedProperty = foo
10+
}
11+
}
12+
13+
@propertyWrapper
14+
public struct PropertyWrapper<Value> {
15+
public let defaultValue: Value
16+
17+
public var projectedValue: PropertyWrapper<Value> {
18+
get {
19+
return self
20+
}
21+
set {
22+
self = newValue
23+
}
24+
}
25+
26+
public var wrappedValue: Value {
27+
return defaultValue
28+
}
29+
30+
public init(defaultValue: Value) {
31+
self.defaultValue = defaultValue
32+
}
33+
}

test/multifile/Inputs/sr12429.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public struct PropertyWrapper<Value> {
2626
get {
2727
return self
2828
}
29-
// Having this setter is what causes the mis-compilation
3029
set {
3130
self = newValue
3231
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: cp %s %t/main.swift
3+
// RUN: %target-build-swift -o %t/main %t/main.swift %S/Inputs/rdar61229365.swift
4+
// RUN: %target-codesign %t/main
5+
// RUN: %target-run %t/main
6+
7+
// REQUIRES: executable_test
8+
9+
class YourClass : MyClass {
10+
override init() {
11+
super.init()
12+
}
13+
}
14+
15+
let object = YourClass()
16+
object.check()

0 commit comments

Comments
 (0)