Even though `trackingLists.remove(_:)` returns a discardable result,
`withCriticalRegion` forwards that return value as its own return value, which
the compiler then flags as unused.
This is a partial revert to the dirty bit tracking since that has caused
runtime failures for existing applications. It may be resurrected later
once we can isolate the actual impact to behavior.
The internal dirty bit tracking state incorrectly flagged all changes as
participation when the mutation during observation occurred. This lead
to un-releated mutations filtering into same-isolation based changes
causing extra events to occur.
This is the implementation for
https://github.com/swiftlang/swift-evolution/blob/main/proposals/0506-advanced-observation-tracking.md
and additionally two bug fixes around termination events.
This adds two new entry points for tracking observations. One new
one-shot api that has a new options parameter for controlling events and
one new continuous form that is a callback version of Observations.
Bug fixes:
Previously `Observations` had a very small but still present window of
opportunity during deinitialization to miss an event and leave the
AsyncSequence never emitting a final event but never finishing.
Primarily this could occur when a weakly referenced `@Observable` type
was deinitialized from another isolation than the observation itself.
This current implementation leverages the new options parameter to
account for the deinitailization.
Both `Observations` and `withObservationTracking` where susceptible to a
very small race condition where there was a window of opportunity of a
secondary isolation to mutate a tracked property while the setup of the
observation was being called. Self isolation mutation during the setup
cannot be reported since that would distinctly cause recursive failures
in both observation based code but also code like SwiftUI using it so
the same isolation must be ignored, however external isolation changes
have now been addressed by verifying the tracking lists against the
potential "dirty-ness" of a property. This fixes
https://github.com/swiftlang/swift/issues/83359.
At the same time, drop that dependency in the new build system, so that
we don't add an additional linkage for Darwin platforms compared to what
we are doing in the current build system.
Addresses rdar://158313871
The pthread APIs on FreeBSD do not include nullability APIs so the
pthread mutex APIs are imported as pointers to optional values.
Other platforms include nullability APIs and import the pthread APIs as
pointers to the mutex. Splitting the locking primitive type based on the
OS.
Fixes: rdar://150880976
The runtime functions for locking end up referencing a symbol that is
not publicly emitted. This leads to broken linux builds.
Since that interface is not public and does not offer a stable mechanism
and Synchronization cannot be used (due to it being a higher deployment
target) instead it has to revert to implementing locking from scratch
for all platforms.
This is mostly replicated from the swift-async-algorithms package and
should be usable enough to accomplish the goals of this module.
Resolves rdar://150060874
* [Observation] ensure event triggers on deinitialziation passes as if all properties that are being observed have changed (for weak storage)
* Add missing deinitialize method for synthetically triggering willSet
* Correct the weak location for tests
* Correct the test to actually test the deinitialization willSet trigger instead of testing weak value deinitialization time
* Refine the tests for deinit triggers to more tightly trigger deinitialization and weak references
* Correct missing trailing closure on deinit replacement
* Ensure all potential ids are triggered at the deinitialization edge trigger
This entails passing a linker flags to Apple linkers when the standard
library is not meant for inclusion in such cache.
For this to have effect on every library, propagate link flags when
building _Concurrency and Observation.
This is needed for Apple internal configurations.
Addresses rdar://120653968
* [Observation] Correct tracking such that recursive but disperate changes can be tracked without crashing
* [Observation] Adjust the SPI interface for tracking to support deferred cancellation of events and handle both willSet and didSet events
This adopts `@attached(peer)` for generating an observable type's
underscored storage when expanding the `@ObservationTracked` macro,
instead of using `arbitrary` with the member macro on the
observable type.
With support for redundant conformance declarations via macros,
the `Observable` protocol can be a non-marker protocol, which
provides more flexibility for evolution in the future.
rdar://111463883
This change also switches to the new ExtensionMacro protocol,
the requirement for which includes information about whether the
conformance to the Observable protocol has already been added, either
in the declaration or in a superclass to the macro-attributed type.
This allows the @Observable macro to be applied to subclasses of
observable types without redundant-conformance errors.
* Make ObservationRegistrar Codable/Hashable
These conformances enable automatic Codable synthesis for Observable
types, and smooth the runway for structs being supported by the
Observable macro in the future.
* Limit Observable macro to classes
This removes the ability for the Observable macro to apply to structs,
and adds diagnostic tests for the three disallowed declaration kinds.
The review of SE-0395 is down to small details at this point that won't
affect the overall shape of the API much. Rename the model in
anticipation of that.
Now that we've made accessor macro expansion more lazy, ensure that
when querying for init accessors (e.g., to build a memberwise
initializer), we also expand any accessor macros that might produce an
init accessor.
This is a partial step toward the real goal, which is that
`AbstractStorageDecl::getAccessor()` should lazily expand macros if
needed.
Update the Observable macro to document that it produces an `init`
accessor.
The `hasStorage()` computation is used in many places to determine the
signatures of other declarations. It currently needs to expand accessor
macros, which causes a number of cyclic references. Provide a
simplified request to determine `hasStorage` without expanding or
resolving macros, breaking a common pattern of cycles when using
macros.
Fixes rdar://109668383.
* [Observation] Transition to peer macros instead of arbitrary members
* [Observation] Lift the initializer requirement by utilizing init accessors for fully formed definite initialization
* [Observation] Gate enabling of peer macros by flag
* [Observation] Enable feature for InitAccessors in the observation tests
* [Observation] Add tests to validate memberwise and definite initialization
* [Observation] Change visibility of observation runtime functions to be hidden
* [Observation] Update API requirements for Observable AsyncSequence names and alter the behavior of value emissions to be based upon transactionality
* [Observation] Slight naming alteration of isolation -> isolatedTo
Note: This re-enables the previously disabled tests since the implementation should be considerably more robust to hangs.