@swift-ci Please test macOS
@swift-ci Please smoke test Linux
@eeckstein As far as I'm aware, our actual static
bridging functions (_forceBridgeFromObjectiveC
, _conditionallyBridgeFromObjectiveC
, and _unconditionallyBridgeFromObjectiveC
) should not require annotations as:
static func
s which have no local storage (or write out to inout
-params)func
s applies here — the params should not be ownedIs my understanding here correct?
Sorry, why is this specific to reference types? cc @airspeedswift
@jrose-apple Sorry, have I missed something here? Is this not inherently related to values which require reference counting?
"Values which require reference counting" isn't quite the same as "reference types". String and Array and Data all require reference counting too, right?
Ah, therein lies my misunderstanding about what was necessary here. I'll re-audit for those types as well.
Closing for now.
Build failed
Swift Test OS X Platform
Git Sha - 402457b
Made another pass here to add annotations to cover other non-trivial types. Will be doing another pass to confirm there's nothing I missed.
@swift-ci Please test macOS
@swift-ci Please smoke test Linux
Build failed
Swift Test OS X Platform
Git Sha - 402457b
@jrose-apple @eeckstein Do the changes here look correct? Does anything stand out as being out of place?
157 | 157 | } | |
158 | 158 | ||
159 | mutating func append(contentsOf other: [Int]) { | ||
159 | mutating func append(contentsOf other: __owned [Int]) { |
this probably isn't necessary since it's just [Int]
No, Array of Int is not a trivial type, i.e. involves reference counting of the array buffer.
Right, but IndexPath doesn't gain anything by taking the array owned, since it's not going to be able to use that buffer for storage, and the type isn't generic.
You are right, assuming that the case where self is empty and size of other > 2 is not the common case, it's better to pass other as guaranteed.
(I misread airspeedswift's comment: I though he meant that it's not worth annotating because of the parameter type).
Can you explain what the principles are for what is and isn't annotated? Since you're explicitly writing both __shared
and __owned
, I'd expect it to be
public
/@usableFromInline
functions and initializersand perhaps some of the non-public stuff as optimization hints. But I see public
functions where that hasn't been done, such as https://github.com/apple/swift/blob/9f042bc7c3452307b7929f5b76db5261b623d79a/stdlib/public/SDK/Foundation/Calendar.swift#L507.
107 | 107 | // MARK: Bridging | |
108 | 108 | ||
109 | fileprivate init(reference : NSCalendar) { | ||
109 | fileprivate init(reference : __shared NSCalendar) { |
This one should be owned
, no? Since you're immediately going to store it.
Although it's not a public entry point anyway, so it doesn't really matter.
_MutableHandle
makes a copy of the reference given to it so we never store the original — I've propagated __shared
out to every init(reference:)
which uses this, per @eeckstein's recommendation.
962 | 962 | /// Initializes `self` by referencing the given dictionary container in the given encoder. | |
963 | 963 | fileprivate init(referencing encoder: _JSONEncoder, | |
964 | key: CodingKey, convertedKey: CodingKey, wrapping dictionary: NSMutableDictionary) { | ||
964 | key: CodingKey, convertedKey: __shared CodingKey, wrapping dictionary: NSMutableDictionary) { |
I don't see why only the one parameter changed here.
This parameter is not stored; all others are. Based on your comments, it sounds to me like I've misunderstood something critical here. Let me start an email thread so we can sort this out.
1179 | 1179 | /// - parameter options: Options for the read operation. Default value is `[]`. | |
1180 | 1180 | /// - throws: An error in the Cocoa domain, if `url` cannot be read. | |
1181 | public init(contentsOf url: URL, options: Data.ReadingOptions = []) throws { | ||
1181 | public init(contentsOf url: __shared URL, options: __shared Data.ReadingOptions = []) throws { |
Data.ReadingOptions is an ObjC enum, right? So it shouldn't matter what ownership you use.
Sure — some of the changes here were mechanical, so I can pull this one out. I'm surprised the compiler didn't produce a warning/error in this case.
We haven't really talked about what form that'll take yet, but yeah, that's a reasonable idea. (You wouldn't necessarily want to do it to everything that's trivial, because a new version of the library might make it non-trivial, but that's not going to happen to an @objc
enum.)
@jrose-apple Sure — based on the guidelines I was given, I went ahead and annotated every function parameter which deviated from the default rules that I understand are in place (__shared
is assumed for all function parameters by default, __owned
is assumed for all init
parameters by default). Anything not annotated is meant to assume the default.
If it would be more helpful (or even necessary) to annotate all parameters regardless of the default, then I'm willing to go through and do that. Similarly, if I've misunderstood the guidelines (see rdar://problem/34989766 for discussion between between me and @eeckstein), happy to be corrected.
If it would be more helpful (or even necessary) to annotate all parameters regardless of the default
No, that's not necessary
I feel silly now. I didn't realize you were just annotating divergences from the default. Sorry for jumping in!
@swift-ci Please test macOS
@swift-ci Please smoke test Linux
Build failed
Swift Test OS X Platform
Git Sha - 9f042bc
Latest commit removes the unnecessary __shared
annotations on Data.ReadingOptions
and friends (which are Obj-C enums). If tests are green I'll merge.
@jrose-apple No worries at all, BTW — thanks for taking the time to review! Thanks @eeckstein for the help, too.
Login to write a write a comment.
What's in this pull request?
Annotates portions of the Foundation overlay with the appropriate
__shared
/__owned
annotations following the patterns we use (resolving rdar://problem/34989766). I looked at every declaredfunc
andinit
within our overlay and annotated all methods as appropriate. ~~~A search of all storedvar
s shows no necessary changes AFAICT as we don't expose reference types from our Swift APIs.~~~ (Sincevar
types cannot be annotated for ownership, there's nothing for us to do in the cases wherevar
s should be__shared
.)Overall the changes mostly revolve around bridging:
copy()
the passedNS
type before holding onto it as a reference to preserve value semantics, and in those cases, the parameter should be__shared
as we don't hold on to the original. (AFAIK,copy()
should help enforce the right refcounting in the case wherecopy()
returnsself
.)NS
type out of the Swift type via bridging (which copies as well) and hold on to theNS
typeThere are a few cases where
init
parameters go unused (such as inString.init?(contentsOf:)
), and some cases aroundKeyPath
where we appear to not store the givenKeyPath
but it actually ends up stored in a global table.