Last active
March 2, 2018 01:25
-
-
Save omochi/af63493d713074428e2fa6a78f0cb491 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol P1 { | |
init() | |
} | |
protocol P2 { | |
init() | |
} | |
struct S { | |
func a<T: P1>(_ type: T.Type) -> T { | |
return a(type) ?? type.init() | |
} | |
private func a<T>(_ type: T.Type) -> T? { | |
guard let p2Type = type as? P2.Type else { return nil } | |
return p2Type.init() as? T | |
} | |
} | |
extension Int: P1 {} | |
S().a(Int.self) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(source_file | |
(protocol "P1" <Self : P1> interface type='P1.Protocol' access=internal @_fixed_layout requirement signature=<Self> | |
(constructor_decl "init()" interface type='<Self where Self : P1> (Self.Type) -> () -> Self' access=internal designated | |
(parameter_list | |
(parameter "self" type='inout Self' interface type='inout Self' mutable)) | |
(parameter_list))) | |
(protocol "P2" <Self : P2> interface type='P2.Protocol' access=internal @_fixed_layout requirement signature=<Self> | |
(constructor_decl "init()" interface type='<Self where Self : P2> (Self.Type) -> () -> Self' access=internal designated | |
(parameter_list | |
(parameter "self" type='inout Self' interface type='inout Self' mutable)) | |
(parameter_list))) | |
(struct_decl "S" interface type='S.Type' access=internal @_fixed_layout | |
(func_decl "a(_:)" <T : P1> interface type='<T where T : P1> (S) -> (T.Type) -> T' access=internal captures=(<generic> ) | |
(parameter_list | |
(parameter "self" type='S' interface type='S')) | |
(parameter_list | |
(parameter "type" type='T.Type' interface type='T.Type')) | |
(result | |
(type_ident | |
(component id='T' bind=a.(file).S.a(_:).T@a.swift:11:12))) | |
(brace_stmt | |
(return_stmt | |
(binary_expr type='T' location=a.swift:12:24 range=[a.swift:12:16 - line:12:37] nothrow | |
(declref_expr type='(T?, @autoclosure () throws -> T) throws -> T' location=a.swift:12:24 range=[a.swift:12:24 - line:12:24] decl=Swift.(file).?? [with T] function_ref=unapplied) | |
(tuple_expr implicit type='(T?, @autoclosure () throws -> T)' location=a.swift:12:16 range=[a.swift:12:16 - line:12:37] | |
(inject_into_optional implicit type='T?' location=a.swift:12:16 range=[a.swift:12:16 - line:12:22] | |
(call_expr type='T' location=a.swift:12:16 range=[a.swift:12:16 - line:12:22] nothrow arg_labels=_: | |
(dot_syntax_call_expr implicit type='(T.Type) -> T' location=a.swift:12:16 range=[a.swift:12:16 - line:12:16] nothrow | |
(declref_expr type='(S) -> (T.Type) -> T' location=a.swift:12:16 range=[a.swift:12:16 - line:12:16] decl=a.(file).S.a@a.swift:11:10 [with T[abstract:P1]] function_ref=double) | |
(declref_expr implicit type='S' location=a.swift:12:16 range=[a.swift:12:16 - line:12:16] decl=a.(file).S.a(_:).self@a.swift:11:10 function_ref=unapplied)) | |
(paren_expr type='(T.Type)' location=a.swift:12:18 range=[a.swift:12:17 - line:12:22] | |
(declref_expr type='T.Type' location=a.swift:12:18 range=[a.swift:12:18 - line:12:18] decl=a.(file).S.a(_:).type@a.swift:11:21 function_ref=unapplied)))) | |
(autoclosure_expr implicit type='() throws -> T' location=a.swift:12:27 range=[a.swift:12:27 - line:12:37] discriminator=0 captures=(<generic> type<noescape>) | |
(parameter_list) | |
(call_expr type='T' location=a.swift:12:32 range=[a.swift:12:27 - line:12:37] nothrow arg_labels= | |
(constructor_ref_call_expr type='() -> T' location=a.swift:12:32 range=[a.swift:12:27 - line:12:32] nothrow | |
(declref_expr type='(T.Type) -> () -> T' location=a.swift:12:32 range=[a.swift:12:32 - line:12:32] decl=a.(file).P1.init()@a.swift:3:5 [with T[abstract:P1]] function_ref=double) | |
(declref_expr type='T.Type' location=a.swift:12:27 range=[a.swift:12:27 - line:12:27] decl=a.(file).S.a(_:).type@a.swift:11:21 function_ref=unapplied)) | |
(tuple_expr type='()' location=a.swift:12:36 range=[a.swift:12:36 - line:12:37])))))))) | |
(func_decl "a(_:)" <T> interface type='<T> (S) -> (T.Type) -> T?' access=private captures=(<generic> ) | |
(parameter_list | |
(parameter "self" type='S' interface type='S')) | |
(parameter_list | |
(parameter "type" type='T.Type' interface type='T.Type')) | |
(result | |
) | |
(brace_stmt | |
(guard_stmt | |
(pattern | |
(optional_some_element implicit type='P2.Type?' | |
(pattern_let implicit type='P2.Type' | |
(pattern_named type='P2.Type' 'p2Type'))) | |
(conditional_checked_cast_expr type='P2.Type?' location=a.swift:16:33 range=[a.swift:16:28 - line:16:40] value_cast writtenType='P2.Type' | |
(declref_expr type='T.Type' location=a.swift:16:28 range=[a.swift:16:28 - line:16:28] decl=a.(file).S.a(_:).type@a.swift:15:25 function_ref=unapplied))) | |
(brace_stmt | |
(return_stmt | |
(call_expr implicit type='T?' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] nothrow arg_labels=nilLiteral: | |
(constructor_ref_call_expr implicit type='(()) -> T?' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] nothrow | |
(declref_expr implicit type='(Optional<T>.Type) -> (()) -> Optional<T>' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] decl=Swift.(file).Optional.init(nilLiteral:) [with T] function_ref=single) | |
(type_expr implicit type='T?.Type' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] typerepr='T?')) | |
(tuple_expr implicit type='(nilLiteral: ())' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] names=nilLiteral | |
(tuple_expr type='()' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59])))))) | |
(return_stmt | |
(conditional_checked_cast_expr type='T?' location=a.swift:17:30 range=[a.swift:17:16 - line:17:34] value_cast writtenType='T' | |
(open_existential_expr implicit type='P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:28] | |
(opaque_value_expr implicit type='(P2).Type' location=a.swift:17:16 range=[a.swift:17:16 - line:17:16] @ 0x7fccb28c2660) | |
(declref_expr type='P2.Type' location=a.swift:17:16 range=[a.swift:17:16 - line:17:16] decl=a.(file).S.a(_:).p2Type@a.swift:16:19 function_ref=unapplied) | |
(erasure_expr implicit type='P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:28] | |
(abstract_conformance protocol=P2) | |
(call_expr type='P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:28] nothrow arg_labels= | |
(constructor_ref_call_expr type='() -> P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:23] nothrow | |
(declref_expr type='((P2).Type) -> () -> P2' location=a.swift:17:23 range=[a.swift:17:23 - line:17:23] decl=a.(file).P2.init()@a.swift:7:5 [with P2[abstract:P2]] function_ref=double) | |
(opaque_value_expr implicit type='(P2).Type' location=a.swift:17:16 range=[a.swift:17:16 - line:17:16] @ 0x7fccb28c2660)) | |
(tuple_expr type='()' location=a.swift:17:27 range=[a.swift:17:27 - line:17:28])))))))) | |
(constructor_decl implicit "init()" interface type='(S.Type) -> () -> S' access=internal designated | |
(parameter_list | |
(parameter "self" type='inout S' interface type='inout S' mutable)) | |
(parameter_list) | |
(brace_stmt | |
(return_stmt implicit)))) | |
(extension_decl Int inherits: P1) | |
(top_level_code_decl | |
(brace_stmt | |
(call_expr type='Int' location=a.swift:22:5 range=[a.swift:22:1 - line:22:15] nothrow arg_labels=_: | |
(dot_syntax_call_expr type='(Int.Type) -> Int' location=a.swift:22:5 range=[a.swift:22:1 - line:22:5] nothrow | |
(declref_expr type='(S) -> (Int.Type) -> Int' location=a.swift:22:5 range=[a.swift:22:5 - line:22:5] decl=a.(file).S.a@a.swift:11:10 [with Int[Int: P1 module a]] function_ref=single) | |
(call_expr type='S' location=a.swift:22:1 range=[a.swift:22:1 - line:22:3] nothrow arg_labels= | |
(constructor_ref_call_expr type='() -> S' location=a.swift:22:1 range=[a.swift:22:1 - line:22:1] nothrow | |
(declref_expr implicit type='(S.Type) -> () -> S' location=a.swift:22:1 range=[a.swift:22:1 - line:22:1] decl=a.(file).S.init()@a.swift:10:8 function_ref=single) | |
(type_expr type='S.Type' location=a.swift:22:1 range=[a.swift:22:1 - line:22:1] typerepr='S')) | |
(tuple_expr type='()' location=a.swift:22:2 range=[a.swift:22:2 - line:22:3]))) | |
(paren_expr type='(Int.Type)' location=a.swift:22:7 range=[a.swift:22:6 - line:22:15] | |
(dot_self_expr type='Int.Type' location=a.swift:22:7 range=[a.swift:22:7 - line:22:11] | |
(type_expr type='Int.Type' location=a.swift:22:7 range=[a.swift:22:7 - line:22:7] typerepr='Int'))))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(source_file | |
(protocol "P1" <Self : P1> interface type='P1.Protocol' access=internal @_fixed_layout requirement signature=<Self> | |
(constructor_decl "init()" interface type='<Self where Self : P1> (Self.Type) -> () -> Self' access=internal designated | |
(parameter_list | |
(parameter "self" type='inout Self' interface type='inout Self' inout)) | |
(parameter_list))) | |
(protocol "P2" <Self : P2> interface type='P2.Protocol' access=internal @_fixed_layout requirement signature=<Self> | |
(constructor_decl "init()" interface type='<Self where Self : P2> (Self.Type) -> () -> Self' access=internal designated | |
(parameter_list | |
(parameter "self" type='inout Self' interface type='inout Self' inout)) | |
(parameter_list))) | |
(struct_decl "S" interface type='S.Type' access=internal @_fixed_layout | |
(func_decl "a(_:)" <T : P1> interface type='<T where T : P1> (S) -> (T.Type) -> T' access=internal captures=(<generic> ) | |
(parameter_list | |
(parameter "self" type='S' interface type='S')) | |
(parameter_list | |
(parameter "type" type='T.Type' interface type='T.Type')) | |
(result | |
(type_ident | |
(component id='T' bind=a.(file).S.a(_:).T@a.swift:11:12))) | |
(brace_stmt | |
(return_stmt | |
(binary_expr type='T' location=a.swift:12:24 range=[a.swift:12:16 - line:12:37] nothrow | |
(declref_expr type='(T?, @autoclosure () throws -> T) throws -> T' location=a.swift:12:24 range=[a.swift:12:24 - line:12:24] decl=Swift.(file).?? [with T] function_ref=unapplied) | |
(tuple_expr implicit type='(T?, @autoclosure () throws -> T)' location=a.swift:12:16 range=[a.swift:12:16 - line:12:37] | |
(call_expr type='T?' location=a.swift:12:16 range=[a.swift:12:16 - line:12:22] nothrow arg_labels=_: | |
(dot_syntax_call_expr implicit type='(T.Type) -> T?' location=a.swift:12:16 range=[a.swift:12:16 - line:12:16] nothrow | |
(declref_expr type='(S) -> (T.Type) -> T?' location=a.swift:12:16 range=[a.swift:12:16 - line:12:16] decl=a.(file).S.a@a.swift:15:18 [with T] function_ref=double) | |
(declref_expr implicit type='S' location=a.swift:12:16 range=[a.swift:12:16 - line:12:16] decl=a.(file).S.a(_:).self@a.swift:11:10 function_ref=unapplied)) | |
(paren_expr type='(T.Type)' location=a.swift:12:18 range=[a.swift:12:17 - line:12:22] | |
(declref_expr type='T.Type' location=a.swift:12:18 range=[a.swift:12:18 - line:12:18] decl=a.(file).S.a(_:).type@a.swift:11:21 function_ref=unapplied))) | |
(autoclosure_expr implicit type='() throws -> T' location=a.swift:12:27 range=[a.swift:12:27 - line:12:37] discriminator=0 captures=(<generic> type<noescape>) | |
(parameter_list) | |
(call_expr type='T' location=a.swift:12:32 range=[a.swift:12:27 - line:12:37] nothrow arg_labels= | |
(constructor_ref_call_expr type='() -> T' location=a.swift:12:32 range=[a.swift:12:27 - line:12:32] nothrow | |
(declref_expr type='(T.Type) -> () -> T' location=a.swift:12:32 range=[a.swift:12:32 - line:12:32] decl=a.(file).P1.init()@a.swift:3:5 [with T[abstract:P1]] function_ref=double) | |
(declref_expr type='T.Type' location=a.swift:12:27 range=[a.swift:12:27 - line:12:27] decl=a.(file).S.a(_:).type@a.swift:11:21 function_ref=unapplied)) | |
(tuple_expr type='()' location=a.swift:12:36 range=[a.swift:12:36 - line:12:37])))))))) | |
(func_decl "a(_:)" <T> interface type='<T> (S) -> (T.Type) -> T?' access=private captures=(<generic> ) | |
(parameter_list | |
(parameter "self" type='S' interface type='S')) | |
(parameter_list | |
(parameter "type" type='T.Type' interface type='T.Type')) | |
(result | |
) | |
(brace_stmt | |
(guard_stmt | |
(pattern | |
(optional_some_element implicit type='P2.Type?' | |
(pattern_let implicit type='P2.Type' | |
(pattern_named type='P2.Type' 'p2Type'))) | |
(conditional_checked_cast_expr type='P2.Type?' location=a.swift:16:33 range=[a.swift:16:28 - line:16:40] value_cast writtenType='P2.Type' | |
(declref_expr type='T.Type' location=a.swift:16:28 range=[a.swift:16:28 - line:16:28] decl=a.(file).S.a(_:).type@a.swift:15:25 function_ref=unapplied))) | |
(brace_stmt | |
(return_stmt | |
(call_expr implicit type='T?' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] nothrow arg_labels=nilLiteral: | |
(constructor_ref_call_expr implicit type='(()) -> T?' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] nothrow | |
(declref_expr implicit type='(Optional<T>.Type) -> (()) -> Optional<T>' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] decl=Swift.(file).Optional.init(nilLiteral:) [with T] function_ref=single) | |
(type_expr implicit type='T?.Type' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] typerepr='T?')) | |
(tuple_expr implicit type='(nilLiteral: ())' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59] names=nilLiteral | |
(tuple_expr type='()' location=a.swift:16:59 range=[a.swift:16:59 - line:16:59])))))) | |
(return_stmt | |
(conditional_checked_cast_expr type='T?' location=a.swift:17:30 range=[a.swift:17:16 - line:17:34] value_cast writtenType='T' | |
(open_existential_expr implicit type='P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:28] | |
(opaque_value_expr implicit type='(P2).Type' location=a.swift:17:16 range=[a.swift:17:16 - line:17:16] @ 0x7fd95e16d9f8) | |
(declref_expr type='P2.Type' location=a.swift:17:16 range=[a.swift:17:16 - line:17:16] decl=a.(file).S.a(_:).p2Type@a.swift:16:19 function_ref=unapplied) | |
(erasure_expr implicit type='P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:28] | |
(abstract_conformance protocol=P2) | |
(call_expr type='P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:28] nothrow arg_labels= | |
(constructor_ref_call_expr type='() -> P2' location=a.swift:17:23 range=[a.swift:17:16 - line:17:23] nothrow | |
(declref_expr type='((P2).Type) -> () -> P2' location=a.swift:17:23 range=[a.swift:17:23 - line:17:23] decl=a.(file).P2.init()@a.swift:7:5 [with P2[abstract:P2]] function_ref=double) | |
(opaque_value_expr implicit type='(P2).Type' location=a.swift:17:16 range=[a.swift:17:16 - line:17:16] @ 0x7fd95e16d9f8)) | |
(tuple_expr type='()' location=a.swift:17:27 range=[a.swift:17:27 - line:17:28])))))))) | |
(constructor_decl implicit "init()" interface type='(S.Type) -> () -> S' access=internal designated | |
(parameter_list | |
(parameter "self" type='inout S' interface type='inout S' inout)) | |
(parameter_list) | |
(brace_stmt | |
(return_stmt implicit)))) | |
(extension_decl Int inherits: P1) | |
(top_level_code_decl | |
(brace_stmt | |
(call_expr type='Int' location=a.swift:22:5 range=[a.swift:22:1 - line:22:15] nothrow arg_labels=_: | |
(dot_syntax_call_expr type='(Int.Type) -> Int' location=a.swift:22:5 range=[a.swift:22:1 - line:22:5] nothrow | |
(declref_expr type='(S) -> (Int.Type) -> Int' location=a.swift:22:5 range=[a.swift:22:5 - line:22:5] decl=a.(file).S.a@a.swift:11:10 [with Int[Int: P1 module a]] function_ref=single) | |
(call_expr type='S' location=a.swift:22:1 range=[a.swift:22:1 - line:22:3] nothrow arg_labels= | |
(constructor_ref_call_expr type='() -> S' location=a.swift:22:1 range=[a.swift:22:1 - line:22:1] nothrow | |
(declref_expr implicit type='(S.Type) -> () -> S' location=a.swift:22:1 range=[a.swift:22:1 - line:22:1] decl=a.(file).S.init()@a.swift:10:8 function_ref=single) | |
(type_expr type='S.Type' location=a.swift:22:1 range=[a.swift:22:1 - line:22:1] typerepr='S')) | |
(tuple_expr type='()' location=a.swift:22:2 range=[a.swift:22:2 - line:22:3]))) | |
(paren_expr type='(Int.Type)' location=a.swift:22:7 range=[a.swift:22:6 - line:22:15] | |
(dot_self_expr type='Int.Type' location=a.swift:22:7 range=[a.swift:22:7 - line:22:11] | |
(type_expr type='Int.Type' location=a.swift:22:7 range=[a.swift:22:7 - line:22:7] typerepr='Int'))))))) |
org.swift.4120180228a
(call_expr type='T?' location=a.swift:12:16 range=[a.swift:12:16 - line:12:22] nothrow arg_labels=_:
直接 Optional<T>
に推論、暗黙アップキャストが除去
norioさんに教わりました。ありがとうございました。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
4.0だとT + upcast to T? に推論
inject_into_optionalのとこ