[swift-dev] How should NSArray<void(^)(void)>* be imported?

Jacob Bandes-Storch jtbandes at gmail.com
Sat Mar 5 03:54:18 CST 2016


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 at apple.com> wrote:

>
> > On Mar 3, 2016, at 10:12 PM, Jacob Bandes-Storch <jtbandes at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160305/3605ccf1/attachment.html>


More information about the swift-dev mailing list