Files
swift-mirror/test/stdlib/BinaryIntegerRequirements.swift
Max Moiseev bfddc4a763 [stdlib] Make default implementations of bitwise operators as obsoleted
Fixes: https://bugs.swift.org/browse/SR-7019

Prior to Swift 4 and the new integers, there was a protocol called
`BitwiseOperations`. It was deemed not needed with the introduction of
the integer protocols. But, for backward compatibility, it was left in
the standard library as `_BitwiseOperations` with a conditionally
available typealias `BitwiseOperations`. That protocol declares only the
"non-muating" operators, the mutating ones (i.e. `|=` and friends) are
defined as free functions. They are implemented in terms of
`_BitwiseOperations` protocol requirements, which is reasonable.

In the new integer protocols we established a
convention to provide default implementations for non-mutating functions
in terms of mutating ones (exactly the opposite of a much earlier
decision made for `BitwiseOperations`). So now, when you define a type
that conforms to the `FixedWidthInteger`, even though both mutating and
non-mutating bitwise operations are required, the default implementation
of `|` comes from extension FixedWidthInteger, and the default
implementation of `|=` comes from the _BitwiseOperations free functions.
And they are mutually recursive. Hence the crash.

This commit breaks the recursion by marking default implementations for
`|` etc. in `_BitwiseOperations` obsoleted from Swift 4.1 onward. The
test is also added to make sure the change helps.
2018-02-20 16:31:20 -08:00

62 lines
3.2 KiB
Swift

// RUN: %swift -swift-version 4 -typecheck -verify %s
struct MyInt: FixedWidthInteger { // expected-error {{type 'MyInt' does not conform to protocol 'BinaryInteger'}}
typealias IntegerLiteralType = Int
static let isSigned = false
init(integerLiteral value: Int) { fatalError() }
init(_truncatingBits bits: UInt) { fatalError() }
init<T : BinaryFloatingPoint>(_ source: T) { fatalError() }
init?<T : BinaryFloatingPoint>(exactly source: T) { fatalError() }
init<T : BinaryInteger>(_ source: T) { fatalError() }
init?<T : BinaryInteger>(exactly source: T) { fatalError() }
init<T : BinaryInteger>(truncatingIfNeeded source: T) { fatalError() }
init<T : BinaryInteger>(clamping source: T) { fatalError() }
let words = [UInt]()
let _lowWord: UInt = 0
static var bitWidth: Int { fatalError() }
var trailingZeroBitCount: Int { fatalError() }
static func /=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
static func /(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
static func %=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
static func %(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
static func +=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
static func +(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
static func -=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
static func -(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
static func *=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
static func *(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
static func ==(_ lhs: MyInt, _ rhs: MyInt) -> Bool { fatalError() }
static func <(_ lhs: MyInt, _ rhs: MyInt) -> Bool { fatalError() }
static prefix func ~ (_ x: MyInt) -> MyInt { fatalError() }
static func >><RHS: BinaryInteger>(_ lhs: MyInt, _ rhs: RHS) -> MyInt { fatalError() }
static func >>=<RHS: BinaryInteger>(_ lhs: inout MyInt, _ rhs: RHS) { fatalError() }
static func <<<RHS: BinaryInteger>(_ lhs: MyInt, _ rhs: RHS) -> MyInt { fatalError() }
static func <<=<RHS: BinaryInteger>(_ lhs: inout MyInt, _ rhs: RHS) { fatalError() }
func quotientAndRemainder(dividingBy rhs: MyInt) -> (quotient: MyInt, remainder: MyInt) { fatalError() }
func signum() -> MyInt { fatalError() }
var hashValue: Int { fatalError() }
var byteSwapped: MyInt { fatalError() }
static var max: MyInt { fatalError() }
static var min: MyInt { fatalError() }
func addingReportingOverflow(_ rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
func subtractingReportingOverflow(_ rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
func multipliedReportingOverflow(by rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
func dividedReportingOverflow(by rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
func remainderReportingOverflow(dividingBy rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
func multipliedFullWidth(by other: MyInt) -> (high: MyInt, low: Magnitude) { fatalError() }
func dividingFullWidth(_ dividend: (high: MyInt, low: Magnitude)) -> (quotient: MyInt, remainder: MyInt) { fatalError() }
var nonzeroBitCount: Int { fatalError() }
var leadingZeroBitCount: Int { fatalError() }
var magnitude: UInt { fatalError() }
}