> On Feb 22, 2017, at 10:20, David Sweeris via swift-evolution 
> <[email protected]> wrote:
> 
> What if we extended that to any type that’s ExpressibleByNilLiteral & 
> Equatable?

Note that this is not how the Unsafe*Pointer optimization works: in that case, 
the type Unsafe*Pointer is not ExpressibleByNilLiteral, it just has some 
spare/guaranteed-to-be-unused sentinel values in its representation, that the 
compiler knows about. This also works for types like `enum X { case A, B }`: an 
optional like X? (and X??, all the way up to 254 ?’s) is also represented as a 
single byte, because there’s spare values that the compiler knows won't be used 
by valid instances of X.

Converting valid instances  to .none would break round-tripping: Optional(x)! 
would sometimes fail, if x was the sentinel value. This seems likely to cause 
generic code to stop working.

Huon



Example program for the enum optimization:

enum X {
    case A, B
}

typealias O2<T> = T??
typealias O4<T> = O2<O2<T>>
typealias O8<T> = O4<O4<T>>
typealias O16<T> = O8<O8<T>>
typealias O32<T> = O16<O16<T>>
typealias O64<T> = O32<O32<T>>
typealias O128<T> = O64<O64<T>>
typealias O256<T> = O128<O128<T>>

typealias O254<T> = O128<O64<O32<O16<O8<O4<O2<T>>>>>>>
typealias O255<T> = O254<T>?

func size<T>(_: T.Type) -> Int {
    return MemoryLayout<T>.size
}

print(size(X.self), // 1
      size((X?).self), // 1
      size(O254<X>.self), // 1
      size(O255<X>.self), // 2
      size(O256<X>.self)) // 3

(The last is 3 because the compiler currently essentially treats O255<X> like 
an opaque/all-values-valid 2-byte type, like Int16, and so adds an extra byte 
for the extra ?. It could theoretically be 2 if the unused values in the extra 
byte in O255<X> are reused.)
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to