-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Sema: Correct composition of property wrappers. #26326
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
Sema: Correct composition of property wrappers. #26326
Conversation
11b365e
to
cc94dd3
Compare
This reverts commit 5e08f7d.
cc94dd3
to
84ad55c
Compare
@swift-ci Please test |
// mutating-ness of either the getter or setter, since we need both to | ||
// perform a writeback cycle. | ||
case Mutating: | ||
if (Setter == DoesntExist) { |
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.
Does this need a special case? If the setter is DoesntExist
, std::max()
will always end up returning DoesntExist
, right?
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 suppose not. It seems worth calling this out as a specific rule, though.
Fixes rdar://problem/53407949 | SR-11138. Previously, we'd only look at the outermost property wrapper to decide whether the wrapped property's getter and setter were `mutating` (or exist at all). In reality, this requires considering the semantics of the composed accesses of each wrapper layer's `wrappedValue` property. Fixing this systematically addresses a number of issues: - As SR-11138 reported, composing a nonmutating-get-set wrapper ought to produce a composed wrapper that's nonmutating. - We would previously allow a property wrapper with a mutating getter to be nested inside one with only a getter, even though the resulting implementation was unsound (because there's no mutable context for the inner wrapper to execute its get on.) - Similarly, we would construct unsound setters in cases where the setter can't exist, such as when the nested wrapper isn't settable but the outer wrapper is.
84ad55c
to
fa4dd15
Compare
@swift-ci Please test |
Build failed |
Build failed |
@swift-ci Please test source compatibility |
Fixes rdar://problem/53407949 | SR-11138. Previously, we'd only look at the outermost property wrapper to decide whether the wrapped property's getter and setter were
mutating
(or exist at all). In reality, this requires considering the semantics of the composed accesses of each wrapper layer'swrappedValue
property. Fixing this systematically addresses a number of issues:As SR-11138 reported, composing a nonmutating-get-set wrapper ought to produce a composed wrapper that's nonmutating.
We would previously allow a property wrapper with a mutating getter to be nested inside one with only a getter, even though the resulting implementation was unsound (because there's no mutable context for the inner wrapper to execute its get on.)
Similarly, we would construct unsound setters in cases where the setter can't exist, such as when the nested wrapper isn't settable but the outer wrapper is.