Skip to content

C types with void explicitly in the parameter list (e.g. void (*)(void)) are assigned the wrong Haskell type #155

Open
@lehmacdj

Description

@lehmacdj

When attempting to invoke a function with a void argument like in this snippet:

-- | - (void)prepareForReadingItemsAtURLs:(NSArray<NSURL *> *)readingURLs
--        options:(NSFileCoordinatorReadingOptions)readingOptions
--        writingItemsAtURLs:(NSArray<NSURL *> *)writingURLs
--        options:(NSFileCoordinatorWritingOptions)writingOptions
--        error:(NSError **)outError
--        byAccessor:(void (^)(void (^completionHandler)(void)))batchAccessor;
m_NSFileCoordinator_prepareForReadingAndWritingItems ::
  Ptr NSFileCoordinator ->
  Ptr NSArray ->  -- readingURLs
  NSFileCoordinatorReadingOptions ->
  Ptr NSArray ->  -- writingURLs
  NSFileCoordinatorWritingOptions ->
  Ptr (Ptr NSError) ->
  IO () ->
  IO ()
m_NSFileCoordinator_prepareForReadingAndWritingItems fileCoordinator readingURLs readingOptions writingURLs writingOptions errorPtr accessor = do
  -- let accessor' :: FunPtr (CInt -> IO ()) -> IO () = \completionHandler -> accessor ($(C.peekFunPtr [t| CInt -> IO () |]) completionHandler 0)
  [C.block| void {
    [$(NSFileCoordinator *fileCoordinator)
      prepareForReadingItemsAtURLs: $(NSArray *readingURLs)
      options: $(NSFileCoordinatorReadingOptions readingOptions)
      writingItemsAtURLs: $(NSArray *writingURLs)
      options: $(NSFileCoordinatorWritingOptions writingOptions)
      error: $(NSError **errorPtr)
      byAccessor: ^(void (^completionHandler)(void)) {
        $fun:(void (*accessor)(void))();
        completionHandler()
      }
    ];
  }
  |]

I get an error like so:

• Unacceptable argument type in foreign declaration:
    ‘()’ cannot be marshalled in a foreign call
• When checking declaration:
    foreign import ccall safe "wrapper" inline_c_ffi_6989586621681841573
      :: (() -> IO ()) -> IO (FunPtr (() -> IO ()))

Inspecting the FunPtr docs, I see that this is not the expected type for a function pointer of type void (*)(void) instead it should have type IO () or (). The bug is in buildArr in the antiquoter for $fun:. I'm working on a fix and will make a PR shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions