Skip to content

Commit 781f632

Browse files
committed
[stdlib] Various documentation revisions and fixes
- Revisions to unsafeDowncast and withVaList - Fix the Int64/UInt64 discussion - Buffer pointer revisions - Fix Optional example to use new integer methods - Revise and correct some UnsafeRawBufferPointer docs - Fix symmetricDifference examples - Fix wording in FloatingPoint.nextDown - Update ImplicitlyUnwrappedOptional - Clarify elementsEqual - Minor integer doc fixes - Comment for _AppendKeyPath - Clarification re collection indices - Revise RangeExpression.relative(to:) - Codable revisions
1 parent a24a439 commit 781f632

15 files changed

+282
-192
lines changed

stdlib/public/core/Builtin.swift

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -246,18 +246,26 @@ public func _unsafeReferenceCast<T, U>(_ x: T, to: U.Type) -> U {
246246
return Builtin.castReference(x)
247247
}
248248

249-
/// - returns: `x as T`.
249+
/// Returns the given instance cast unconditionally to the specified type.
250250
///
251-
/// - Precondition: `x is T`. In particular, in -O builds, no test is
252-
/// performed to ensure that `x` actually has dynamic type `T`.
251+
/// The instance passed as `x` must be an instance of type `T`.
253252
///
254-
/// - Warning: Trades safety for performance. Use `unsafeDowncast`
255-
/// only when `x as! T` has proven to be a performance problem and you
256-
/// are confident that, always, `x is T`. It is better than an
257-
/// `unsafeBitCast` because it's more restrictive, and because
258-
/// checking is still performed in debug builds.
253+
/// Use this function instead of `unsafeBitcast(_:to:)` because this function
254+
/// is more restrictive and still performs a check in debug builds. In -O
255+
/// builds, no test is performed to ensure that `x` actually has the dynamic
256+
/// type `T`.
257+
///
258+
/// - Warning: This function trades safety for performance. Use
259+
/// `unsafeDowncast(_:to:)` only when you are confident that `x is T` always
260+
/// evaluates to `true`, and only after `x as! T` has proven to be a
261+
/// performance problem.
262+
///
263+
/// - Parameters:
264+
/// - x: An instance to cast to type `T`.
265+
/// - type: The type `T` to which `x` is cast.
266+
/// - Returns: The instance `x`, cast to type `T`.
259267
@_transparent
260-
public func unsafeDowncast<T : AnyObject>(_ x: AnyObject, to: T.Type) -> T {
268+
public func unsafeDowncast<T : AnyObject>(_ x: AnyObject, to type: T.Type) -> T {
261269
_debugPrecondition(x is T, "invalid unsafeDowncast")
262270
return Builtin.castReference(x)
263271
}
@@ -337,7 +345,6 @@ func swift_class_getInstanceExtents(_ theClass: AnyClass)
337345
func swift_objc_class_unknownGetInstanceExtents(_ theClass: AnyClass)
338346
-> (negative: UInt, positive: UInt)
339347

340-
/// - Returns:
341348
@inline(__always)
342349
internal func _class_getInstancePositiveExtentSize(_ theClass: AnyClass) -> Int {
343350
#if _runtime(_ObjC)

stdlib/public/core/Codable.swift

Lines changed: 69 additions & 73 deletions
Large diffs are not rendered by default.

stdlib/public/core/Collection.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -445,18 +445,6 @@ public struct IndexingIterator<
445445
/// corresponding element. In the example above, `firstSpace` is used to
446446
/// extract the prefix that contains elements up to that index.
447447
///
448-
/// You can pass only valid indices to collection operations. You can find a
449-
/// complete set of a collection's valid indices by starting with the
450-
/// collection's `startIndex` property and finding every successor up to, and
451-
/// including, the `endIndex` property. All other values of the `Index` type,
452-
/// such as the `startIndex` property of a different collection, are invalid
453-
/// indices for this collection.
454-
///
455-
/// Saved indices may become invalid as a result of mutating operations. For
456-
/// more information about index invalidation in mutable collections, see the
457-
/// reference for the `MutableCollection` and `RangeReplaceableCollection`
458-
/// protocols, as well as for the specific type you're using.
459-
///
460448
/// Accessing Individual Elements
461449
/// =============================
462450
///
@@ -481,6 +469,18 @@ public struct IndexingIterator<
481469
/// print(text.first)
482470
/// // Prints "Optional("B")"
483471
///
472+
/// You can pass only valid indices to collection operations. You can find a
473+
/// complete set of a collection's valid indices by starting with the
474+
/// collection's `startIndex` property and finding every successor up to, and
475+
/// including, the `endIndex` property. All other values of the `Index` type,
476+
/// such as the `startIndex` property of a different collection, are invalid
477+
/// indices for this collection.
478+
///
479+
/// Saved indices may become invalid as a result of mutating operations. For
480+
/// more information about index invalidation in mutable collections, see the
481+
/// reference for the `MutableCollection` and `RangeReplaceableCollection`
482+
/// protocols, as well as for the specific type you're using.
483+
///
484484
/// Accessing Slices of a Collection
485485
/// ================================
486486
///

stdlib/public/core/FloatingPoint.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ public protocol FloatingPoint: SignedNumeric, Strideable, Hashable {
10051005

10061006
/// The greatest representable value that compares less than this value.
10071007
///
1008-
/// For any finite value `x`, `x.nextDown` is greater than `x`. For `nan` or
1008+
/// For any finite value `x`, `x.nextDown` is less than `x`. For `nan` or
10091009
/// `-infinity`, `x.nextDown` is `x` itself. The following special cases
10101010
/// also apply:
10111011
///

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,9 +1120,8 @@ public struct Set<Element : Hashable> :
11201120
/// In the following example, the elements of the `employees` set that are
11211121
/// also members of `neighbors` are removed from `employees`, while the
11221122
/// elements of `neighbors` that are not members of `employees` are added to
1123-
/// `employees`. In particular, the names `"Alicia"`, `"Chris"`, and
1124-
/// `"Diana"` are removed from `employees` while the name `"Forlani"` is
1125-
/// added.
1123+
/// `employees`. In particular, the names `"Bethany"` and `"Eric"` are
1124+
/// removed from `employees` while the name `"Forlani"` is added.
11261125
///
11271126
/// var employees: Set = ["Alicia", "Bethany", "Diana", "Eric"]
11281127
/// let neighbors = ["Bethany", "Eric", "Forlani"]

stdlib/public/core/ImplicitlyUnwrappedOptional.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@
1212

1313
/// An optional type that allows implicit member access.
1414
///
15-
/// *Deprecated.*
15+
/// The `ImplicitlyUnwrappedOptional` type is deprecated. To create an optional
16+
/// value that is implicitly unwrapped, place an exclamation mark (`!`) after
17+
/// the type that you want to denote as optional.
18+
///
19+
/// // An implicitly unwrapped optional integer
20+
/// let guaranteedNumber: Int! = 6
21+
///
22+
/// // An optional integer
23+
/// let possibleNumber: Int? = 5
1624
@_fixed_layout
1725
public enum ImplicitlyUnwrappedOptional<Wrapped> : ExpressibleByNilLiteral {
1826
// The compiler has special knowledge of the existence of

stdlib/public/core/Integers.swift.gyb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,9 @@ public protocol BinaryInteger :
13351335
/// Creates an integer from the given floating-point value, rounding toward
13361336
/// zero.
13371337
///
1338+
/// Any fractional part of the value passed as `source` is removed, rounding
1339+
/// the value toward zero.
1340+
///
13381341
/// let x = Int(21.5)
13391342
/// // x == 21
13401343
/// let y = Int(-21.5)
@@ -1347,7 +1350,8 @@ public protocol BinaryInteger :
13471350
/// // Error: ...the result would be less than UInt.min
13481351
///
13491352
/// - Parameter source: A floating-point value to convert to an integer.
1350-
/// `source` must be representable in this type after rounding toward zero.
1353+
/// `source` must be representable in this type after rounding toward
1354+
/// zero.
13511355
init<T : BinaryFloatingPoint>(_ source: T)
13521356

13531357
/// Creates a new instance from the given integer.
@@ -2502,7 +2506,7 @@ extension SignedInteger where Self : FixedWidthInteger {
25022506
% z = 's' if signed else 'z'
25032507

25042508
% Article = 'An' if bits == 8 else 'A'
2505-
% if bits == word_bits:
2509+
% if self_type.is_word:
25062510
/// ${'A ' if signed else 'An un'}signed integer value type.
25072511
///
25082512
/// On 32-bit platforms, `${Self}` is the same size as `${Self}32`, and

stdlib/public/core/KeyPath.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,9 @@ func _projectKeyPathReferenceWritable<Root, Value>(
13471347
// constrained by being overrides, and so that we can use exact-type constraints
13481348
// on `Self` to prevent dynamically-typed methods from being inherited by
13491349
// statically-typed key paths.
1350+
1351+
/// This protocol is an implementation detail of key path expressions; do not
1352+
/// use it directly.
13501353
@_show_in_interface
13511354
public protocol _AppendKeyPath {}
13521355

stdlib/public/core/Optional.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ public enum Optional<Wrapped> : ExpressibleByNilLiteral {
178178
///
179179
/// let possibleNumber: Int? = Int("42")
180180
/// let nonOverflowingSquare = possibleNumber.flatMap { x -> Int? in
181-
/// let (result, overflowed) = Int.multiplyWithOverflow(x, x)
182-
/// return overflowed ? nil : result
181+
/// let (result, overflowed) = x.multipliedReportingOverflow(by: x)
182+
/// return overflowed == .overflow ? nil : result
183183
/// }
184184
/// print(nonOverflowingSquare)
185185
/// // Prints "Optional(1764)"

stdlib/public/core/Range.swift.gyb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,39 @@ public protocol RangeExpression {
1818
/// Returns the range of indices within the given collection described by
1919
/// this range expression.
2020
///
21+
/// You can use the `relative(to:)` method to convert a range expression,
22+
/// which could be missing one or both of its endpoints, into a concrete
23+
/// range that is bounded on both sides. The following example uses this
24+
/// method to convert a partial range up to `4` into a half-open range,
25+
/// using an array instance to add the range's lower bound.
26+
///
27+
/// let numbers = [10, 20, 30, 40, 50, 60, 70]
28+
/// let upToFour = ..<4
29+
///
30+
/// let r1 = upToFour.relative(to: numbers)
31+
/// // r1 == 0..<4
32+
///
33+
/// The `r1` range is bounded on the lower end by `0` because that is the
34+
/// starting index of the `numbers` array. When the collection passed to
35+
/// `relative(to:)` starts with a different index, that index is used as the
36+
/// lower bound instead. The next example creates a slice of `numbers`
37+
/// starting at index `2`, and then uses the slice with `relative(to:)` to
38+
/// convert `upToFour` to a concrete range.
39+
///
40+
/// let numbersSuffix = numbers[2...]
41+
/// // numbersSuffix == [30, 40, 50, 60, 70]
42+
///
43+
/// let r2 = upToFour.relative(to: numbersSuffix)
44+
/// // r2 == 2..<4
45+
///
46+
/// Use this method only if you need the concrete range it produces. To
47+
/// access a slice of a collection using a range expression, use the
48+
/// collection's generic subscript that uses a range expression as its
49+
/// parameter.
50+
///
51+
/// let numbersPrefix = numbers[upToFour]
52+
/// // numbersPrefix == [10, 20, 30, 40]
53+
///
2154
/// - Parameter collection: The collection to evaluate this range expression
2255
/// in relation to.
2356
/// - Returns: A range suitable for slicing `collection`. The returned range

stdlib/public/core/SequenceAlgorithms.swift.gyb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ extension Sequence ${"" if preds else "where Element : Equatable"} {
301301
302302
% if preds:
303303
/// Returns a Boolean value indicating whether this sequence and another
304-
/// sequence contain equivalent elements, using the given predicate as the
305-
/// equivalence test.
304+
/// sequence contain equivalent elements in the same order, using the given
305+
/// predicate as the equivalence test.
306306
///
307307
/// At least one of the sequences must be finite.
308308
///

stdlib/public/core/SetAlgebra.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,15 +276,14 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
276276
/// In the following example, the elements of the `employees` set that are
277277
/// also members of `neighbors` are removed from `employees`, while the
278278
/// elements of `neighbors` that are not members of `employees` are added to
279-
/// `employees`. In particular, the names `"Alicia"`, `"Chris"`, and
280-
/// `"Diana"` are removed from `employees` while the names `"Forlani"` and
281-
/// `"Greta"` are added.
279+
/// `employees`. In particular, the names `"Bethany"` and `"Eric"` are
280+
/// removed from `employees` while the name `"Forlani"` is added.
282281
///
283-
/// var employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
284-
/// let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
282+
/// var employees: Set = ["Alicia", "Bethany", "Diana", "Eric"]
283+
/// let neighbors: Set = ["Bethany", "Eric", "Forlani"]
285284
/// employees.formSymmetricDifference(neighbors)
286285
/// print(employees)
287-
/// // Prints "["Diana", "Chris", "Forlani", "Alicia", "Greta"]"
286+
/// // Prints "["Diana", "Forlani", "Alicia"]"
288287
///
289288
/// - Parameter other: A set of the same type.
290289
mutating func formSymmetricDifference(_ other: Self)

stdlib/public/core/UnsafeBufferPointer.swift.gyb

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,23 @@ public struct Unsafe${Mutable}BufferPointer<Element>
306306
% if not Mutable:
307307
/// Creates a buffer over the same memory as the given buffer slice.
308308
///
309-
/// The new buffer will represent the same region of memory as the slice,
310-
/// but it's indices will be rebased to zero. Given:
309+
/// The new buffer represents the same region of memory as `slice`, but is
310+
/// indexed starting at zero instead of sharing indices with the original
311+
/// buffer. For example:
311312
///
312-
/// let slice = buffer[n..<m]
313-
/// let rebased = UnsafeBufferPointer(rebasing: slice)
313+
/// let buffer = returnsABuffer()
314+
/// let n = 5
315+
/// let slice = buffer[n...]
316+
/// let rebased = UnsafeBufferPointer(rebasing: slice)
314317
///
315-
/// One may assume `rebased.startIndex == 0` and `rebased[0] == slice[n]`.
318+
/// After rebasing `slice` as the `rebased` buffer, the following are true:
316319
///
317-
/// - Parameter slice: the raw buffer slice to rebase.
320+
/// - `rebased.startIndex == 0`
321+
/// - `rebased[0] == slice[n]`
322+
/// - `rebased[0] == buffer[n]`
323+
/// - `rebased.count == slice.count`
324+
///
325+
/// - Parameter slice: The buffer slice to rebase.
318326
@_inlineable
319327
public init(rebasing slice: RandomAccessSlice<UnsafeBufferPointer<Element>>) {
320328
self.init(start: slice.base.baseAddress! + slice.startIndex,
@@ -324,15 +332,23 @@ public struct Unsafe${Mutable}BufferPointer<Element>
324332

325333
/// Creates a buffer over the same memory as the given buffer slice.
326334
///
327-
/// The new buffer will represent the same region of memory as the slice,
328-
/// but it's indices will be rebased to zero. Given:
335+
/// The new buffer represents the same region of memory as `slice`, but is
336+
/// indexed starting at zero instead of sharing indices with the original
337+
/// buffer. For example:
338+
///
339+
/// let buffer = returnsABuffer()
340+
/// let n = 5
341+
/// let slice = buffer[n...]
342+
/// let rebased = Unsafe${Mutable}BufferPointer(rebasing: slice)
329343
///
330-
/// let slice = buffer[n..<m]
331-
/// let rebased = UnsafeBufferPointer(rebasing: slice)
344+
/// After rebasing `slice` as the `rebased` buffer, the following are true:
332345
///
333-
/// One may assume `rebased.startIndex == 0` and `rebased[0] == slice[n]`.
346+
/// - `rebased.startIndex == 0`
347+
/// - `rebased[0] == slice[n]`
348+
/// - `rebased[0] == buffer[n]`
349+
/// - `rebased.count == slice.count`
334350
///
335-
/// - Parameter slice: the buffer slice to rebase.
351+
/// - Parameter slice: The buffer slice to rebase.
336352
@_inlineable
337353
public init(
338354
rebasing slice:
@@ -388,17 +404,26 @@ extension Unsafe${Mutable}BufferPointer : CustomDebugStringConvertible {
388404

389405

390406
extension UnsafeMutableBufferPointer {
391-
/// Initializes memory in the buffer with the elements of `source`.
392-
/// Returns an iterator to any elements of `source` that didn't fit in the
393-
/// buffer, and an index to the point in the buffer one past the last element
394-
/// written (so `startIndex` if no elements written, `endIndex` if the buffer
395-
/// was completely filled).
407+
/// Initializes the buffer's memory with the given elements.
408+
///
409+
/// When calling the `initialize(from:)` method on a buffer `b`, the memory
410+
/// referenced by `b` must be uninitialized or the `Element` type must be a
411+
/// trivial type. After the call, the memory referenced by this buffer up
412+
/// to, but not including, the returned index is initialized. The buffer
413+
/// must contain sufficient memory to accommodate
414+
/// `source.underestimatedCount`.
396415
///
397-
/// - Precondition: The memory in `self` is uninitialized. The buffer must
398-
/// contain sufficient uninitialized memory to accommodate `source.underestimatedCount`.
416+
/// The returned index is the position of the element in the buffer one past
417+
/// the last element written. If `source` contains no elements, the returned
418+
/// index is equal to the buffer's `startIndex`. If `source` contains an
419+
/// equal or greater number of elements than the buffer can hold, the
420+
/// returned index is equal to the buffer's `endIndex`.
399421
///
400-
/// - Postcondition: The `Pointee`s at `self[startIndex..<returned index]` are
401-
/// initialized.
422+
/// - Parameter source: A sequence of elements with which to initializer the
423+
/// buffer.
424+
/// - Returns: An iterator to any elements of `source` that didn't fit in the
425+
/// buffer, and an index to the point in the buffer one past the last
426+
/// element written.
402427
@_inlineable
403428
public func initialize<S: Sequence>(from source: S) -> (S.Iterator, Index)
404429
where S.Element == Element {

0 commit comments

Comments
 (0)