Swift NilLiteralConvertible to an initializer requirement

Swift SVN r21980
This commit is contained in:
Doug Gregor
2014-09-16 20:43:35 +00:00
parent f3d1e5f448
commit 7f80e00d37
15 changed files with 73 additions and 59 deletions

View File

@@ -62,7 +62,7 @@ IDENTIFIER_WITH_NAME(MaxBuiltinIntegerType, "_MaxBuiltinIntegerType")
IDENTIFIER(IntegerLiteralType) IDENTIFIER(IntegerLiteralType)
IDENTIFIER_WITH_NAME(AllZeros, "allZeros") IDENTIFIER_WITH_NAME(AllZeros, "allZeros")
IDENTIFIER_WITH_NAME(BoolValue, "boolValue") IDENTIFIER_WITH_NAME(BoolValue, "boolValue")
IDENTIFIER_WITH_NAME(ConvertFromNilLiteral, "convertFromNilLiteral") IDENTIFIER_WITH_NAME(NilLiteral, "nilLiteral")
IDENTIFIER_WITH_NAME(ConvertFromIntegerLiteral, "convertFromIntegerLiteral") IDENTIFIER_WITH_NAME(ConvertFromIntegerLiteral, "convertFromIntegerLiteral")
IDENTIFIER_WITH_NAME(ConvertFromBuiltinIntegerLiteral, IDENTIFIER_WITH_NAME(ConvertFromBuiltinIntegerLiteral,
"_convertFromBuiltinIntegerLiteral") "_convertFromBuiltinIntegerLiteral")

View File

@@ -564,58 +564,71 @@ static void makeOptionSetAllZerosProperty(StructDecl *optionSetDecl,
// Build the NilLiteralConvertible conformance: // Build the NilLiteralConvertible conformance:
// //
// extension NSSomeOptionSet : NilLiteralConvertible { // extension NSSomeOptionSet : NilLiteralConvertible {
// static func convertFromNilLiteral() -> S { // init(nilLiteral: ())
// return S() // self = S()
// } // }
// } // }
static FuncDecl *makeNilLiteralConformance(StructDecl *optionSetDecl, static ConstructorDecl *makeNilLiteralConformance(StructDecl *optionSetDecl,
ValueDecl *valueDecl) { ValueDecl *valueDecl) {
auto &C = optionSetDecl->getASTContext(); auto &C = optionSetDecl->getASTContext();
auto optionSetType = optionSetDecl->getDeclaredTypeInContext(); auto optionSetType = optionSetDecl->getDeclaredTypeInContext();
VarDecl *selfDecl = createSelfDecl(optionSetDecl, true); VarDecl *selfDecl = createSelfDecl(optionSetDecl, /*staticMethod=*/false);
Pattern *selfParam = createTypedNamedPattern(selfDecl); Pattern *selfParam = createTypedNamedPattern(selfDecl);
Pattern *methodParam = TuplePattern::create(C, SourceLoc(),{},SourceLoc());
methodParam->setType(TupleType::getEmpty(C));
Pattern *params[] = {selfParam, methodParam};
Identifier baseName = C.getIdentifier("convertFromNilLiteral"); VarDecl *nilDecl = new (C) ParamDecl(/*isLet=*/true, SourceLoc(),
C.Id_NilLiteral, SourceLoc(),
DeclName name(C, baseName, { }); Identifier(),
auto factoryDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, TupleType::getEmpty(C),
SourceLoc(), optionSetDecl);
name, Pattern *nilParam = createTypedNamedPattern(nilDecl);
SourceLoc(), nullptr, Type(), params, Pattern *methodParam = TuplePattern::create(C, SourceLoc(),
TypeLoc::withoutLoc(optionSetType), { TuplePatternElt(nilParam) },
optionSetDecl); SourceLoc());
methodParam->setType(ParenType::get(C, nilParam->getType()));
factoryDecl->setStatic();
factoryDecl->setImplicit();
factoryDecl->setAccessibility(Accessibility::Public);
Type factoryType = FunctionType::get(TupleType::getEmpty(C), optionSetType); DeclName initName(C, C.Id_init, { C.Id_NilLiteral });
factoryType = FunctionType::get(selfDecl->getType(), factoryType); auto initDecl = new (C) ConstructorDecl(initName, SourceLoc(), OTK_None,
factoryDecl->setType(factoryType); SourceLoc(), selfParam, methodParam,
factoryDecl->setBodyResultType(optionSetType); nullptr, optionSetDecl);
initDecl->setImplicit();
initDecl->setAccessibility(Accessibility::Public);
Type metaType = MetatypeType::get(optionSetType);
Type paramType = TupleType::get({ TupleTypeElt(methodParam->getType(),
C.Id_NilLiteral) },
C);
Type fnType = FunctionType::get(paramType, optionSetType);
Type allocFnType = FunctionType::get(metaType, fnType);
Type initFnType = FunctionType::get(optionSetType, fnType);
initDecl->setType(allocFnType);
initDecl->setInitializerType(initFnType);
// Form the body of the initializer.
auto *ctorRef = new (C) DeclRefExpr(ConcreteDeclRef(optionSetDecl), auto *ctorRef = new (C) DeclRefExpr(ConcreteDeclRef(optionSetDecl),
SourceLoc(), /*implicit*/ true); SourceLoc(), /*implicit*/ true);
auto *arg = TupleExpr::createEmpty(C, SourceLoc(), SourceLoc(), auto *arg = TupleExpr::createEmpty(C, SourceLoc(), SourceLoc(),
/*implicit*/ true); /*implicit*/ true);
auto *ctorCall = new (C) CallExpr(ctorRef, arg, /*implicit*/ true); auto *ctorCall = new (C) CallExpr(ctorRef, arg, /*implicit*/ true);
auto *ctorRet = new (C) ReturnStmt(SourceLoc(), ctorCall, /*implicit*/ true);
auto selfRef = new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/ true,
/*UsesDirectPropertyAccess=*/false,
selfDecl->getType());
auto *assign = new (C) AssignExpr(selfRef, SourceLoc(), ctorCall,
/*implicit*/ true);
auto body = BraceStmt::create(C, SourceLoc(), auto body = BraceStmt::create(C, SourceLoc(),
ASTNode(ctorRet), ASTNode(assign),
SourceLoc(), SourceLoc(),
/*implicit*/ true); /*implicit*/ true);
factoryDecl->setBody(body); initDecl->setBody(body);
// Add as an external definition. // Add as an external definition.
C.addedExternalDecl(factoryDecl); C.addedExternalDecl(initDecl);
return factoryDecl; return initDecl;
} }
// Build the default initializer for an option set. // Build the default initializer for an option set.

View File

@@ -1318,9 +1318,11 @@ namespace {
if (defaultType->isEqual(type)) if (defaultType->isEqual(type))
type = defaultType; type = defaultType;
} }
DeclName initName(tc.Context, tc.Context.Id_init,
{ tc.Context.Id_NilLiteral });
return convertLiteral(expr, type, expr->getType(), protocol, return convertLiteral(expr, type, expr->getType(), protocol,
Identifier(), tc.Context.Id_ConvertFromNilLiteral, Identifier(), initName,
nullptr, Identifier(), nullptr, Identifier(),
Identifier(), Identifier(),
[] (Type type) -> bool { [] (Type type) -> bool {

View File

@@ -401,8 +401,8 @@ public struct AutoreleasingUnsafeMutablePointer<T /* TODO : class */>
} }
@transparent public @transparent public
static func convertFromNilLiteral() -> AutoreleasingUnsafeMutablePointer { init(nilLiteral: ()) {
return AutoreleasingUnsafeMutablePointer(_nilRawPointer) value = _nilRawPointer
} }
@transparent public @transparent public

View File

@@ -81,7 +81,7 @@ public struct COpaquePointer : Equatable, Hashable, NilLiteralConvertible {
@transparent @transparent
public init() { public init() {
value = Builtin.inttoptr_Word(0.value) value = _nilRawPointer
} }
@transparent @transparent
@@ -133,8 +133,8 @@ public struct COpaquePointer : Equatable, Hashable, NilLiteralConvertible {
} }
@transparent public @transparent public
static func convertFromNilLiteral() -> COpaquePointer { init(nilLiteral: ()) {
return COpaquePointer() value = _nilRawPointer
} }
} }
@@ -168,8 +168,8 @@ public struct CFunctionPointer<T> : Equatable, Hashable, NilLiteralConvertible {
} }
@transparent public @transparent public
static func convertFromNilLiteral() -> CFunctionPointer { init(nilLiteral: ()) {
return CFunctionPointer() value = COpaquePointer()
} }
} }

View File

@@ -204,7 +204,7 @@ public protocol RawOptionSetType : _RawOptionSetType, BitwiseOperationsType,
/// Conforming to this protocol allows a type to be usable with the 'nil' /// Conforming to this protocol allows a type to be usable with the 'nil'
/// literal. /// literal.
public protocol NilLiteralConvertible { public protocol NilLiteralConvertible {
class func convertFromNilLiteral() -> Self init(nilLiteral: ())
} }
public protocol _BuiltinIntegerLiteralConvertible { public protocol _BuiltinIntegerLiteralConvertible {

View File

@@ -34,8 +34,8 @@ public enum ImplicitlyUnwrappedOptional<T>
// Make nil work with ImplicitlyUnwrappedOptional // Make nil work with ImplicitlyUnwrappedOptional
@transparent public @transparent public
static func convertFromNilLiteral() -> ImplicitlyUnwrappedOptional<T> { init(nilLiteral: ()) {
return .None self = .None
} }
/// Haskell's fmap, which was mis-named /// Haskell's fmap, which was mis-named

View File

@@ -37,8 +37,8 @@ public enum Optional<T> : Reflectable, NilLiteralConvertible {
} }
@transparent @transparent
public static func convertFromNilLiteral() -> Optional<T> { public init(nilLiteral: ()) {
return .None self = .None
} }
} }
@@ -131,8 +131,7 @@ public func != <T: Equatable> (lhs: T?, rhs: T?) -> Bool {
// isn't equatable. // isn't equatable.
public struct _OptionalNilComparisonType : NilLiteralConvertible { public struct _OptionalNilComparisonType : NilLiteralConvertible {
@transparent @transparent
public static func convertFromNilLiteral() -> _OptionalNilComparisonType { public init(nilLiteral: ()) {
return _OptionalNilComparisonType()
} }
} }
@transparent public @transparent public

View File

@@ -95,8 +95,8 @@ public struct ${Self}<T>
// Make nil work with ${Self}. // Make nil work with ${Self}.
@transparent public @transparent public
static func convertFromNilLiteral() -> ${Self}<T> { init(nilLiteral: ()) {
return .null() self = .null()
} }
@transparent @transparent

View File

@@ -121,8 +121,8 @@ public struct Selector : StringLiteralConvertible, NilLiteralConvertible {
} }
@transparent public @transparent public
static func convertFromNilLiteral() -> Selector { init(nilLiteral: ()) {
return Selector() ptr = nil
} }
} }
@@ -170,8 +170,8 @@ public struct NSZone : NilLiteralConvertible {
public init() { pointer = nil } public init() { pointer = nil }
@transparent public @transparent public
static func convertFromNilLiteral() -> NSZone { init(nilLiteral: ()) {
return NSZone() pointer = nil
} }
} }

View File

@@ -39,7 +39,7 @@ struct <loc>FooRuncingOptions</loc> : <ref:Protocol>RawOptionSetType</ref> {
<decl:Var>static var <loc>EnableMince</loc>: <ref:Struct>FooRuncingOptions</ref> { get }</decl> <decl:Var>static var <loc>EnableMince</loc>: <ref:Struct>FooRuncingOptions</ref> { get }</decl>
<decl:Var>static var <loc>EnableQuince</loc>: <ref:Struct>FooRuncingOptions</ref> { get }</decl> <decl:Var>static var <loc>EnableQuince</loc>: <ref:Struct>FooRuncingOptions</ref> { get }</decl>
<decl:Var>static var <loc>allZeros</loc>: <ref:Struct>FooRuncingOptions</ref> { get }</decl> <decl:Var>static var <loc>allZeros</loc>: <ref:Struct>FooRuncingOptions</ref> { get }</decl>
<decl:Func>static func <loc>convertFromNilLiteral()</loc> -> <ref:Struct>FooRuncingOptions</ref></decl> <decl:Constructor><loc>init(nilLiteral _: ())</loc></decl>
}</decl> }</decl>
<decl:Struct>struct <loc>FooStruct1</loc> { <decl:Struct>struct <loc>FooStruct1</loc> {
<decl:Var>var <loc>x</loc>: <ref:Struct>Int32</ref></decl> <decl:Var>var <loc>x</loc>: <ref:Struct>Int32</ref></decl>

View File

@@ -39,7 +39,7 @@ struct FooRuncingOptions : RawOptionSetType {
static var EnableMince: FooRuncingOptions { get } static var EnableMince: FooRuncingOptions { get }
static var EnableQuince: FooRuncingOptions { get } static var EnableQuince: FooRuncingOptions { get }
static var allZeros: FooRuncingOptions { get } static var allZeros: FooRuncingOptions { get }
static func convertFromNilLiteral() -> FooRuncingOptions init(nilLiteral _: ())
} }
struct FooStruct1 { struct FooStruct1 {
var x: Int32 var x: Int32

View File

@@ -52,7 +52,7 @@ struct FooRuncingOptions : RawOptionSetType {
static var EnableMince: FooRuncingOptions { get } static var EnableMince: FooRuncingOptions { get }
static var EnableQuince: FooRuncingOptions { get } /* But this is quince */ static var EnableQuince: FooRuncingOptions { get } /* But this is quince */
static var allZeros: FooRuncingOptions { get } static var allZeros: FooRuncingOptions { get }
static func convertFromNilLiteral() -> FooRuncingOptions init(nilLiteral _: ())
} }
struct FooStruct1 { struct FooStruct1 {

View File

@@ -79,7 +79,7 @@
// FOUNDATION-NEXT: {{^}} static var EnableMince: NSRuncingOptions { get }{{$}} // FOUNDATION-NEXT: {{^}} static var EnableMince: NSRuncingOptions { get }{{$}}
// FOUNDATION-NEXT: {{^}} static var EnableQuince: NSRuncingOptions { get }{{$}} // FOUNDATION-NEXT: {{^}} static var EnableQuince: NSRuncingOptions { get }{{$}}
// FOUNDATION-NEXT: {{^}} static var allZeros: NSRuncingOptions { get }{{$}} // FOUNDATION-NEXT: {{^}} static var allZeros: NSRuncingOptions { get }{{$}}
// FOUNDATION-NEXT: {{^}} static func convertFromNilLiteral() -> NSRuncingOptions{{$}} // FOUNDATION-NEXT: {{^}} init(nilLiteral _: ()){{$}}
// FOUNDATION-NEXT: {{^}}}{{$}} // FOUNDATION-NEXT: {{^}}}{{$}}
// FOUNDATION-LABEL: {{^}}/// Unavailable Global Functions{{$}} // FOUNDATION-LABEL: {{^}}/// Unavailable Global Functions{{$}}

View File

@@ -62,8 +62,8 @@ public struct NSZone: NilLiteralConvertible {
public var pointer : COpaquePointer public var pointer : COpaquePointer
@transparent public @transparent public
static func convertFromNilLiteral() -> NSZone { init(nilLiteral: ()) {
return NSZone(pointer: COpaquePointer()) pointer = COpaquePointer()
} }
} }