[commit: ghc] master: Export constructors for IntPtr and WordPtr (a28611b)

git at git.haskell.org git at git.haskell.org
Sun May 1 22:49:36 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/a28611b14930c9fd73b0028857e1ea8c0e64a38a/ghc

>---------------------------------------------------------------

commit a28611b14930c9fd73b0028857e1ea8c0e64a38a
Author: RyanGlScott <ryan.gl.scott at gmail.com>
Date:   Mon May 2 00:07:14 2016 +0200

    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


>---------------------------------------------------------------

a28611b14930c9fd73b0028857e1ea8c0e64a38a
 libraries/base/Foreign/C/Types.hs            |  4 ++++
 libraries/base/Foreign/Ptr.hs                | 25 +++++++++++++++++++++++--
 libraries/base/System/Posix/Types.hs         |  4 ++++
 libraries/base/changelog.md                  |  6 ++++++
 testsuite/tests/ffi/should_compile/T11983.c  |  5 +++++
 testsuite/tests/ffi/should_compile/T11983.h  |  9 +++++++++
 testsuite/tests/ffi/should_compile/T11983.hs | 11 +++++++++++
 testsuite/tests/ffi/should_compile/all.T     |  2 ++
 8 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/libraries/base/Foreign/C/Types.hs b/libraries/base/Foreign/C/Types.hs
index fef8e4a..b725a4a 100644
--- a/libraries/base/Foreign/C/Types.hs
+++ b/libraries/base/Foreign/C/Types.hs
@@ -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
diff --git a/libraries/base/Foreign/Ptr.hs b/libraries/base/Foreign/Ptr.hs
index efe580a..5e6bccf 100644
--- a/libraries/base/Foreign/Ptr.hs
+++ b/libraries/base/Foreign/Ptr.hs
@@ -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.
+-}
diff --git a/libraries/base/System/Posix/Types.hs b/libraries/base/System/Posix/Types.hs
index c2ac65e..5389e6e 100644
--- a/libraries/base/System/Posix/Types.hs
+++ b/libraries/base/System/Posix/Types.hs
@@ -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
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index f935c59..dd386ed 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -1,5 +1,11 @@
 # 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
diff --git a/testsuite/tests/ffi/should_compile/T11983.c b/testsuite/tests/ffi/should_compile/T11983.c
new file mode 100644
index 0000000..2b475fb
--- /dev/null
+++ b/testsuite/tests/ffi/should_compile/T11983.c
@@ -0,0 +1,5 @@
+#include <stdint.h>
+#include "T11983.h"
+
+void intptr_example(intptr_t i)   {}
+void uintptr_example(uintptr_t u) {}
diff --git a/testsuite/tests/ffi/should_compile/T11983.h b/testsuite/tests/ffi/should_compile/T11983.h
new file mode 100644
index 0000000..33c78cb
--- /dev/null
+++ b/testsuite/tests/ffi/should_compile/T11983.h
@@ -0,0 +1,9 @@
+#ifndef T11983_H
+#define T11983_H
+
+#include <stdint.h>
+
+void intptr_example(intptr_t);
+void uintptr_example(uintptr_t);
+
+#endif // T11983_H
diff --git a/testsuite/tests/ffi/should_compile/T11983.hs b/testsuite/tests/ffi/should_compile/T11983.hs
new file mode 100644
index 0000000..162d241
--- /dev/null
+++ b/testsuite/tests/ffi/should_compile/T11983.hs
@@ -0,0 +1,11 @@
+{-# 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 ()
diff --git a/testsuite/tests/ffi/should_compile/all.T b/testsuite/tests/ffi/should_compile/all.T
index ec6326b..dac31ae 100644
--- a/testsuite/tests/ffi/should_compile/all.T
+++ b/testsuite/tests/ffi/should_compile/all.T
@@ -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'])



More information about the ghc-commits mailing list