From 25458a52be53186a1c0cb5510d193f7cdb06a3c4 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Fri, 17 Oct 2025 01:06:52 -0400 Subject: [PATCH 01/10] Revise `InlineArray` documentation Update documentation for `InlineArray` to include examples with type sugar, reword to avoid certain jargon that may be unfamiliar to some standard library users, and incorporate additional details mostly drawn from the proposal text. --- stdlib/public/core/InlineArray.swift | 88 +++++++++++++++++++++------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index dda7430d21dbf..366bd9ec4ecd7 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -12,34 +12,82 @@ /// A fixed-size array. /// -/// The `InlineArray` type is a specialized array that stores its elements -/// contiguously inline, rather than allocating an out-of-line region of memory -/// with copy-on-write optimization. +/// An `InlineArray` is a specialized container that does not use a separate +/// memory allocation just to store its elements. When a value is copied, all of +/// its elements are copied eagerly. Use an `InlineArray` when you have a fixed +/// number of elements and need to avoid a separate heap allocation. +/// +/// Initializing a Value +/// -------------------- +/// +/// When initializing a new `InlineArray` value, you'll need to initialize all +/// of its elements. You can use an array literal just as with `Array`, rely on +/// type inference for the `count` and `Element` type, and spell the type with +/// the shorthand `[count of Element]`. +/// +/// let a: InlineArray<3, Int> = [1, 2, 3] +/// // With type inference: +/// let b: InlineArray<_, Int> = [1, 2, 3] +/// let c: InlineArray<3, _> = [1, 2, 3] +/// let d: InlineArray = [1, 2, 3] +/// // With shorthand (and, optionally, type inference): +/// let e: [3 of Int] = [1, 2, 3] +/// let f: [_ of Int] = [1, 2, 3] +/// let g: [3 of _] = [1, 2, 3] +/// let h: [_ of _] = [1, 2, 3] +/// +/// Accessing Elements +/// ------------------ +/// +/// Just as with `Array`, you can read and modify an element in an +/// `InlineArray` using a subscript. Unless you use the `unchecked` subscript, +/// any index you provide is subject to bounds checking; if invalid, it will +/// trigger a runtime error in your program. +/// +/// var values: [3 of Double] = [1, 1.5, 2] +/// print(values[0]) // Prints "1.0" +/// values[1] -= 0.25 +/// print(values[1]) // Prints "1.25" +/// values[3] = 42.0 // Fatal error: Index out of bounds +/// +/// Working with Noncopyable Elements +/// --------------------------------- +/// +/// An `InlineArray` can store elements of potentially noncopyable type. When +/// `Element` isn't copyable, the `InlineArray` itself also isn't copyable. You +/// must then explicitly move or consume the value if you want to transfer +/// ownership. /// /// Memory Layout /// ------------- /// -/// An *empty* array's size is zero. Its stride and alignment are one byte. -/// -/// A *nonempty* array's size and stride are equal to the element's stride -/// multiplied by the number of elements. Its alignment is equal to the -/// element's alignment. +/// If an `InlineArray` is a stored property of a class, then it will be +/// allocated on the heap along with the other stored properties of the class. +/// Otherwise, in general, an `InlineArray` will be allocated on the stack. /// -/// MemoryLayout>.size //-> 6 -/// MemoryLayout>.stride //-> 6 -/// MemoryLayout>.alignment //-> 2 +/// Elements in an `InlineArray` are stored contiguously, and the memory layout +/// can be easily determined: /// -/// Literal Initialization -/// ---------------------- +/// A *nonempty* `InlineArray`'s size and stride are both found by multiplying +/// the `count` of elements by the `Element`'s stride. Its alignment is equal to +/// the `Element`'s alignment. /// -/// Array literal syntax can be used to initialize an `InlineArray` instance. -/// A stack-allocated array will do in-place initialization of each element. -/// The `count` and/or `Element` can be inferred from the array literal. +/// struct S { +/// let x: UInt32 +/// let y: Bool +/// } +/// MemoryLayout.size // 5 +/// MemoryLayout.stride // 8 +/// MemoryLayout.alignment // 4 +/// MemoryLayout<[3 of S]>.size // 24 +/// MemoryLayout<[3 of S]>.stride // 24 +/// MemoryLayout<[3 of S]>.alignment // 4 +/// MemoryLayout<(S, S, S)>.size // 21 +/// MemoryLayout<(S, S, S)>.stride // 24 +/// MemoryLayout<(S, S, S)>.alignment // 4 /// -/// let a: InlineArray<4, Int> = [1, 2, 4, 8] -/// let b: InlineArray<_, Int> = [1, 2, 4, 8] -/// let c: InlineArray<4, _> = [1, 2, 4, 8] -/// let d: InlineArray = [1, 2, 4, 8] +/// An *empty* `InlineArray`'s size is zero. Its stride and alignment are both +/// one byte. @available(SwiftStdlib 6.2, *) @frozen @safe From bf2e5c4ce45da973947b0c07bdbcac8cb98b3d12 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Fri, 17 Oct 2025 12:25:49 -0400 Subject: [PATCH 02/10] Update `InlineArray` documentation for reviewer feedback --- stdlib/public/core/InlineArray.swift | 54 +++++++++++++++------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index 366bd9ec4ecd7..14800b099c6f7 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -26,23 +26,25 @@ /// the shorthand `[count of Element]`. /// /// let a: InlineArray<3, Int> = [1, 2, 3] -/// // With type inference: /// let b: InlineArray<_, Int> = [1, 2, 3] /// let c: InlineArray<3, _> = [1, 2, 3] /// let d: InlineArray = [1, 2, 3] -/// // With shorthand (and, optionally, type inference): +/// /// let e: [3 of Int] = [1, 2, 3] /// let f: [_ of Int] = [1, 2, 3] /// let g: [3 of _] = [1, 2, 3] /// let h: [_ of _] = [1, 2, 3] /// +/// You can also use one of the type's initializers to create a new value +/// programmatically. +/// /// Accessing Elements /// ------------------ /// /// Just as with `Array`, you can read and modify an element in an -/// `InlineArray` using a subscript. Unless you use the `unchecked` subscript, -/// any index you provide is subject to bounds checking; if invalid, it will -/// trigger a runtime error in your program. +/// `InlineArray` using a subscript. Unless you use the memory-unsafe +/// `unchecked` subscript, any index you provide is subject to bounds checking; +/// if invalid, it will trigger a runtime error in your program. /// /// var values: [3 of Double] = [1, 1.5, 2] /// print(values[0]) // Prints "1.0" @@ -50,6 +52,12 @@ /// print(values[1]) // Prints "1.25" /// values[3] = 42.0 // Fatal error: Index out of bounds /// +/// You can use the `indices` property to iterate over all elements in order. +/// +/// for index in values.indices { +/// print(values[index]) +/// } +/// /// Working with Noncopyable Elements /// --------------------------------- /// @@ -61,30 +69,28 @@ /// Memory Layout /// ------------- /// -/// If an `InlineArray` is a stored property of a class, then it will be -/// allocated on the heap along with the other stored properties of the class. -/// Otherwise, in general, an `InlineArray` will be allocated on the stack. -/// -/// Elements in an `InlineArray` are stored contiguously, and the memory layout -/// can be easily determined: +/// An `InlineArray` stores its elements contiguously. If an `InlineArray` is a +/// stored property of a class, then it will be allocated on the heap along with +/// the other stored properties of the class. Otherwise, in general, an +/// `InlineArray` will be allocated on the stack. /// -/// A *nonempty* `InlineArray`'s size and stride are both found by multiplying +/// A *non-empty* `InlineArray`'s size and stride are both found by multiplying /// the `count` of elements by the `Element`'s stride. Its alignment is equal to /// the `Element`'s alignment. /// -/// struct S { +/// struct Record { /// let x: UInt32 /// let y: Bool /// } -/// MemoryLayout.size // 5 -/// MemoryLayout.stride // 8 -/// MemoryLayout.alignment // 4 -/// MemoryLayout<[3 of S]>.size // 24 -/// MemoryLayout<[3 of S]>.stride // 24 -/// MemoryLayout<[3 of S]>.alignment // 4 -/// MemoryLayout<(S, S, S)>.size // 21 -/// MemoryLayout<(S, S, S)>.stride // 24 -/// MemoryLayout<(S, S, S)>.alignment // 4 +/// MemoryLayout.size // 5 +/// MemoryLayout.stride // 8 +/// MemoryLayout.alignment // 4 +/// MemoryLayout<[2 of Record]>.size // 16 +/// MemoryLayout<[2 of Record]>.stride // 16 +/// MemoryLayout<[2 of Record]>.alignment // 4 +/// MemoryLayout<(Record, Record)>.size // 13 +/// MemoryLayout<(Record, Record)>.stride // 16 +/// MemoryLayout<(Record, Record)>.alignment // 4 /// /// An *empty* `InlineArray`'s size is zero. Its stride and alignment are both /// one byte. @@ -251,7 +257,7 @@ extension InlineArray where Element: ~Copyable { /// count of the array, to initialize every element by passing the closure /// the index of the current element being initialized. /// - /// InlineArray<4, Int> { 1 << $0 } //-> [1, 2, 4, 8] + /// [4 of Int] { $0 * 2 } // [0, 2, 4, 6] /// /// The closure is allowed to throw an error at any point during /// initialization at which point the array will stop initialization, @@ -290,7 +296,7 @@ extension InlineArray where Element: ~Copyable { /// count of the array, to initialize every element by passing the closure an /// immutable borrow reference to the preceding element. /// - /// InlineArray<4, Int>(first: 1) { $0 << 1 } //-> [1, 2, 4, 8] + /// [4 of Int](first: 1) { $0 * 2 } // [1, 2, 4, 8] /// /// The closure is allowed to throw an error at any point during /// initialization at which point the array will stop initialization, From 0f1d51903ad00d7e7257d80f7f3ed501d2b916a7 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 11:48:31 -0400 Subject: [PATCH 03/10] [docs] Restore original spelling for invoking `InlineArray` initializers --- stdlib/public/core/InlineArray.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index 14800b099c6f7..ede40bce7d5e8 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -257,7 +257,7 @@ extension InlineArray where Element: ~Copyable { /// count of the array, to initialize every element by passing the closure /// the index of the current element being initialized. /// - /// [4 of Int] { $0 * 2 } // [0, 2, 4, 6] + /// InlineArray<4, Int> { $0 * 2 } // [0, 2, 4, 6] /// /// The closure is allowed to throw an error at any point during /// initialization at which point the array will stop initialization, @@ -296,7 +296,7 @@ extension InlineArray where Element: ~Copyable { /// count of the array, to initialize every element by passing the closure an /// immutable borrow reference to the preceding element. /// - /// [4 of Int](first: 1) { $0 * 2 } // [1, 2, 4, 8] + /// InlineArray<4, Int>(first: 1) { $0 * 2 } // [1, 2, 4, 8] /// /// The closure is allowed to throw an error at any point during /// initialization at which point the array will stop initialization, From 4c73064df916862cd15e1cdb46a7799ebe3b9bdc Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:02:32 -0400 Subject: [PATCH 04/10] Update stdlib/public/core/InlineArray.swift Co-authored-by: Alex Martini --- stdlib/public/core/InlineArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index ede40bce7d5e8..b6330456605b5 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -12,7 +12,7 @@ /// A fixed-size array. /// -/// An `InlineArray` is a specialized container that does not use a separate +/// An `InlineArray` is a specialized container that doesn't use a separate /// memory allocation just to store its elements. When a value is copied, all of /// its elements are copied eagerly. Use an `InlineArray` when you have a fixed /// number of elements and need to avoid a separate heap allocation. From 7de0ae4f1f32f5bba2dd542e27344263f9509498 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:03:37 -0400 Subject: [PATCH 05/10] Update stdlib/public/core/InlineArray.swift Co-authored-by: Alex Martini --- stdlib/public/core/InlineArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index b6330456605b5..50ed38c2b3d81 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -20,7 +20,7 @@ /// Initializing a Value /// -------------------- /// -/// When initializing a new `InlineArray` value, you'll need to initialize all +/// When initializing a new `InlineArray` value, you initialize all /// of its elements. You can use an array literal just as with `Array`, rely on /// type inference for the `count` and `Element` type, and spell the type with /// the shorthand `[count of Element]`. From 9e2583382aa9ecf9a192acfbecdcde85369b75cf Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:04:17 -0400 Subject: [PATCH 06/10] Update stdlib/public/core/InlineArray.swift Co-authored-by: Alex Martini --- stdlib/public/core/InlineArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index 50ed38c2b3d81..e048869807fa8 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -44,7 +44,7 @@ /// Just as with `Array`, you can read and modify an element in an /// `InlineArray` using a subscript. Unless you use the memory-unsafe /// `unchecked` subscript, any index you provide is subject to bounds checking; -/// if invalid, it will trigger a runtime error in your program. +/// invalid indices trigger a runtime error in your program. /// /// var values: [3 of Double] = [1, 1.5, 2] /// print(values[0]) // Prints "1.0" From 2496d434aa09f41f4586d20fe7f2d371ebb3c742 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:04:27 -0400 Subject: [PATCH 07/10] Update stdlib/public/core/InlineArray.swift Co-authored-by: Alex Martini --- stdlib/public/core/InlineArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index e048869807fa8..e3cfea847c9b6 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -70,7 +70,7 @@ /// ------------- /// /// An `InlineArray` stores its elements contiguously. If an `InlineArray` is a -/// stored property of a class, then it will be allocated on the heap along with +/// stored property of a class, then it's allocated on the heap along with /// the other stored properties of the class. Otherwise, in general, an /// `InlineArray` will be allocated on the stack. /// From 4a956963259cdcc4fb9ef6389ba50f627a9e118d Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:04:41 -0400 Subject: [PATCH 08/10] Update stdlib/public/core/InlineArray.swift Co-authored-by: Alex Martini --- stdlib/public/core/InlineArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index e3cfea847c9b6..7eb08543c22cc 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -72,7 +72,7 @@ /// An `InlineArray` stores its elements contiguously. If an `InlineArray` is a /// stored property of a class, then it's allocated on the heap along with /// the other stored properties of the class. Otherwise, in general, an -/// `InlineArray` will be allocated on the stack. +/// `InlineArray` is allocated on the stack. /// /// A *non-empty* `InlineArray`'s size and stride are both found by multiplying /// the `count` of elements by the `Element`'s stride. Its alignment is equal to From 556095025a013f4328b02ce296900a0242323c47 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:12:36 -0400 Subject: [PATCH 09/10] [docs] Address reviewer feedback on `InlineArray` initialization. --- stdlib/public/core/InlineArray.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index 7eb08543c22cc..30ce28e108684 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -35,8 +35,7 @@ /// let g: [3 of _] = [1, 2, 3] /// let h: [_ of _] = [1, 2, 3] /// -/// You can also use one of the type's initializers to create a new value -/// programmatically. +/// You can also use one of the type's initializers to create a new value. /// /// Accessing Elements /// ------------------ From bd9c6728efccaf648a6b23874224d63a2daea577 Mon Sep 17 00:00:00 2001 From: Xiaodi Wu <13952+xwu@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:41:54 -0400 Subject: [PATCH 10/10] [docs] Clarify "eagerly" in InlineArray docs ...adjust line wrapping to account for adoption of prior suggestions, and some minor edits. --- stdlib/public/core/InlineArray.swift | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/stdlib/public/core/InlineArray.swift b/stdlib/public/core/InlineArray.swift index 30ce28e108684..af4b93e337590 100644 --- a/stdlib/public/core/InlineArray.swift +++ b/stdlib/public/core/InlineArray.swift @@ -14,16 +14,17 @@ /// /// An `InlineArray` is a specialized container that doesn't use a separate /// memory allocation just to store its elements. When a value is copied, all of -/// its elements are copied eagerly. Use an `InlineArray` when you have a fixed -/// number of elements and need to avoid a separate heap allocation. +/// its elements are copied eagerly, like those of a tuple. Use an `InlineArray` +/// when you have a fixed number of elements and need to avoid a separate heap +/// allocation. /// /// Initializing a Value /// -------------------- /// -/// When initializing a new `InlineArray` value, you initialize all -/// of its elements. You can use an array literal just as with `Array`, rely on -/// type inference for the `count` and `Element` type, and spell the type with -/// the shorthand `[count of Element]`. +/// When initializing a new `InlineArray` value, you must initialize all of its +/// elements. You can use an array literal just as with `Array`, rely on type +/// inference for the `count` and `Element` type, and spell the type with the +/// shorthand `[count of Element]`. /// /// let a: InlineArray<3, Int> = [1, 2, 3] /// let b: InlineArray<_, Int> = [1, 2, 3] @@ -40,10 +41,10 @@ /// Accessing Elements /// ------------------ /// -/// Just as with `Array`, you can read and modify an element in an -/// `InlineArray` using a subscript. Unless you use the memory-unsafe -/// `unchecked` subscript, any index you provide is subject to bounds checking; -/// invalid indices trigger a runtime error in your program. +/// Just as with `Array`, you can read and modify an element in an `InlineArray` +/// using a subscript. Unless you use the memory-unsafe `unchecked` subscript, +/// any index you provide is subject to bounds checking; an invalid index +/// triggers a runtime error in your program. /// /// var values: [3 of Double] = [1, 1.5, 2] /// print(values[0]) // Prints "1.0" @@ -69,8 +70,8 @@ /// ------------- /// /// An `InlineArray` stores its elements contiguously. If an `InlineArray` is a -/// stored property of a class, then it's allocated on the heap along with -/// the other stored properties of the class. Otherwise, in general, an +/// stored property of a class, then it's allocated on the heap along with the +/// other stored properties of the class. Otherwise, in general, an /// `InlineArray` is allocated on the stack. /// /// A *non-empty* `InlineArray`'s size and stride are both found by multiplying