Commit a28611b1 authored by Ryan Scott's avatar Ryan Scott Committed by Ben Gamari

Export constructors for IntPtr and WordPtr

This finishes what #5529 started by exporting the constructors for
`IntPtr` and `WordPtr` from `Foreign.Ptr`, allowing them to be used in
`foreign` declarations.

Fixes #11983.

Test Plan: `make TEST=T11983`

Reviewers: simonpj, hvr, bgamari, austin

Reviewed By: simonpj

Subscribers: simonpj, thomie

Differential Revision: https://phabricator.haskell.org/D2142

GHC Trac Issues: #11983
parent ecc06030
......@@ -10,7 +10,7 @@
-- Module : Foreign.C.Types
-- Copyright : (c) The FFI task force 2001
-- License : BSD-style (see the file libraries/base/LICENSE)
--
--
-- Maintainer : ffi@haskell.org
-- Stability : provisional
-- Portability : portable
......@@ -63,6 +63,10 @@ module Foreign.C.Types
-- XXX GHC doesn't support CLDouble yet
-- , CLDouble(..)
-- See Note [Exporting constructors of marshallable foreign types]
-- in Foreign.Ptr for why the constructors for these newtypes are
-- exported.
-- ** Other types
-- Instances of: Eq and Storable
......
......@@ -7,7 +7,7 @@
-- Module : Foreign.Ptr
-- Copyright : (c) The FFI task force 2001
-- License : BSD-style (see the file libraries/base/LICENSE)
--
--
-- Maintainer : ffi@haskell.org
-- Stability : provisional
-- Portability : portable
......@@ -41,12 +41,15 @@ module Foreign.Ptr (
-- Free the function pointer created by foreign export dynamic.
-- * Integral types with lossless conversion to and from pointers
IntPtr,
IntPtr(..),
ptrToIntPtr,
intPtrToPtr,
WordPtr,
WordPtr(..),
ptrToWordPtr,
wordPtrToPtr
-- See Note [Exporting constructors of marshallable foreign types]
-- for why the constructors for IntPtr and WordPtr are exported.
) where
import GHC.Ptr
......@@ -97,3 +100,21 @@ ptrToIntPtr (Ptr a#) = IntPtr (I# (addr2Int# a#))
-- | casts an @IntPtr@ to a @Ptr@
intPtrToPtr :: IntPtr -> Ptr a
intPtrToPtr (IntPtr (I# i#)) = Ptr (int2Addr# i#)
{-
Note [Exporting constructors of marshallable foreign types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
One might expect that IntPtr, WordPtr, and the other newtypes in the
Foreign.C.Types and System.Posix.Types modules to be abstract, but this is not
the case in GHC (see Trac #5229 and #11983). In fact, we deliberately export
the constructors for these datatypes in order to satisfy a requirement of the
Haskell 2010 Report (§ 8.4.2) that if a newtype is used in a foreign
declaration, then its constructor must be visible.
This requirement was motivated by the fact that using a type in a foreign
declaration necessarily exposes some information about the type to the user,
so being able to use abstract types in a foreign declaration breaks their
abstraction (see Trac #3008). As a result, the constructors of all FFI-related
newtypes in base must be exported in order to be useful for FFI programming,
even at the cost of exposing their underlying, architecture-dependent types.
-}
......@@ -11,7 +11,7 @@
-- Module : System.Posix.Types
-- Copyright : (c) The University of Glasgow 2002
-- License : BSD-style (see the file libraries/base/LICENSE)
--
--
-- Maintainer : libraries@haskell.org
-- Stability : provisional
-- Portability : non-portable (requires POSIX)
......@@ -68,6 +68,10 @@ module System.Posix.Types (
Fd(..),
-- See Note [Exporting constructors of marshallable foreign types]
-- in Foreign.Ptr for why the constructors for these newtypes are
-- exported.
#if defined(HTYPE_NLINK_T)
LinkCount,
#endif
......
# Changelog for [`base` package](http://hackage.haskell.org/package/base)
## next *TBA*
* Bundled with GHC *TBA*
* `Foreign.Ptr` now exports the constructors for `IntPtr` and `WordPtr`
(#11983)
## 4.9.0.0 *TBA*
* Bundled with GHC 8.0
......
#include <stdint.h>
#include "T11983.h"
void intptr_example(intptr_t i) {}
void uintptr_example(uintptr_t u) {}
#ifndef T11983_H
#define T11983_H
#include <stdint.h>
void intptr_example(intptr_t);
void uintptr_example(uintptr_t);
#endif // T11983_H
{-# LANGUAGE ForeignFunctionInterface #-}
module T11983 where
{-# INCLUDE T11983.h #-}
import Foreign.Ptr
foreign import ccall "intptr_example"
intPtrExample :: IntPtr -> IO ()
foreign import ccall "uintptr_example"
wordPtrExample :: WordPtr -> IO ()
......@@ -30,3 +30,5 @@ test('T3742', normal, compile, [''])
test('cc015', normal, compile, [''])
test('cc016', normal, compile, [''])
test('T10460', normal, compile, [''])
test('T11983', [ omit_ways(['ghci']), extra_clean(['T11983.o']) ],
compile, ['T11983.c'])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment