Files
swift-mirror/validation-test/stdlib/InvalidStrideable.swift
Robert Widmann d0bc2a8611 Custom message for recursive Strideable witness
Strideable declares a default witness for Equatable and Comparable

extension Strideable {
  @_inlineable
  public static func < (x: Self, y: Self) -> Bool {
    return x.distance(to: y) > 0
  }

  @_inlineable
  public static func == (x: Self, y: Self) -> Bool {
    return x.distance(to: y) == 0
  }
}

This witness is implemented recursively because the expectation
is that Stride != Self.  However, it is possible to implement
SignedNumeric and Strideable together and inherit this conformance
which will cause undefined behavior - usually a crash.

Provide an overload when Stride == Self and crash with custom message
that mentions that Equatable and Comparable have to be implemented
in this case.

- It's better than nothing.
2017-09-15 12:31:09 -04:00

44 lines
2.0 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift -emit-executable -DTEST_EQUATABLE -o %t/InvalidStrideableEq %s
// RUN: ! %target-run %t/InvalidStrideableEq 2>&1 | %FileCheck %s --check-prefix=CHECK-EQUATABLE
// RUN: %target-build-swift -emit-executable -DTEST_COMPARABLE -o %t/InvalidStrideableCmp %s
// RUN: ! %target-run %t/InvalidStrideableCmp 2>&1 | %FileCheck %s --check-prefix=CHECK-COMPARABLE
// REQUIRES: executable_test
//
// Check that a circular Strideable inheriting witnesses from Stdlib crashes
// with a rich error message.
//
struct InvalidStrideable : Strideable, SignedNumeric {
typealias Magnitude = InvalidStrideable
init?<T>(exactly: T) where T : BinaryInteger { return nil }
var magnitude: InvalidStrideable { return self }
static func += (lhs: inout InvalidStrideable, rhs: InvalidStrideable) { }
static func -= (lhs: inout InvalidStrideable, rhs: InvalidStrideable) { }
static func *= (lhs: inout InvalidStrideable, rhs: InvalidStrideable) { }
static func + (lhs: InvalidStrideable, rhs: InvalidStrideable) -> InvalidStrideable { return rhs }
static func - (lhs: InvalidStrideable, rhs: InvalidStrideable) -> InvalidStrideable { return rhs }
static func * (lhs: InvalidStrideable, rhs: InvalidStrideable) -> InvalidStrideable { return rhs }
typealias IntegerLiteralType = Int
init(integerLiteral : Int) {}
typealias Stride = InvalidStrideable
init() {}
func distance(to rhs: InvalidStrideable) -> InvalidStrideable { return self }
func advanced(by n: InvalidStrideable) -> InvalidStrideable { return self }
}
#if TEST_EQUATABLE
// CHECK-EQUATABLE: fatal error: Strideable conformance where 'Stride == Self' requires user-defined implementation of the '==' operator
_ = InvalidStrideable() == InvalidStrideable()
#else
// CHECK-COMPARABLE: fatal error: Strideable conformance where 'Stride == Self' requires user-defined implementation of the '<' operator
_ = InvalidStrideable() < InvalidStrideable() // Will trap with error message
#endif