mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
62 lines
3.2 KiB
Swift
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() }
|
|
}
|