Skip to content

Instantly share code, notes, and snippets.

@omochi
Last active March 2, 2018 01:25
Show Gist options
  • Save omochi/af63493d713074428e2fa6a78f0cb491 to your computer and use it in GitHub Desktop.
Save omochi/af63493d713074428e2fa6a78f0cb491 to your computer and use it in GitHub Desktop.
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)
(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')))))))
(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')))))))
@omochi
Copy link
Author

omochi commented Mar 1, 2018

4.0だとT + upcast to T? に推論
inject_into_optionalのとこ

@omochi
Copy link
Author

omochi commented Mar 2, 2018

org.swift.4120180228a

@omochi
Copy link
Author

omochi commented Mar 2, 2018

(call_expr type='T?' location=a.swift:12:16 range=[a.swift:12:16 - line:12:22] nothrow arg_labels=_:

@omochi
Copy link
Author

omochi commented Mar 2, 2018

直接 Optional<T> に推論、暗黙アップキャストが除去

@omochi
Copy link
Author

omochi commented Mar 2, 2018

norioさんに教わりました。ありがとうございました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment