Skip to content

[stdlib] Add an ambiguity breaker for RRC.popLast #14941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions stdlib/public/core/RangeReplaceableCollection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,7 @@ extension RangeReplaceableCollection where Self : BidirectionalCollection {
public mutating func removeLast() -> Element {
_precondition(!isEmpty, "Can't remove last element from an empty collection")
// NOTE if you change this implementation, change popLast above as well
// AND change the tie-breaker implementations in the next extension
if let result = _customRemoveLast() { return result }
return remove(at: index(before: endIndex))
}
Expand Down Expand Up @@ -865,10 +866,27 @@ extension RangeReplaceableCollection where Self : BidirectionalCollection {
}
}

// FIXME: swift-3-indexing-model: file a bug for the compiler?
/// Ambiguity breakers.
extension RangeReplaceableCollection
where Self : BidirectionalCollection, SubSequence == Self {
where Self : BidirectionalCollection, SubSequence == Self {
/// Removes and returns the last element of the collection.
///
/// Calling this method may invalidate all saved indices of this
/// collection. Do not rely on a previously stored index value after
/// altering a collection with any operation that can change its length.
///
/// - Returns: The last element of the collection if the collection is not
/// empty; otherwise, `nil`.
///
/// - Complexity: O(1)
@_inlineable
public mutating func popLast() -> Element? {
if isEmpty { return nil }
// duplicate of removeLast logic below, to avoid redundant precondition
if let result = _customRemoveLast() { return result }
return remove(at: index(before: endIndex))
}

/// Removes and returns the last element of the collection.
///
/// The collection must not be empty.
Expand All @@ -884,9 +902,8 @@ extension RangeReplaceableCollection
@discardableResult
public mutating func removeLast() -> Element {
_precondition(!isEmpty, "Can't remove last element from an empty collection")
if let result = _customRemoveLast() {
return result
}
// NOTE if you change this implementation, change popLast above as well
if let result = _customRemoveLast() { return result }
return remove(at: index(before: endIndex))
}

Expand Down
2 changes: 1 addition & 1 deletion validation-test/stdlib/Arrays.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,7 @@ ArrayTestSuite.test("Native/isEmpty") {
expectFalse(a.isEmpty)
}

% for Kind in ['Array', 'ContiguousArray']:
% for Kind in ['Array', 'ContiguousArray', 'ArraySlice']:
ArrayTestSuite.test("${Kind}/popLast") {
// Empty
do {
Expand Down