- Proposal: SE-NNNN
- Authors: Anton Zhilin
- Review Manager: TBD
- Status: Awaiting review
Change nil
literal type from ()
to Nil
.
Before:
public protocol ExpressibleByNilLiteral {
init(nilLiteral: ())
}
After:
public struct Nil {
init()
}
public protocol ExpressibleByNilLiteral {
associatedtype NilLiteralType = Nil
init(nilLiteral: NilLiteralType)
}
Swift-evolution thread: Discussion thread topic for that proposal
Currently, nil
differs from other literals: it doesn't have its own type.
But in some cases we want to deal directly with it, without creating any instances.
The most important use case is comparison of an Optional
to nil
.
Currently, this operation is implemented using a hidden struct _OptionalNilComparisonType
,
which is needed precisely because because nil
does not have its own type.
Removal of such underscored types is one of the goals stated in Generics manifesto.
Additionally, declaration of ExpressibleByNilLiteral
differs from all other Expressible
s,
because it doesn't have a Literal
type. It is generally beneficial to eliminate special cases.
Introduce a struct Nil
, which becomes the default type for nil
literals:
public struct Nil : ExpressibleByNilLiteral {
init()
init(nilLiteral: NilLiteralType)
}
let a = nil
print(type(of: a)) //=> Nil
Rewrite ExpressibleByNilLiteral
:
public protocol ExpressibleByNilLiteral {
associatedtype NilLiteralType = Nil
init(nilLiteral: NilLiteralType)
}
Make use of Nil
in the standard library:
public func == <T>(left: T?, right: Nil)
public func == <T>(left: Nil, right: T?)
public func != <T>(left: T?, right: Nil)
public func != <T>(left: Nil, right: T?)
public func ~= <T>(left: Nil, right: T?)
Nil
identifier is taken, therefore applications that already use it will stop compiling.
Automatic migration is somewhat possible by renaming of the old entity; manual migration is recommended.
Applications that use declare ExpressibleByNilLiteral
conformances will stop compiling.
Automatic migration is possible.
Applications that use Nil
identifier will have to make ABI-breaking changes.
Otherwise, the change can mostly be applied in an ABI-compatible manner.