-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SILGen: Fix setting variables with property wrappers marked objc dynamic #27516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SILGen: Fix setting variables with property wrappers marked objc dynamic #27516
Conversation
@swift-ci Please test |
@@ -1430,7 +1430,14 @@ namespace { | |||
|
|||
// Create the allocating setter function. It captures the base address. | |||
auto setterInfo = SGF.getConstantInfo(setter); | |||
SILValue setterFRef = SGF.emitGlobalFunctionRef(loc, setter, setterInfo); | |||
SILValue setterFRef; | |||
if (setter.hasDecl() && setter.getDecl()->isObjCDynamic()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the setter be a class method or a witness method also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, this code is for property wrapped vars.
This:
class SomeWrapperTests {
@SomeWrapper var someWrapper: Int = 0
will just emit a function ref.
I am guessing we treat this like stored properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Property-wrapped vars should definitely be overridable in subclasses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, then the code before this patch is broken:
@propertyWrapper
public struct SomeWrapper {
private var value: Int
public init(wrappedValue: Int) {
value = wrappedValue
}
public var wrappedValue: Int {
get { value }
set { value = newValue }
}
}
SILGen will emit a direct function_ref and not a class_method call for the setter in the example below:
class SomeWrapperTests {
@SomeWrapper var someWrapper: Int = 0
func testAssignment() {
someWrapper = 1000
}
}
sil hidden [ossa] @$s7Wrapper04SomeA5TestsC14testAssignmentyyF : $@convention(method) (@guaranteed SomeWrapperTests) -> () {
// %0 // users: %12, %6, %1
bb0(%0 : @guaranteed $SomeWrapperTests):
...
%9 = function_ref @$s7Wrapper04SomeA0V12wrappedValueACSi_tcfCTc : $@convention(thin) (@thin SomeWrapper.Type) -> @owned @callee_guaranteed (Int) -> SomeWrapper
%10 = apply %9(%8) : $@convention(thin) (@thin SomeWrapper.Type) -> @owned @callee_guaranteed (Int) -> SomeWrapper
// function_ref SomeWrapperTests.someWrapper.setter
%11 = function_ref @$s7Wrapper04SomeA5TestsC04someA0Sivs : $@convention(method) (Int, @guaranteed SomeWrapperTests) -> ()
%12 = copy_value %0 : $SomeWrapperTests
%13 = partial_apply [callee_guaranteed] %11(%12) : $@convention(method) (Int, @guaranteed SomeWrapperTests) -> ()
assign_by_wrapper %5 : $Int to %7 : $*SomeWrapper, init %10 : $@callee_guaranteed (Int) -> SomeWrapper, set %13 : $@callee_guaranteed (Int) -> ()
end_access %7 : $*SomeWrapper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yikes! We should fix that too, then. :-) I guess I'll file a separate Radar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed SR-11571, soon to be cloned.
rdar://54181647