diff --git a/stdlib/public/core/Comparable.swift b/stdlib/public/core/Comparable.swift index 4b8898147d329..6baf5100f60a2 100644 --- a/stdlib/public/core/Comparable.swift +++ b/stdlib/public/core/Comparable.swift @@ -135,7 +135,7 @@ /// (`FloatingPoint.nan`) compares as neither less than, greater than, nor /// equal to any normal floating-point value. Exceptional values need not /// take part in the strict total order. -public protocol Comparable: Equatable, ~Copyable { +public protocol Comparable: Equatable, ~Copyable, ~Escapable { /// Returns a Boolean value indicating whether the value of the first /// argument is less than that of the second argument. /// @@ -173,7 +173,7 @@ public protocol Comparable: Equatable, ~Copyable { static func > (lhs: borrowing Self, rhs: borrowing Self) -> Bool } -extension Comparable where Self: ~Copyable { +extension Comparable where Self: ~Copyable & ~Escapable { /// Returns a Boolean value indicating whether the value of the first argument /// is greater than that of the second argument. /// diff --git a/test/SILOptimizer/mandatory_performance_optimizations.sil b/test/SILOptimizer/mandatory_performance_optimizations.sil index 5f917d0731c4a..7415cd12d82b8 100644 --- a/test/SILOptimizer/mandatory_performance_optimizations.sil +++ b/test/SILOptimizer/mandatory_performance_optimizations.sil @@ -84,7 +84,7 @@ bb0: sil [no_allocation] [ossa] @deserialize_and_inline_after_devirtualize : $@convention(thin) (@in Int) -> () { bb0(%0 : $*Int): %1 = metatype $@thick Int.Type - %2 = witness_method $Int, #Comparable."<" : (Self.Type) -> (borrowing Self, borrowing Self) -> Bool : $@convention(witness_method: Comparable) <τ_0_0 where τ_0_0 : Comparable> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> Bool + %2 = witness_method $Int, #Comparable."<" : (Self.Type) -> (borrowing Self, borrowing Self) -> Bool : $@convention(witness_method: Comparable) <τ_0_0 where τ_0_0 : Comparable> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> Bool %3 = apply %2(%0, %0, %1) : $@convention(witness_method: Comparable) <τ_0_0 where τ_0_0 : Comparable> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @thick τ_0_0.Type) -> Bool %4 = tuple() return %4 : $() @@ -124,7 +124,7 @@ bb0(%0 : $*Int, %1 : $*Int, %2 : $@thick Int.Type): sil_witness_table public_external [serialized] Int: Comparable module Swift { base_protocol Equatable: Int: Equatable module Swift - method #Comparable."<": (Self.Type) -> (borrowing Self, borrowing Self) -> Bool : @$sSiSLsSL1loiySbx_xtFZTW + method #Comparable."<": (Self.Type) -> (borrowing Self, borrowing Self) -> Bool : @$sSiSLsSL1loiySbx_xtFZTW } sil [ossa] @get_int_value : $@convention(thin) () -> Int32 { diff --git a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected index 60bce9a98bf46..2558f377f71ef 100644 --- a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected @@ -71,7 +71,6 @@ Protocol CodingKey has added inherited protocol Copyable Protocol CodingKey has added inherited protocol Escapable Protocol Collection has added inherited protocol Copyable Protocol Collection has added inherited protocol Escapable -Protocol Comparable has added inherited protocol Escapable Protocol CustomDebugStringConvertible has added inherited protocol Copyable Protocol CustomDebugStringConvertible has added inherited protocol Escapable Protocol CustomLeafReflectable has added inherited protocol Copyable @@ -384,18 +383,18 @@ Func Equatable.==(_:_:) has generic signature change from to -Func Comparable.<(_:_:) has generic signature change from to +// Comparable: ~Copyable & ~Escapable +Protocol Comparable has generic signature change from to +Func Comparable.<(_:_:) has generic signature change from to Func Comparable.<(_:_:) has parameter 0 changing from Default to Shared Func Comparable.<(_:_:) has parameter 1 changing from Default to Shared -Func Comparable.<=(_:_:) has generic signature change from to +Func Comparable.<=(_:_:) has generic signature change from to Func Comparable.<=(_:_:) has parameter 0 changing from Default to Shared Func Comparable.<=(_:_:) has parameter 1 changing from Default to Shared -Func Comparable.>(_:_:) has generic signature change from to +Func Comparable.>(_:_:) has generic signature change from to Func Comparable.>(_:_:) has parameter 0 changing from Default to Shared Func Comparable.>(_:_:) has parameter 1 changing from Default to Shared -Func Comparable.>=(_:_:) has generic signature change from to +Func Comparable.>=(_:_:) has generic signature change from to Func Comparable.>=(_:_:) has parameter 0 changing from Default to Shared Func Comparable.>=(_:_:) has parameter 1 changing from Default to Shared diff --git a/test/api-digester/stability-stdlib-abi-without-asserts.test b/test/api-digester/stability-stdlib-abi-without-asserts.test index 52124e2147282..155b1a53b53ea 100644 --- a/test/api-digester/stability-stdlib-abi-without-asserts.test +++ b/test/api-digester/stability-stdlib-abi-without-asserts.test @@ -189,7 +189,6 @@ Protocol CodingKey has added inherited protocol Copyable Protocol CodingKey has added inherited protocol Escapable Protocol Collection has added inherited protocol Copyable Protocol Collection has added inherited protocol Escapable -Protocol Comparable has added inherited protocol Escapable Protocol CustomDebugStringConvertible has added inherited protocol Copyable Protocol CustomDebugStringConvertible has added inherited protocol Escapable Protocol CustomLeafReflectable has added inherited protocol Copyable @@ -889,23 +888,23 @@ Func Equatable.==(_:_:) has generic signature change from to -Func Comparable.<(_:_:) has generic signature change from to +// Comparable: ~Copyable & ~Escapable +Protocol Comparable has generic signature change from to +Func Comparable.<(_:_:) has generic signature change from to Func Comparable.<(_:_:) has parameter 0 changing from Default to Shared Func Comparable.<(_:_:) has parameter 1 changing from Default to Shared -Func Comparable.<=(_:_:) has generic signature change from to -Func Comparable.<=(_:_:) has mangled name changing from 'static (extension in Swift):Swift.Comparable.<= infix(A, A) -> Swift.Bool' to 'static (extension in Swift):Swift.Comparable< where A: ~Swift.Copyable>.<= infix(A, A) -> Swift.Bool' +Func Comparable.<=(_:_:) has generic signature change from to +Func Comparable.<=(_:_:) has mangled name changing from 'static (extension in Swift):Swift.Comparable.<= infix(A, A) -> Swift.Bool' to 'static (extension in Swift):Swift.Comparable< where A: ~Swift.Copyable, A: ~Swift.Escapable>.<= infix(A, A) -> Swift.Bool' Func Comparable.<=(_:_:) has parameter 0 changing from Default to Shared Func Comparable.<=(_:_:) has parameter 1 changing from Default to Shared Func Comparable.<=(_:_:) is now with @_preInverseGenerics -Func Comparable.>(_:_:) has generic signature change from to -Func Comparable.>(_:_:) has mangled name changing from 'static (extension in Swift):Swift.Comparable.> infix(A, A) -> Swift.Bool' to 'static (extension in Swift):Swift.Comparable< where A: ~Swift.Copyable>.> infix(A, A) -> Swift.Bool' +Func Comparable.>(_:_:) has generic signature change from to +Func Comparable.>(_:_:) has mangled name changing from 'static (extension in Swift):Swift.Comparable.> infix(A, A) -> Swift.Bool' to 'static (extension in Swift):Swift.Comparable< where A: ~Swift.Copyable, A: ~Swift.Escapable>.> infix(A, A) -> Swift.Bool' Func Comparable.>(_:_:) has parameter 0 changing from Default to Shared Func Comparable.>(_:_:) has parameter 1 changing from Default to Shared Func Comparable.>(_:_:) is now with @_preInverseGenerics -Func Comparable.>=(_:_:) has generic signature change from to -Func Comparable.>=(_:_:) has mangled name changing from 'static (extension in Swift):Swift.Comparable.>= infix(A, A) -> Swift.Bool' to 'static (extension in Swift):Swift.Comparable< where A: ~Swift.Copyable>.>= infix(A, A) -> Swift.Bool' +Func Comparable.>=(_:_:) has generic signature change from to +Func Comparable.>=(_:_:) has mangled name changing from 'static (extension in Swift):Swift.Comparable.>= infix(A, A) -> Swift.Bool' to 'static (extension in Swift):Swift.Comparable< where A: ~Swift.Copyable, A: ~Swift.Escapable>.>= infix(A, A) -> Swift.Bool' Func Comparable.>=(_:_:) has parameter 0 changing from Default to Shared Func Comparable.>=(_:_:) has parameter 1 changing from Default to Shared Func Comparable.>=(_:_:) is now with @_preInverseGenerics diff --git a/test/stdlib/NoncopyableComparable.swift b/test/stdlib/NoncopyableComparable.swift index 2867848ce19f0..eb80c01661aae 100644 --- a/test/stdlib/NoncopyableComparable.swift +++ b/test/stdlib/NoncopyableComparable.swift @@ -9,30 +9,44 @@ // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -// RUN: %target-run-simple-swift +// RUN: %target-run-simple-swift(-enable-experimental-feature Lifetimes) // REQUIRES: executable_test +// REQUIRES: swift_feature_Lifetimes import StdlibUnittest let NoncopyableComparableTests = TestSuite("NoncopyableComparable") -struct Noncopyable: ~Copyable { +struct Noncopyable: ~Copyable, ~Escapable { var wrapped: Wrapped } -extension Noncopyable: Equatable where Wrapped: Equatable & ~Copyable { } +extension Noncopyable: Equatable where Wrapped: Equatable & ~Copyable & ~Escapable { } -extension Noncopyable: Comparable where Wrapped: Comparable & ~Copyable { +extension Noncopyable: Comparable where Wrapped: Comparable & ~Copyable & ~Escapable { static func < (lhs: borrowing Self, rhs: borrowing Self) -> Bool { lhs.wrapped < rhs.wrapped } } -extension Comparable where Self: ~Copyable { +extension Noncopyable: Escapable where Wrapped: Escapable & ~Copyable { } + +struct Nonescapable: ~Escapable { + let wrapped: Int +} + +extension Nonescapable: Equatable { } + +extension Nonescapable: Comparable { + static func <(lhs: Self, rhs: Self) -> Bool { lhs.wrapped < rhs.wrapped } + +} + +extension Comparable where Self: ~Copyable & ~Escapable { func isLessThan(_ other: borrowing Self) -> Bool { self < other } } -func isLessOrEqual(_ lhs: borrowing T, _ rhs: borrowing T) -> Bool { +func isLessOrEqual(_ lhs: borrowing T, _ rhs: borrowing T) -> Bool { lhs <= rhs } @@ -80,6 +94,24 @@ NoncopyableComparableTests.test("comparing noncopyables") { expectTrue(array.inReverseOrder()) array.swapAt(1, 2) expectFalse(array.inReverseOrder()) - } +} + +NoncopyableComparableTests.test("comparing nonescapables") { + let a = Noncopyable(wrapped: .init(wrapped: 0)) + let b = Noncopyable(wrapped: .init(wrapped: 1)) + let c = Noncopyable(wrapped: .init(wrapped: 2)) + + expectTrue(a < b) + expectTrue(c > a) + expectFalse(a < a) + expectFalse(a > c) + expectFalse(c <= a) + expectTrue(a <= a) + expectTrue(a < b && b < c) + + expectTrue(a.isLessThan(b)) + expectTrue(isLessOrEqual(a,b)) + expectFalse(b.isLessThan(a)) +} runAllTests()