public struct DivisibilityIterator<Element: BinaryInteger> where Element.Magnitude == Element {
enum State {
case zero
case one
case other(divisor: Element, dividend: Element)
}
var state: State
init<T: BinaryInteger>(divisor: T, firstDividend: T) where T.Magnitude == Element {
let absoluteDivisor = divisor.magnitude
switch absoluteDivisor {
case 0:
state = .zero // 1
case 1:
state = .one // 1
default:
let reducedDividend = firstDividend % divisor
let absoluteDividend: Element
if reducedDividend < 0 {
absoluteDividend = absoluteDivisor - reducedDividend.magnitude // 2
} else {
absoluteDividend = reducedDividend.magnitude // 2
}
state = .other(absoluteDivisor, absoluteDividend) // 1
}
}
}
The errors at 1 are: "'DivisibilityIterator' requires the types 'Element' and 'Element.Magnitude' be equivalent". The ones at 2 are: "Cannot assign value of type 'T.Magnitude' to type 'Element'", with a fix-it of: "Insert ' as! Element'".
Error 1 makes no sense because it's completely irrelevant to what I'm doing there! Error 2 makes no sense because the initializer's where clause already requires the types to be the same. Is there some subtle rules of Swift I'm missing in either case?
I tried moving the State type to a separate enum generic type; got the same error. I closed the playground window, quit Xcode, and reopened both; didn't help. I haven't rebooted the computer (yet). That has helped in the past, but it's totally unacceptable that the Playgrounds system is that fragile to need that workaround, especially that there's no guarantee that it'll work.
struct Foo<Element: BinaryInteger> where Element.Magnitude == Element {
var value: Int
init<T: BinaryInteger>(divisor: T) where T.Magnitude == Element {
value = 1 /* 'Foo<Element>' requires the types 'Element' and 'Element.Magnitude' be equivalent */
}
}
Looks like T.Magnitude == Element makes compiler forget the Element constraint, or something. It looks like a bug.