I'm wading through little by little, but I clearly still have a lot to
learn... sorry if I'm bothering you with questions!
Comparing the SIL for the `*completionBlock*` getter, which is imported as
()->()...
%15 = class_method [volatile] %14 : $NSOperation,
#NSOperation.completionBlock!getter.1.foreign : NSOperation -> () -> *(()
-> ())?* , $@convention(objc_method) (NSOperation) -> @autoreleased
*Optional<@convention(block)
() -> ()>*
Here I see that "@convention(block)" is retained in the type
information, and appears in the expanded form Optional<@convention(block)
()->()>, even though the getter completionBlock getter is of type
"NSOperation -> () -> (() -> ())?", and ()->() is what we see in generated
interfaces.
...vs. the `*executionBlocks*` getter, which is imported as [()->()]...
%11 = class_method [volatile] %10 : $NSBlockOperation,
#NSBlockOperation.executionBlocks!getter.1.foreign : NSBlockOperation -> ()
-> *[() -> ()]* , $@convention(objc_method) (NSBlockOperation) ->
@autoreleased Optional<NSArray>
%12 = apply %11(%10) : $@convention(objc_method) (NSBlockOperation) ->
@autoreleased Optional<NSArray>
%13 = function_ref
@_TF10Foundation22_convertNSArrayToArrayurFGSqCSo7NSArray_GSax_ :
$@convention(thin) <τ_0_0> (@owned Optional<NSArray>) -> @owned Array<τ_0_0>
%14 = apply *%13<() -> ()>*(%12) : $@convention(thin) <τ_0_0> (@owned
Optional<NSArray>) -> @owned Array<τ_0_0>
release_value %14 : *$Array<() -> ()>*
I don't see @convention(block) anywhere here. And when I check the type of
static_cast<FunctionTypeMetadata*>(T)->getConvention(), from inside
findBridgeWitness, the convention is Swift.
So not only is there no conformance for blocks (which seems like an easy
thing to add, like you said, similarly to _BridgeableMetatype), but I think
the @convention(block) is being *completely lost* by
adjustTypeForConcreteImport. Is this true or am I missing something?
How is @convention(block) retained after importing in order to produce the
right type from completionBlock.getter, namely Optional<@convention(block)
()->()>, but it appears only as Optional<()->()> in the generated
interface? Why does this mechanism not produce a call to
_convertNSArrayToArray<@convention(block) ()->()>, but only
_convertNSArrayToArray<()->()> ?
Jacob
···
On Fri, Mar 4, 2016 at 9:46 AM, Joe Groff <jgroff@apple.com> wrote:
> On Mar 3, 2016, at 10:12 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:
>
> I see, thanks for the clarification. How is it, then, that properties
whose type is void(^)(void) already work fine?
For properties, we can statically bridge them by emitting thunk getters
and setters at compile time. We have to do this dynamically for bridged
containers since they can freely be in ObjC or Swift representation at
runtime.
-Joe