Skip to content

Commit 3e932c0

Browse files
committed
stdlib: Add custom .first to Array
This makes Array.first much small and more efficient. Without this, Array.first compiled down to RandomAccessCollection.first, which ended up in pretty unefficient code. rdar://problem/46291397
1 parent 87298c0 commit 3e932c0

File tree

4 files changed

+13
-7
lines changed

4 files changed

+13
-7
lines changed

stdlib/public/core/Array.swift

+6
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,12 @@ extension Array: RandomAccessCollection, MutableCollection {
765765
public var count: Int {
766766
return _getCount()
767767
}
768+
769+
@inlinable
770+
@_alwaysEmitIntoClient
771+
public var first: Element? {
772+
_getCount() == 0 ? nil : _buffer[0]
773+
}
768774
}
769775

770776
extension Array: ExpressibleByArrayLiteral {

test/IDE/complete_from_stdlib.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func testArchetypeReplacement1<FOO : Equatable>(_ a: [FOO]) {
133133
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceMethod]/CurrNominal: append({#(newElement): Equatable#})[#Void#]{{; name=.+}}
134134
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceMethod]/CurrNominal: insert({#(newElement): Equatable#}, {#at: Int#})[#Void#]{{; name=.+}}
135135
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceVar]/Super: isEmpty[#Bool#]{{; name=.+}}
136-
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceVar]/Super: first[#Equatable?#]{{; name=.+}}
136+
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceVar]/CurrNominal: first[#Equatable?#]{{; name=.+}}
137137
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceMethod]/Super: dropFirst({#(k): Int#})[#ArraySlice<Equatable>#]{{; name=.+}}
138138
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceMethod]/Super: dropLast({#(k): Int#})[#ArraySlice<Equatable>#]{{; name=.+}}
139139
// PRIVATE_NOMINAL_MEMBERS_5-DAG: Decl[InstanceMethod]/Super: prefix({#(maxLength): Int#})[#ArraySlice<Equatable>#]{{; name=.+}}
@@ -164,7 +164,7 @@ func testArchetypeReplacement3 (_ a : [Int]) {
164164
// PRIVATE_NOMINAL_MEMBERS_7: Begin completions
165165
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/CurrNominal: append({#(newElement): Int#})[#Void#]
166166
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: removeLast()[#Int#]
167-
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceVar]/Super: first[#Int?#]
167+
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceVar]/CurrNominal: first[#Int?#]
168168
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: map({#(transform): (Int) throws -> T##(Int) throws -> T#})[' rethrows'][#[T]#]
169169
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: dropLast({#(k): Int#})[#ArraySlice<Int>#]
170170
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: elementsEqual({#(other): Sequence#}, {#by: (Int, Sequence.Element) throws -> Bool##(Int, Sequence.Element) throws -> Bool#})[' rethrows'][#Bool#]; name=elementsEqual(other: Sequence, by: (Int, Sequence.Element) throws -> Bool) rethrows

test/IDE/complete_literal.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func testArray(f1: Float) {
8383
_ = [1, 2, f1] #^LITERAL8^#
8484
}
8585
// LITERAL8-DAG: Decl[InstanceVar]/CurrNominal: .count[#Int#]; name=count
86-
// LITERAL8-DAG: Decl[InstanceVar]/Super: .first[#Float?#]; name=first
86+
// LITERAL8-DAG: Decl[InstanceVar]/CurrNominal: .first[#Float?#]; name=first
8787

8888
func testDict(f1: Float) {
8989
_ = ["foo": f1, "bar": "baz"] #^LITERAL9^#

test/IDE/complete_swift_key_path.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ let _ = \Person.friends#^ARRAY_NODOT^#
5757
// ARRAY-NODOT: Begin completions
5858
// ARRAY-NODOT-DAG: Decl[Subscript]/CurrNominal: [{#(index): Int#}][#Person#]; name=[index: Int]
5959
// ARRAY-NODOT-DAG: Decl[InstanceVar]/CurrNominal: .count[#Int#]; name=count
60-
// ARRAY-NODOT-DAG: Decl[InstanceVar]/Super: .first[#Person?#]; name=first
60+
// ARRAY-NODOT-DAG: Decl[InstanceVar]/CurrNominal: .first[#Person?#]; name=first
6161

6262
let _ = \Person.friends.#^ARRAY_DOT^#
6363
// ARRAY-DOT: Begin completions
6464
// ARRAY-DOT-NOT: Decl[Subscript]/CurrNominal: [{#(index): Int#}][#Element#]; name=[Int]
6565
// ARRAY-DOT-DAG: Decl[InstanceVar]/CurrNominal: count[#Int#]; name=count
66-
// ARRAY-DOT-DAG: Decl[InstanceVar]/Super: first[#Person?#]; name=first
66+
// ARRAY-DOT-DAG: Decl[InstanceVar]/CurrNominal: first[#Person?#]; name=first
6767
// ARRAY-DOT-NOT: Decl[Subscript]/CurrNominal: [{#(index): Int#}][#Element#]; name=[Int]
6868

6969
let _ = \Person.friends[0]#^OBJ_NODOT^#
@@ -114,13 +114,13 @@ let _ = \[Person]#^ARRAYTYPE_NODOT^#
114114
// ARRAYTYPE-NODOT: Begin completions
115115
// ARRAYTYPE-NODOT-DAG: Decl[Subscript]/CurrNominal: .[{#(index): Int#}][#Person#]; name=[index: Int]
116116
// ARRAYTYPE-NODOT-DAG: Decl[InstanceVar]/CurrNominal: .count[#Int#]; name=count
117-
// ARRAYTYPE-NODOT-DAG: Decl[InstanceVar]/Super: .first[#Person?#]; name=first
117+
// ARRAYTYPE-NODOT-DAG: Decl[InstanceVar]/CurrNominal: .first[#Person?#]; name=first
118118

119119
let _ = \[Person].#^ARRAYTYPE_DOT^#
120120
// ARRAYTYPE-DOT: Begin completions
121121
// ARRAYTYPE-DOT-DAG: Decl[Subscript]/CurrNominal: [{#(index): Int#}][#Person#]; name=[index: Int]
122122
// ARRAYTYPE-DOT-DAG: Decl[InstanceVar]/CurrNominal: count[#Int#]; name=count
123-
// ARRAYTYPE-DOT-DAG: Decl[InstanceVar]/Super: first[#Person?#]; name=first
123+
// ARRAYTYPE-DOT-DAG: Decl[InstanceVar]/CurrNominal: first[#Person?#]; name=first
124124

125125
func test(_ p: Person) {
126126
let _ = p[keyPath: \Person.#^APPLY_TYPE_DOT^#]

0 commit comments

Comments
 (0)