Update for SE-0107: UnsafeRawPointer
This adds a "mutating" initialize to UnsafePointer to make
Immutable -> Mutable conversions explicit.
These are quick fixes to stdlib, overlays, and test cases that are necessary
in order to remove arbitrary UnsafePointer conversions.
Many cases can be expressed better up by reworking the surrounding
code, but we first need a working starting point.
This is another necessary step in introducing changes
for SE-0107: UnsafeRawPointer.
UnsafeRawPointer is great for bytewise pointer operations.
OpaquePointer goes away.
The _RawByte type goes away.
StringBuffer always binds memory to the correct CodeUnit
when allocating memory.
Before accessing the string, a dynamic element width check
allows us to assume the bound memory type.
Generic entry points like atomicCompareExchange no longer handle
both kinds of pointers. Normally that's good because you
should not be using generics in that case, just upcast
to raw pointer. However, with pointers-to-pointers
you can't do that.
It replaces String initializers taking Character or UnicodeScalar as a repeating value by a more general initializer that takes a String as a repeating value. This is done to avoid the ambiguities in the current String API, which can be only resolved by explicit casting.
String.append(_:UnicodeScalar) APIs is also removed to match these changes.
In various cases where we had global operators for non-generic
concrete types (such as String + String), move those operators into
the type. This should not affect the sources, but makes the exposition
of the library cleaner.
Plus, it's a good test for the compiler, which uncovered a few issues
where the compiler was coupled with the library.
change includes both the necessary protocol updates and the deprecation
warnings
suitable for migration. A future patch will remove the renamings and
make this
a hard error.
Added tests for expected-error and fix-its.
- Add arguments signature regardless that is the same as before.
Because the error message looks more natural.
e.g. "makeIterator" => "makeIterator()",
"replaceSubrange" => "replaceSubrange(_:with:)"
- Any${ExistentialCollection}.underestimateCount() was a method, not
computed property.
- 'LazySequenceType' has been renamed to 'LazySequenceProtocol', but not
'LazyCollectionProtocol'
- Streamable.writeTo(_:) had no argument label.
- Fixed typo in print() debugPrint() error message (not working for now)
- Repeated.init(): changed `renamed` to `message` because the arugment
order has changed.
- Marked `public` for some unavailable method on `Sequence`
- Sequence.split(_:maxSplit:allowEmptySlices) was replaced with
split(separator:maxSplits:omittingEmptySubsequences:),
not split(separator:omittingEmptySubsequences:isSeparator:)
- Sequence.split(_:allowEmptySlices:isSeparator) was replaced with
split(maxSplits:omittingEmptySubsequences:isSeparator:),
not split(_:omittingEmptySubsequences:isSeparator:)
- Sequence.startsWith(_:isEquivalent:) or startsWith(_:) had no label on
the first argument.
- transcode(_:_:_:_:stopOnError), not transcode(_:_:_:_:stoppingOnError)
- Removed mutating methods from UnsafePointer.
alloc(_:), dealloc(_:), setter:memory, initialize(_:), destroy(),
and destroy(_:)
This documentation revision covers a large number of types & protocols:
String, its views and their indices, the Unicode codec types and protocol,
as well as Character, UnicodeScalar, and StaticString, among others.
This also includes a few small changes across the standard library for
consistency.
The RangeProtocol was a very weak and fragile abstraction because it
didn't specify the interpretation of the endpoints. To write a
non-trivial algorithm, one usually needed to consult that information.
The standard library code only actually worked correctly with half-open
and closed ranges (and didn't handle fully open ranges, for example).
The other two protocols, HalfOpenRangeProtocol and ClosedRangeProtocol,
were only used for code sharing, and present an ABI burden. We can use
gyb instead.
Before,
* We had a generic implementation of replaceSubrange that would
satisfy the protocol's last non-defaulted requirement
* A generic removeSubrange was in the protocol requirements needlessly
* The default implementation of that generic removeSubrange dispatched
to replaceSubrange instead of the non-generic removeSubrange, robbing
the model of optimization opportunities.
Now,
* There's one non-generic replaceSubrange that models must implement.
* The default implementation of removeSubrange uses replaceSubrange to
do its work.
* Models can implement the non-generic removeSubrange if they can
implement it faster than the default implementation.
* The generic removeSubrange uses the non-generic removeSubrange to do
its work.
This is a staging attribute that will eventually mean "fixed-contents"
for structs and "closed" for enums, as described in
docs/LibraryEvolution.rst.
This is pretty much the minimal set of types that must be fixed-layout,
because SILGen makes assumptions about their lowering.
If desired, some SILGen refactoring can allow some of these to be
resilient. For example, bridging value types could be made to work
with resilient types.
Use it for hashing and comparison.
During String's hashValue and comparison function we create a
_NSContiguousString instance to call Foundation's hash/compare function. This is
expensive because we have allocate and deallocate a short lived object on the
heap (and deallocation for Swift objects is expensive). Instead help the
optimizer to allocate this object on the stack.
Introduces two functions on the internal _NSContiguousString:
_unsafeWithNotEscapedSelfPointer and _unsafeWithNotEscapedSelfPointerPair that
pass the _NSContiguousString instance as an opaque pointer to their closure
argument. Usage of these functions asserts that the closure will not escape
objects transitively reachable from the opaque pointer.
We then use those functions to call into the runtime to call foundation
functions on the passed strings. The optimizer can promote the strings to the
stack because of the assertion this API makes.
let lhsStr = _NSContiguousString(self._core) // will be promoted to the stack.
let rhsStr = _NSContiguousString(rhs._core) // will be promoted to the stack.
let res = lhsStr._unsafeWithNotEscapedSelfPointerPair(rhsStr) {
return _stdlib_compareNSStringDeterministicUnicodeCollationPointer($0, $1)
}
Tested by existing String tests.
We should see some nice performance improvements for string comparison and
dictionary benchmarks.
Here is what I measured at -O on my machine
Name Speedup
Dictionary 2.00x
Dictionary2 1.45x
Dictionary2OfObjects 1.20x
Dictionary3 1.50x
Dictionary3OfObjects 1.45x
DictionaryOfObjects 1.40x
SuperChars 1.60x
rdar://22173647