[Git][ghc/ghc][master] Add operations for obtaining operating-system handles
by Marge Bot (@marge-bot) 27 Jan '26
by Marge Bot (@marge-bot) 27 Jan '26
27 Jan '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
5957a8ad by Wolfgang Jeltsch at 2026-01-27T06:11:40-05:00
Add operations for obtaining operating-system handles
This contribution implements CLC proposal #369. It adds operations for
obtaining POSIX file descriptors and Windows handles that underlie
Haskell handles. Those operating system handles can also be obtained
without such additional operations, but this is more involved and, more
importantly, requires using internals.
- - - - -
22 changed files:
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- + libraries/base/src/System/IO/OS.hs
- libraries/base/tests/IO/all.T
- + libraries/base/tests/IO/osHandles001FileDescriptors.hs
- + libraries/base/tests/IO/osHandles001FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles001WindowsHandles.hs
- + libraries/base/tests/IO/osHandles001WindowsHandles.stdout
- + libraries/base/tests/IO/osHandles002FileDescriptors.hs
- + libraries/base/tests/IO/osHandles002FileDescriptors.stderr
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdin
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles002WindowsHandles.hs
- + libraries/base/tests/IO/osHandles002WindowsHandles.stderr
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdin
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdout
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
Changes:
=====================================
libraries/base/base.cabal.in
=====================================
@@ -255,6 +255,7 @@ Library
, System.Exit
, System.IO
, System.IO.Error
+ , System.IO.OS
, System.Mem
, System.Mem.StableName
, System.Posix.Internals
=====================================
libraries/base/changelog.md
=====================================
@@ -23,6 +23,7 @@
* `GHC.Conc.catchSTM` and `GHC.Conc.Sync.catchSTM` now attach `WhileHandling` annotation to exceptions thrown from the handler. ([GHC #25365](https://gitlab.haskell.org/ghc/ghc/-/issues/25365))
* Remove `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
* Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
+ * Add a new module `System.IO.OS` with operations for obtaining operating-system handles (file descriptors, Windows handles). ([CLC proposal #369](https://github.com/haskell/core-libraries-committee/issues/369))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/base/src/System/IO/OS.hs
=====================================
@@ -0,0 +1,62 @@
+{-# LANGUAGE Safe #-}
+
+{-|
+ This module bridges between Haskell handles and underlying operating-system
+ features.
+-}
+module System.IO.OS
+(
+ -- * Obtaining file descriptors and Windows handles
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+
+ -- ** Caveats
+ -- $with-ref-caveats
+)
+where
+
+import GHC.Internal.System.IO.OS
+ (
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+ )
+
+-- ** Caveats
+
+{-$with-ref-caveats
+ #with-ref-caveats#There are the following caveats regarding the above
+ operations:
+
+ * Flushing of buffers can fail if the given handle is readable but not
+ seekable.
+
+ * If one of these operations is performed as part of an action executed by
+ 'System.IO.Unsafe.unsafePerformIO',
+ 'System.IO.Unsafe.unsafeInterleaveIO', or one of their “dupable”
+ variants and the user-provided action receives an asychnchronous
+ exception and does not catch it, then the following happens:
+
+ - Before the overall computation is suspended, the blocking of handle
+ operations is removed.
+
+ - When the computation is later resumed due to another evaluation
+ attempt, the blocking of handle operations is reinstantiated, the
+ Haskell-managed buffers are flushed again, and the user-provided
+ action is run from the beginning.
+
+ Repeating the previously executed part of the user-provided action
+ cannot be avoided apparently. See the @[async]@ note in the source code
+ of "GHC.Internal.IO.Handle.Internals" for further explanation.
+-}
=====================================
libraries/base/tests/IO/all.T
=====================================
@@ -186,3 +186,15 @@ test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1)
test('T18832', only_ways(['threaded1']), compile_and_run, [''])
test('mkdirExists', [exit_code(1), when(opsys('mingw32'), ignore_stderr)], compile_and_run, [''])
+
+test('osHandles001FileDescriptors', omit_ways(['winio', 'winio_threaded']), compile_and_run, [''])
+test('osHandles001WindowsHandles', only_ways(['winio', 'winio_threaded']), compile_and_run, [''])
+test('osHandles002FileDescriptors', [when(opsys('mingw32'), skip), when(arch('javascript'), skip)], compile_and_run, [''])
+test('osHandles002WindowsHandles', only_ways(['winio', 'winio_threaded']), compile_and_run, [''])
+# It would be good to let `osHandles002FileDescriptors` run also on
+# Windows with the file-descriptor-based I/O manager. However, this
+# test, as it is currently implemented, requires the `unix` package.
+# That said, `UCRT.DLL`, which is used by GHC-generated Windows
+# executables, emulates part of POSIX, enough for this test. As a
+# result, this test could be generalized to also supporting Windows, but
+# this would likely involve creating bindings to C code.
=====================================
libraries/base/tests/IO/osHandles001FileDescriptors.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE TypeApplications #-}
+
+import Control.Monad (mapM_)
+import Control.Exception (SomeException, try)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+ )
+
+main :: IO ()
+main = mapM_ ((>>= print) . try @SomeException) $
+ [
+ withFileDescriptorReadingBiasedRaw stdin (return . show),
+ withFileDescriptorWritingBiasedRaw stdout (return . show),
+ withFileDescriptorWritingBiasedRaw stderr (return . show),
+ withWindowsHandleReadingBiasedRaw stdin (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stdout (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stderr (return . const "_")
+ ]
=====================================
libraries/base/tests/IO/osHandles001FileDescriptors.stdout
=====================================
@@ -0,0 +1,6 @@
+Right "0"
+Right "1"
+Right "2"
+Left <stdin>: withWindowsHandleReadingBiasedRaw: inappropriate type (handle does not use Windows handles)
+Left <stdout>: withWindowsHandleWritingBiasedRaw: inappropriate type (handle does not use Windows handles)
+Left <stderr>: withWindowsHandleWritingBiasedRaw: inappropriate type (handle does not use Windows handles)
=====================================
libraries/base/tests/IO/osHandles001WindowsHandles.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE TypeApplications #-}
+
+import Control.Monad (mapM_)
+import Control.Exception (SomeException, try)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+ )
+
+main :: IO ()
+main = mapM_ ((>>= print) . try @SomeException) $
+ [
+ withFileDescriptorReadingBiasedRaw stdin (return . show),
+ withFileDescriptorWritingBiasedRaw stdout (return . show),
+ withFileDescriptorWritingBiasedRaw stderr (return . show),
+ withWindowsHandleReadingBiasedRaw stdin (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stdout (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stderr (return . const "_")
+ ]
=====================================
libraries/base/tests/IO/osHandles001WindowsHandles.stdout
=====================================
@@ -0,0 +1,6 @@
+Left <stdin>: withFileDescriptorReadingBiasedRaw: inappropriate type (handle does not use file descriptors)
+Left <stdout>: withFileDescriptorWritingBiasedRaw: inappropriate type (handle does not use file descriptors)
+Left <stderr>: withFileDescriptorWritingBiasedRaw: inappropriate type (handle does not use file descriptors)
+Right "_"
+Right "_"
+Right "_"
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.hs
=====================================
@@ -0,0 +1,28 @@
+import Data.Functor (void)
+import Data.ByteString.Char8 (pack)
+import System.Posix.Types (Fd (Fd), ByteCount)
+import System.Posix.IO.ByteString (fdRead, fdWrite)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased
+ )
+
+main :: IO ()
+main = withFileDescriptorReadingBiased stdin $ \ stdinFD ->
+ withFileDescriptorWritingBiased stdout $ \ stdoutFD ->
+ withFileDescriptorWritingBiased stderr $ \ stderrFD ->
+ do
+ regularMsg <- fdRead (Fd stdinFD) inputSizeApproximation
+ void $ fdWrite (Fd stdoutFD) regularMsg
+ void $ fdWrite (Fd stderrFD) (pack errorMsg)
+ where
+
+ inputSizeApproximation :: ByteCount
+ inputSizeApproximation = 100
+
+ errorMsg :: String
+ errorMsg = "And every single door\n\
+ \That I've walked through\n\
+ \Brings me back, back here again\n"
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.stderr
=====================================
@@ -0,0 +1,3 @@
+And every single door
+That I've walked through
+Brings me back, back here again
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.stdin
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.stdout
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.hs
=====================================
@@ -0,0 +1,49 @@
+import Control.Monad (zipWithM_)
+import Data.Functor (void)
+import Data.Char (ord)
+import Foreign.Marshal.Alloc (allocaBytes)
+import Foreign.Storable (pokeElemOff)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased
+ )
+
+main :: IO ()
+main = withWindowsHandleReadingBiased stdin $ \ windowsStdin ->
+ withWindowsHandleWritingBiased stdout $ \ windowsStdout ->
+ withWindowsHandleWritingBiased stderr $ \ windowsStderr ->
+ do
+ withBuffer inputSizeApproximation $ \ bufferPtr -> do
+ inputSize <- win32_ReadFile windowsStdin
+ bufferPtr
+ inputSizeApproximation
+ Nothing
+ void $ win32_WriteFile windowsStdout
+ bufferPtr
+ inputSize
+ Nothing
+ withBuffer errorMsgSize $ \ bufferPtr -> do
+ zipWithM_ (pokeElemOff bufferPtr)
+ [0 ..]
+ (map (fromIntegral . ord) errorMsg)
+ void $ win32_WriteFile windowsStderr
+ bufferPtr
+ errorMsgSize
+ Nothing
+ where
+
+ withBuffer :: DWORD -> (Ptr Word8 -> IO a) -> IO a
+ withBuffer = allocaBytes . fromIntegral
+
+ inputSizeApproximation :: DWORD
+ inputSizeApproximation = 100
+
+ errorMsg :: String
+ errorMsg = "And every single door\n\
+ \That I've walked through\n\
+ \Brings me back, back here again\n"
+
+ errorMsgSize :: DWORD
+ errorMsgSize = fromIntegral (length errorMsg)
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.stderr
=====================================
@@ -0,0 +1,3 @@
+And every single door
+That I've walked through
+Brings me back, back here again
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.stdin
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.stdout
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -328,6 +328,7 @@ Library
GHC.Internal.System.Exit
GHC.Internal.System.IO
GHC.Internal.System.IO.Error
+ GHC.Internal.System.IO.OS
GHC.Internal.System.Mem
GHC.Internal.System.Mem.StableName
GHC.Internal.System.Posix.Internals
=====================================
libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
=====================================
@@ -0,0 +1,323 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
+
+{-|
+ This module bridges between Haskell handles and underlying operating-system
+ features.
+-}
+module GHC.Internal.System.IO.OS
+(
+ -- * Obtaining file descriptors and Windows handles
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+
+ -- ** Caveats
+ -- $with-ref-caveats
+)
+where
+
+import GHC.Internal.Control.Monad (return)
+import GHC.Internal.Control.Concurrent.MVar (MVar)
+import GHC.Internal.Control.Exception (mask)
+import GHC.Internal.Data.Function (const, (.), ($))
+import GHC.Internal.Data.Functor (fmap)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.Data.Bool (otherwise)
+#endif
+import GHC.Internal.Data.Maybe (Maybe (Nothing), maybe)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.Data.Maybe (Maybe (Just))
+#endif
+import GHC.Internal.Data.List ((++))
+import GHC.Internal.Data.String (String)
+import GHC.Internal.Data.Typeable (Typeable, cast)
+import GHC.Internal.System.IO (IO)
+import GHC.Internal.IO.FD (fdFD)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.IO.Windows.Handle
+ (
+ NativeHandle,
+ ConsoleHandle,
+ IoHandle,
+ toHANDLE
+ )
+#endif
+import GHC.Internal.IO.Handle.Types
+ (
+ Handle (FileHandle, DuplexHandle),
+ Handle__ (Handle__, haDevice)
+ )
+import GHC.Internal.IO.Handle.Internals (withHandle_', flushBuffer)
+import GHC.Internal.IO.Exception
+ (
+ IOErrorType (InappropriateType),
+ IOException (IOError),
+ ioException
+ )
+import GHC.Internal.Foreign.Ptr (Ptr)
+import GHC.Internal.Foreign.C.Types (CInt)
+
+-- * Obtaining POSIX file descriptors and Windows handles
+
+{-|
+ Executes a user-provided action on an operating-system handle that underlies
+ a Haskell handle. Before the user-provided action is run, user-defined
+ preparation based on the handle state that contains the operating-system
+ handle is performed. While the user-provided action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withOSHandle :: String
+ -- ^ The name of the overall operation
+ -> (Handle -> MVar Handle__)
+ {-^
+ Obtaining of the handle state variable that holds the
+ operating-system handle
+ -}
+ -> (forall d. Typeable d => d -> IO a)
+ -- ^ Conversion of a device into an operating-system handle
+ -> (Handle__ -> IO ())
+ -- ^ The preparation
+ -> Handle
+ -- ^ The Haskell handle to use
+ -> (a -> IO r)
+ -- ^ The action to execute on the operating-system handle
+ -> IO r
+withOSHandle opName handleStateVar getOSHandle prepare handle act
+ = mask $ \ withOriginalMaskingState ->
+ withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
+ osHandle <- getOSHandle dev
+ prepare handleState
+ withOriginalMaskingState $ act osHandle
+ where
+
+ withHandleState = withHandle_' opName handle (handleStateVar handle)
+{-
+ The 'withHandle_'' operation, which we use here, already performs masking.
+ Still, we have to employ 'mask', in order do obtain the operation that
+ restores the original masking state. The user-provided action should be
+ executed with this original masking state, as there is no inherent reason to
+ generally perform it with masking in place. The masking that 'withHandle_''
+ performs is only for safely accessing handle state and thus constitutes an
+ implementation detail; it has nothing to do with the user-provided action.
+-}
+{-
+ The order of actions in 'withOSHandle' is such that any exception from
+ 'getOSHandle' is thrown before the user-defined preparation is performed.
+-}
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for reading if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarReadingBiased :: Handle -> MVar Handle__
+handleStateVarReadingBiased (FileHandle _ var) = var
+handleStateVarReadingBiased (DuplexHandle _ readingVar _) = readingVar
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for writing if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarWritingBiased :: Handle -> MVar Handle__
+handleStateVarWritingBiased (FileHandle _ var) = var
+handleStateVarWritingBiased (DuplexHandle _ _ writingVar) = writingVar
+
+{-|
+ Yields the result of another operation if that operation succeeded, and
+ otherwise throws an exception that signals that the other operation failed
+ because some Haskell handle does not use an operating-system handle of a
+ required type.
+-}
+requiringOSHandleOfType :: String
+ -- ^ The name of the operating-system handle type
+ -> Maybe a
+ {-^
+ The result of the other operation if it succeeded
+ -}
+ -> IO a
+requiringOSHandleOfType osHandleTypeName
+ = maybe (ioException osHandleOfTypeRequired) return
+ where
+
+ osHandleOfTypeRequired :: IOException
+ osHandleOfTypeRequired
+ = IOError Nothing
+ InappropriateType
+ ""
+ ("handle does not use " ++ osHandleTypeName ++ "s")
+ Nothing
+ Nothing
+
+{-|
+ Obtains the POSIX file descriptor of a device if the device contains one,
+ and throws an exception otherwise.
+-}
+getFileDescriptor :: Typeable d => d -> IO CInt
+getFileDescriptor = requiringOSHandleOfType "POSIX file descriptor" .
+ fmap fdFD . cast
+
+{-|
+ Obtains the Windows handle of a device if the device contains one, and
+ throws an exception otherwise.
+-}
+getWindowsHandle :: Typeable d => d -> IO (Ptr ())
+getWindowsHandle = requiringOSHandleOfType "Windows handle" .
+ toMaybeWindowsHandle
+ where
+
+ toMaybeWindowsHandle :: Typeable d => d -> Maybe (Ptr ())
+#if defined(mingw32_HOST_OS)
+ toMaybeWindowsHandle dev
+ | Just nativeHandle <- cast dev :: Maybe (IoHandle NativeHandle)
+ = Just (toHANDLE nativeHandle)
+ | Just consoleHandle <- cast dev :: Maybe (IoHandle ConsoleHandle)
+ = Just (toHANDLE consoleHandle)
+ | otherwise
+ = Nothing
+ {-
+ This is inspired by the implementation of
+ 'System.Win32.Types.withHandleToHANDLENative'.
+ -}
+#else
+ toMaybeWindowsHandle _ = Nothing
+#endif
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for reading if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for writing if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for reading if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for writing if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiasedRaw
+ = withOSHandle "withFileDescriptorReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiasedRaw
+ = withOSHandle "withFileDescriptorWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiasedRaw
+ = withOSHandle "withWindowsHandleReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiasedRaw
+ = withOSHandle "withWindowsHandleWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ (const $ return ())
+
+-- ** Caveats
+
+{-$with-ref-caveats
+ #with-ref-caveats#This subsection is just a dummy, whose purpose is to serve
+ as the target of the hyperlinks above. The real documentation of the caveats
+ is in the /Caveats/ subsection in the @base@ module @System.IO.OS@, which
+ re-exports the above operations.
+-}
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -10048,6 +10048,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -10086,6 +10086,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -10328,6 +10328,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -10048,6 +10048,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5957a8ad6e944e37d3be7ccf1b0776b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5957a8ad6e944e37d3be7ccf1b0776b…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] PPC NCG: Generate clear right insn at arch width
by Marge Bot (@marge-bot) 27 Jan '26
by Marge Bot (@marge-bot) 27 Jan '26
27 Jan '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
56db94f7 by Peter Trommler at 2026-01-26T11:26:18+01:00
PPC NCG: Generate clear right insn at arch width
The clear right immediate (clrrxi) is only available in word and
doubleword width. Generate clrrxi instructions at architecture
width for all MachOp widths.
Fixes #24145
- - - - -
1 changed file:
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
Changes:
=====================================
compiler/GHC/CmmToAsm/PPC/CodeGen.hs
=====================================
@@ -539,7 +539,7 @@ getRegister' config platform (CmmMachOp mop [x]) -- unary MachOps
CLRLI arch_fmt dst src1 (arch_bits - size)
return (Any (intFormat to) code)
-getRegister' _ _ (CmmMachOp mop [x, y]) -- dyadic PrimOps
+getRegister' _ platform (CmmMachOp mop [x, y]) -- dyadic PrimOps
= case mop of
MO_F_Eq _ -> condFltReg EQQ x y
MO_F_Ne _ -> condFltReg NE x y
@@ -622,8 +622,9 @@ getRegister' _ _ (CmmMachOp mop [x, y]) -- dyadic PrimOps
(src, srcCode) <- getSomeReg x
let clear_mask = if imm == -4 then 2 else 3
fmt = intFormat rep
+ arch_fmt = intFormat (wordWidth platform)
code dst = srcCode
- `appOL` unitOL (CLRRI fmt dst src clear_mask)
+ `appOL` unitOL (CLRRI arch_fmt dst src clear_mask)
return (Any fmt code)
_ -> trivialCode rep False AND x y
MO_Or rep -> trivialCode rep False OR x y
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/56db94f791c6aae32798d82b74670c9…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/56db94f791c6aae32798d82b74670c9…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26832] 8 commits: Export labelThread from Control.Concurrent
by Teo Camarasu (@teo) 27 Jan '26
by Teo Camarasu (@teo) 27 Jan '26
27 Jan '26
Teo Camarasu pushed to branch wip/T26832 at Glasgow Haskell Compiler / GHC
Commits:
917ab8ff by Oleg Grenrus at 2026-01-23T10:52:55-05:00
Export labelThread from Control.Concurrent
- - - - -
3f5e8d80 by Cheng Shao at 2026-01-23T10:53:37-05:00
ci: only push perf notes on master/release branches
This patch fixes push_perf_notes logic in ci.sh to only push perf
notes on master/release branches. We used to unconditionally push perf
notes even in MRs, but the perf numbers in the wip branches wouldn't
be used as baseline anyway, plus this is causing a space leak in the
ghc-performance-notes repo. See #25317 for the perf notes repo size
problem.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
414b9593 by Cheng Shao at 2026-01-24T07:11:51-05:00
ci: remove duplicate keys in .gitlab-ci.yml
This patch removes accidentally duplicate keys in `.gitlab-ci.yml`.
The YAML spec doesn't allow duplicate keys in the first place, and
according to GitLab docs
(https://docs.gitlab.com/ci/yaml/yaml_optimization/#anchors) the
latest key overrides the earlier entries.
- - - - -
e5cb5491 by Cheng Shao at 2026-01-24T07:12:34-05:00
hadrian: drop obsolete configure/make builder logic for libffi
This patch drops obsolete hadrian logic around `Configure
libffiPath`/`Make libffiPath` builders, they are no longer needed
after libffi-clib has landed. Closes #26815.
- - - - -
2d160222 by Simon Hengel at 2026-01-24T07:13:17-05:00
Fix typo in roles.rst
- - - - -
baa080d7 by Teo Camarasu at 2026-01-27T10:15:41+00:00
ghc-internal: avoid depending on GHC.Internal.Exts
This module is mostly just re-exports. It made sense as a user-facing
module, but there's no good reason ghc-internal modules should depend on
it and doing so linearises the module graph
- - - - -
27b38796 by Teo Camarasu at 2026-01-27T10:51:31+00:00
ghc-internal: move considerAccessible to GHC.Internal.Magic
Previously it lived in GHC.Internal.Exts, but it really deserves to live
along with the other magic function, which are already re-exported from .Exts
- - - - -
836851c8 by Teo Camarasu at 2026-01-27T10:51:31+00:00
ghc-internal: move maxTupleSize to GHC.Internal.Tuple
This previously lived in GHC.Internal.Exts but a comment already said it
should be moved to .Tuple
- - - - -
27 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- compiler/GHC/Builtin/Names.hs
- docs/users_guide/exts/roles.rst
- hadrian/src/Context.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/Make.hs
- libraries/base/changelog.md
- libraries/base/src/Control/Concurrent.hs
- libraries/base/src/System/Timeout.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Foreign/Callback.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim/Internal/Build.hs
- libraries/ghc-internal/src/GHC/Internal/Magic.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/Tuple.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Exports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Imports.hs
- libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Types.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -1050,10 +1050,6 @@ abi-test:
optional: true
dependencies: null
image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora43:$DOCKER_REV"
- rules:
- - if: $CI_MERGE_REQUEST_ID
- - if: '$CI_COMMIT_BRANCH == "master"'
- - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/'
tags:
- x86_64-linux
script:
=====================================
.gitlab/ci.sh
=====================================
@@ -493,6 +493,11 @@ function fetch_perf_notes() {
}
function push_perf_notes() {
+ if [[ "${CI_COMMIT_BRANCH:-}" != "master" ]] && [[ ! "${CI_COMMIT_BRANCH:-}" =~ ghc-[0-9]+\.[0-9]+ ]]; then
+ info "Perf notes are only pushed on master/release branches"
+ return
+ fi
+
if [[ -z "${TEST_ENV:-}" ]]; then
return
fi
=====================================
compiler/GHC/Builtin/Names.hs
=====================================
@@ -1063,7 +1063,7 @@ alternativeClassKey = mkPreludeMiscIdUnique 754
-- Functions for GHC extensions
considerAccessibleName :: Name
-considerAccessibleName = varQual gHC_INTERNAL_EXTS (fsLit "considerAccessible") considerAccessibleIdKey
+considerAccessibleName = varQual gHC_MAGIC (fsLit "considerAccessible") considerAccessibleIdKey
-- Random GHC.Internal.Base functions
fromStringName, otherwiseIdName, foldrName, buildName, augmentName,
=====================================
docs/users_guide/exts/roles.rst
=====================================
@@ -38,7 +38,7 @@ trouble.
The way to identify such situations is to have *roles* assigned to type
variables of datatypes, classes, and type synonyms.
-Roles as implemented in GHC are a from a simplified version of the work
+Roles as implemented in GHC are based on a simplified version of the work
described in `Generative type abstraction and type-level
computation <https://www.seas.upenn.edu/~sweirich/papers/popl163af-weirich.pdf>`__,
published at POPL 2011.
=====================================
hadrian/src/Context.hs
=====================================
@@ -11,7 +11,7 @@ module Context (
pkgLibraryFile,
pkgConfFile, pkgStampFile, resourcePath, objectPath, contextPath, getContextPath, libPath, distDir,
distDynDir,
- haddockStatsFilesDir, ensureConfigured, autogenPath, rtsContext, rtsBuildPath, libffiBuildPath
+ haddockStatsFilesDir, ensureConfigured, autogenPath, rtsContext, rtsBuildPath
) where
import Base
@@ -93,14 +93,6 @@ rtsContext stage = vanillaContext stage rts
rtsBuildPath :: Stage -> Action FilePath
rtsBuildPath stage = buildPath (rtsContext stage)
--- | Build directory for in-tree 'libffi' library.
-libffiBuildPath :: Stage -> Action FilePath
-libffiBuildPath stage = buildPath $ Context
- stage
- libffi
- (error "libffiBuildPath: way not set.")
- (error "libffiBuildPath: inplace not set.")
-
pkgFileName :: Context -> Package -> String -> String -> Action FilePath
pkgFileName context package prefix suffix = do
pid <- pkgUnitId (stage context) package
=====================================
hadrian/src/Settings/Builders/Configure.hs
=====================================
@@ -8,8 +8,7 @@ configureBuilderArgs :: Args
configureBuilderArgs = do
stage <- getStage
gmpPath <- expr (gmpBuildPath stage)
- libffiPath <- expr (libffiBuildPath stage)
- mconcat [ builder (Configure gmpPath) ? do
+ builder (Configure gmpPath) ? do
targetArch <- queryTarget queryArch
targetPlatform <- queryTarget targetPlatformTriple
buildPlatform <- queryBuild targetPlatformTriple
@@ -28,16 +27,3 @@ configureBuilderArgs = do
-- option.
<> [ "--enable-alloca=malloc-notreentrant" | targetArch == "wasm32" ]
<> [ "--with-pic=yes" ]
-
- , builder (Configure libffiPath) ? do
- top <- expr topDirectory
- targetPlatform <- queryTarget targetPlatformTriple
- way <- getWay
- pure [ "--prefix=" ++ top -/- libffiPath -/- "inst"
- , "--libdir=" ++ top -/- libffiPath -/- "inst/lib"
- , "--enable-static=yes"
- , "--enable-shared="
- ++ (if wayUnit Dynamic way
- then "yes"
- else "no")
- , "--host=" ++ targetPlatform ] ]
=====================================
hadrian/src/Settings/Builders/Make.hs
=====================================
@@ -12,12 +12,8 @@ makeBuilderArgs = do
threads <- shakeThreads <$> expr getShakeOptions
stage <- getStage
gmpPath <- expr (gmpBuildPath stage)
- libffiPaths <- forM [Stage1, Stage2, Stage3 ] $ \s -> expr (libffiBuildPath s)
let t = show $ max 4 (threads - 2) -- Don't use all Shake's threads
- mconcat $
- (builder (Make gmpPath ) ? pure ["MAKEFLAGS=-j" ++ t]) :
- [ builder (Make libffiPath) ? pure ["MAKEFLAGS=-j" ++ t, "install"]
- | libffiPath <- libffiPaths ]
+ builder (Make gmpPath) ? pure ["MAKEFLAGS=-j" ++ t]
validateBuilderArgs :: Args
validateBuilderArgs = builder (Make "testsuite/tests") ? do
=====================================
libraries/base/changelog.md
=====================================
@@ -22,6 +22,7 @@
* `GHC.Conc.throwSTM` and `GHC.Conc.Sync.throwSTM` now carry a `HasCallStack` constraint and attach a `Backtrace` annotation to the thrown exception. ([GHC #25365](https://gitlab.haskell.org/ghc/ghc/-/issues/25365))
* `GHC.Conc.catchSTM` and `GHC.Conc.Sync.catchSTM` now attach `WhileHandling` annotation to exceptions thrown from the handler. ([GHC #25365](https://gitlab.haskell.org/ghc/ghc/-/issues/25365))
* Remove `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
+ * Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/base/src/Control/Concurrent.hs
=====================================
@@ -82,6 +82,9 @@ module Control.Concurrent (
-- * Weak references to ThreadIds
mkWeakThreadId,
+ -- * Thread debugging
+ labelThread,
+
-- * GHC's implementation of concurrency
-- |This section describes features specific to GHC's
=====================================
libraries/base/src/System/Timeout.hs
=====================================
@@ -29,7 +29,6 @@ import GHC.Internal.Control.Exception (Exception(..), handleJust, bracket,
asyncExceptionToException,
asyncExceptionFromException)
import GHC.Internal.Data.Unique (Unique, newUnique)
-import GHC.Conc (labelThread)
import Prelude
-- $setup
=====================================
libraries/ghc-internal/src/GHC/Internal/Exts.hs
=====================================
@@ -321,10 +321,7 @@ import GHC.Internal.Data.Data
import GHC.Internal.Data.Ord
import qualified GHC.Internal.Debug.Trace
import GHC.Internal.Unsafe.Coerce ( unsafeCoerce# ) -- just for re-export
-
--- XXX This should really be in Data.Tuple, where the definitions are
-maxTupleSize :: Int
-maxTupleSize = 64
+import GHC.Internal.Tuple (maxTupleSize)
-- | 'the' ensures that all the elements of the list are identical
-- and then returns that unique element
@@ -444,27 +441,3 @@ resizeSmallMutableArray# arr0 szNew a s0 =
(# s2, arr1 #) -> case copySmallMutableArray# arr0 0# arr1 0# szOld s2 of
s3 -> (# s3, arr1 #)
else (# s1, arr0 #)
-
--- | Semantically, @considerAccessible = True@. But it has special meaning
--- to the pattern-match checker, which will never flag the clause in which
--- 'considerAccessible' occurs as a guard as redundant or inaccessible.
--- Example:
---
--- > case (x, x) of
--- > (True, True) -> 1
--- > (False, False) -> 2
--- > (True, False) -> 3 -- Warning: redundant
---
--- The pattern-match checker will warn here that the third clause is redundant.
--- It will stop doing so if the clause is adorned with 'considerAccessible':
---
--- > case (x, x) of
--- > (True, True) -> 1
--- > (False, False) -> 2
--- > (True, False) | considerAccessible -> 3 -- No warning
---
--- Put 'considerAccessible' as the last statement of the guard to avoid get
--- confusing results from the pattern-match checker, which takes \"consider
--- accessible\" by word.
-considerAccessible :: Bool
-considerAccessible = True
=====================================
libraries/ghc-internal/src/GHC/Internal/Heap/Closures.hs
=====================================
@@ -75,9 +75,10 @@ import GHC.Internal.Int
import GHC.Internal.Num
import GHC.Internal.Real
import GHC.Internal.Word
-import GHC.Internal.Exts
import GHC.Internal.Generics
import GHC.Internal.Numeric
+import GHC.Internal.Ptr
+import GHC.Internal.Unsafe.Coerce
import GHC.Internal.Stack (HasCallStack)
------------------------------------------------------------------------
=====================================
libraries/ghc-internal/src/GHC/Internal/JS/Foreign/Callback.hs
=====================================
@@ -21,8 +21,6 @@ module GHC.Internal.JS.Foreign.Callback
import GHC.Internal.JS.Prim
-import qualified GHC.Internal.Exts as Exts
-
import GHC.Internal.Unsafe.Coerce
import GHC.Internal.Base
@@ -131,18 +129,18 @@ asyncCallback3 x = js_asyncCallbackApply 3 (unsafeCoerce x)
-- ----------------------------------------------------------------------------
foreign import javascript unsafe "(($1, $2) => { return h$makeCallback(h$runSync, [$1], $2); })"
- js_syncCallback :: Bool -> Exts.Any -> IO (Callback (IO b))
+ js_syncCallback :: Bool -> Any -> IO (Callback (IO b))
foreign import javascript unsafe "(($1) => { return h$makeCallback(h$run, [], $1); })"
- js_asyncCallback :: Exts.Any -> IO (Callback (IO b))
+ js_asyncCallback :: Any -> IO (Callback (IO b))
foreign import javascript unsafe "(($1) => { return h$makeCallback(h$runSyncReturn, [false], $1); })"
- js_syncCallbackReturn :: Exts.Any -> IO (Callback (IO JSVal))
+ js_syncCallbackReturn :: Any -> IO (Callback (IO JSVal))
foreign import javascript unsafe "(($1, $2, $3) => { return h$makeCallbackApply($2, h$runSync, [$1], $3); })"
- js_syncCallbackApply :: Bool -> Int -> Exts.Any -> IO (Callback b)
+ js_syncCallbackApply :: Bool -> Int -> Any -> IO (Callback b)
foreign import javascript unsafe "(($1, $2) => { return h$makeCallbackApply($1, h$run, [], $2); })"
- js_asyncCallbackApply :: Int -> Exts.Any -> IO (Callback b)
+ js_asyncCallbackApply :: Int -> Any -> IO (Callback b)
foreign import javascript unsafe "(($1, $2) => { return h$makeCallbackApply($1, h$runSyncReturn, [false], $2); })"
- js_syncCallbackApplyReturn :: Int -> Exts.Any -> IO (Callback b)
+ js_syncCallbackApplyReturn :: Int -> Any -> IO (Callback b)
foreign import javascript unsafe "h$release"
js_release :: Callback a -> IO ()
=====================================
libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
=====================================
@@ -42,8 +42,8 @@ module GHC.Internal.JS.Prim ( JSVal(..), JSVal#
import GHC.Internal.Unsafe.Coerce (unsafeCoerce)
import GHC.Internal.Prim
+import GHC.Internal.Types
import qualified GHC.Internal.Exception as Ex
-import qualified GHC.Internal.Exts as Exts
import qualified GHC.Internal.CString as GHC
import GHC.Internal.IO
import GHC.Internal.Data.Bool
@@ -78,15 +78,15 @@ instance Show JSException where
#if defined(javascript_HOST_ARCH)
{-# NOINLINE toIO #-}
-toIO :: Exts.Any -> IO Exts.Any
+toIO :: Any -> IO Any
toIO x = pure x
{-# NOINLINE resolve #-}
-resolve :: JSVal# -> JSVal# -> Exts.Any -> IO ()
+resolve :: JSVal# -> JSVal# -> Any -> IO ()
resolve accept reject x = resolveIO accept reject (pure x)
{-# NOINLINE resolveIO #-} -- used by the rts
-resolveIO :: JSVal# -> JSVal# -> IO Exts.Any -> IO ()
+resolveIO :: JSVal# -> JSVal# -> IO Any -> IO ()
resolveIO accept reject x =
(x >>= evaluate >>= js_callback_any accept) `catch`
(\(e::Ex.SomeException) -> do
@@ -260,16 +260,16 @@ seqList xs = go xs `seq` xs
go [] = ()
foreign import javascript unsafe "h$toHsString"
- js_fromJSString :: JSVal -> Exts.Any
+ js_fromJSString :: JSVal -> Any
foreign import javascript unsafe "h$fromHsString"
- js_toJSString :: Exts.Any -> JSVal
+ js_toJSString :: Any -> JSVal
foreign import javascript unsafe "h$toHsListJSVal"
- js_fromJSArray :: JSVal -> IO Exts.Any
+ js_fromJSArray :: JSVal -> IO Any
foreign import javascript unsafe "h$fromHsListJSVal"
- js_toJSArray :: Exts.Any -> IO JSVal
+ js_toJSArray :: Any -> IO JSVal
foreign import javascript unsafe "(($1) => { return ($1 === null); })"
js_isNull :: JSVal -> Bool
@@ -287,10 +287,10 @@ foreign import javascript unsafe "(() => { return null; })"
js_null :: JSVal
foreign import javascript unsafe "(($1,$2) => { return $1[h$fromHsString($2)]; })"
- js_getProp :: JSVal -> Exts.Any -> IO JSVal
+ js_getProp :: JSVal -> Any -> IO JSVal
foreign import javascript unsafe "(($1,$2) => { return $1[h$fromHsString($2)]; })"
- js_unsafeGetProp :: JSVal -> Exts.Any -> JSVal
+ js_unsafeGetProp :: JSVal -> Any -> JSVal
foreign import javascript unsafe "(($1,$2) => { return $1[$2]; })"
js_getProp' :: JSVal -> JSVal -> IO JSVal
@@ -311,7 +311,7 @@ foreign import javascript unsafe "(($1_1, $1_2) => { return h$decodeUtf8z($1_1,$
js_unsafeUnpackJSStringUtf8## :: Addr# -> JSVal#
foreign import javascript unsafe "(($1, $2) => { return $1($2); })"
- js_callback_any :: JSVal# -> Exts.Any -> IO ()
+ js_callback_any :: JSVal# -> Any -> IO ()
foreign import javascript unsafe "(($1, $2) => { return $1($2); })"
js_callback_jsval :: JSVal# -> JSVal -> IO ()
=====================================
libraries/ghc-internal/src/GHC/Internal/JS/Prim/Internal/Build.hs
=====================================
@@ -145,7 +145,6 @@ module GHC.Internal.JS.Prim.Internal.Build
) where
import GHC.Internal.JS.Prim
-import GHC.Internal.Exts
import GHC.Internal.IO
import GHC.Internal.Unsafe.Coerce
import GHC.Internal.Base
=====================================
libraries/ghc-internal/src/GHC/Internal/Magic.hs
=====================================
@@ -24,7 +24,7 @@
--
-----------------------------------------------------------------------------
-module GHC.Internal.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(..) ) where
+module GHC.Internal.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(..), considerAccessible ) where
--------------------------------------------------
-- See Note [magicIds] in GHC.Types.Id.Make
@@ -34,7 +34,7 @@ module GHC.Internal.Magic ( inline, noinline, lazy, oneShot, runRW#, DataToTag(.
-- because TYPE is not exported by the source Haskell module generated by
-- genprimops which Haddock will typecheck (#15935).
import GHC.Internal.Prim (State#, realWorld#, RealWorld, Int#)
-import GHC.Internal.Types (RuntimeRep(BoxedRep), TYPE, Levity, Constraint)
+import GHC.Internal.Types (RuntimeRep(BoxedRep), TYPE, Levity, Constraint, Bool(True))
-- | The call @inline f@ arranges that @f@ is inlined, regardless of
-- its size. More precisely, the call @inline f@ rewrites to the
@@ -137,3 +137,27 @@ type DataToTag :: forall {lev :: Levity}. TYPE (BoxedRep lev) -> Constraint
-- So it does not get its own Unsafe module, unlike WithDict.
class DataToTag a where
dataToTag# :: a -> Int#
+
+-- | Semantically, @considerAccessible = True@. But it has special meaning
+-- to the pattern-match checker, which will never flag the clause in which
+-- 'considerAccessible' occurs as a guard as redundant or inaccessible.
+-- Example:
+--
+-- > case (x, x) of
+-- > (True, True) -> 1
+-- > (False, False) -> 2
+-- > (True, False) -> 3 -- Warning: redundant
+--
+-- The pattern-match checker will warn here that the third clause is redundant.
+-- It will stop doing so if the clause is adorned with 'considerAccessible':
+--
+-- > case (x, x) of
+-- > (True, True) -> 1
+-- > (False, False) -> 2
+-- > (True, False) | considerAccessible -> 3 -- No warning
+--
+-- Put 'considerAccessible' as the last statement of the guard to avoid get
+-- confusing results from the pattern-match checker, which takes \"consider
+-- accessible\" by word.
+considerAccessible :: Bool
+considerAccessible = True
=====================================
libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
=====================================
@@ -40,8 +40,8 @@ import GHC.Internal.Data.List
import GHC.Internal.Data.Tuple
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Foreign.Storable
-import GHC.Internal.Exts
import GHC.Internal.Unsafe.Coerce
+import GHC.Internal.Ptr
import GHC.Internal.ClosureTypes
import GHC.Internal.Heap.Closures
=====================================
libraries/ghc-internal/src/GHC/Internal/Tuple.hs
=====================================
@@ -27,10 +27,11 @@ module GHC.Internal.Tuple (
Tuple40(..), Tuple41(..), Tuple42(..), Tuple43(..), Tuple44(..), Tuple45(..), Tuple46(..), Tuple47(..), Tuple48(..), Tuple49(..),
Tuple50(..), Tuple51(..), Tuple52(..), Tuple53(..), Tuple54(..), Tuple55(..), Tuple56(..), Tuple57(..), Tuple58(..), Tuple59(..),
Tuple60(..), Tuple61(..), Tuple62(..), Tuple63(..), Tuple64(..),
+ maxTupleSize,
) where
-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
-import GHC.Internal.Types ()
+import GHC.Internal.Types (Int)
default () -- Double and Integer aren't available yet
@@ -598,3 +599,6 @@ data Tuple64 a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 c1 d1 e1
r1 s1 t1 u1 v1 w1 x1 y1 z1 a2 b2 c2 d2 e2 f2 g2 h2 i2 j2 k2 l2
= (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,
r1,s1,t1,u1,v1,w1,x1,y1,z1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2)
+
+maxTupleSize :: Int
+maxTupleSize = 64
=====================================
libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Exports.hs
=====================================
@@ -32,7 +32,6 @@ module GHC.Internal.Wasm.Prim.Exports (
import GHC.Internal.Base
import GHC.Internal.Exception.Type
-import GHC.Internal.Exts
import GHC.Internal.IO
import GHC.Internal.IORef
import GHC.Internal.Int
=====================================
libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Imports.hs
=====================================
@@ -30,7 +30,6 @@ module GHC.Internal.Wasm.Prim.Imports (
import GHC.Internal.Base
import GHC.Internal.Exception
-import GHC.Internal.Exts
import GHC.Internal.IO.Unsafe
import GHC.Internal.Stable
import GHC.Internal.Wasm.Prim.Types
=====================================
libraries/ghc-internal/src/GHC/Internal/Wasm/Prim/Types.hs
=====================================
@@ -20,7 +20,6 @@ module GHC.Internal.Wasm.Prim.Types (
import GHC.Internal.Base
import GHC.Internal.Exception.Type
-import GHC.Internal.Exts
import GHC.Internal.Foreign.C.String.Encoding
import GHC.Internal.ForeignPtr
import GHC.Internal.IO
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -120,6 +120,7 @@ module Control.Concurrent where
isCurrentThreadBound :: GHC.Internal.Types.IO GHC.Internal.Types.Bool
isEmptyMVar :: forall a. MVar a -> GHC.Internal.Types.IO GHC.Internal.Types.Bool
killThread :: ThreadId -> GHC.Internal.Types.IO ()
+ labelThread :: ThreadId -> GHC.Internal.Base.String -> GHC.Internal.Types.IO ()
mkWeakMVar :: forall a. MVar a -> GHC.Internal.Types.IO () -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak (MVar a))
mkWeakThreadId :: ThreadId -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak ThreadId)
modifyMVar :: forall a b. MVar a -> (a -> GHC.Internal.Types.IO (a, b)) -> GHC.Internal.Types.IO b
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -120,6 +120,7 @@ module Control.Concurrent where
isCurrentThreadBound :: GHC.Internal.Types.IO GHC.Internal.Types.Bool
isEmptyMVar :: forall a. MVar a -> GHC.Internal.Types.IO GHC.Internal.Types.Bool
killThread :: ThreadId -> GHC.Internal.Types.IO ()
+ labelThread :: ThreadId -> GHC.Internal.Base.String -> GHC.Internal.Types.IO ()
mkWeakMVar :: forall a. MVar a -> GHC.Internal.Types.IO () -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak (MVar a))
mkWeakThreadId :: ThreadId -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak ThreadId)
modifyMVar :: forall a b. MVar a -> (a -> GHC.Internal.Types.IO (a, b)) -> GHC.Internal.Types.IO b
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -120,6 +120,7 @@ module Control.Concurrent where
isCurrentThreadBound :: GHC.Internal.Types.IO GHC.Internal.Types.Bool
isEmptyMVar :: forall a. MVar a -> GHC.Internal.Types.IO GHC.Internal.Types.Bool
killThread :: ThreadId -> GHC.Internal.Types.IO ()
+ labelThread :: ThreadId -> GHC.Internal.Base.String -> GHC.Internal.Types.IO ()
mkWeakMVar :: forall a. MVar a -> GHC.Internal.Types.IO () -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak (MVar a))
mkWeakThreadId :: ThreadId -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak ThreadId)
modifyMVar :: forall a b. MVar a -> (a -> GHC.Internal.Types.IO (a, b)) -> GHC.Internal.Types.IO b
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -120,6 +120,7 @@ module Control.Concurrent where
isCurrentThreadBound :: GHC.Internal.Types.IO GHC.Internal.Types.Bool
isEmptyMVar :: forall a. MVar a -> GHC.Internal.Types.IO GHC.Internal.Types.Bool
killThread :: ThreadId -> GHC.Internal.Types.IO ()
+ labelThread :: ThreadId -> GHC.Internal.Base.String -> GHC.Internal.Types.IO ()
mkWeakMVar :: forall a. MVar a -> GHC.Internal.Types.IO () -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak (MVar a))
mkWeakThreadId :: ThreadId -> GHC.Internal.Types.IO (GHC.Internal.Weak.Weak ThreadId)
modifyMVar :: forall a b. MVar a -> (a -> GHC.Internal.Types.IO (a, b)) -> GHC.Internal.Types.IO b
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout
=====================================
@@ -4453,6 +4453,7 @@ module Data.Tuple.Experimental where
type Unit# :: GHC.Internal.Types.ZeroBitType
data Unit# = ...
getSolo :: forall a. Solo a -> a
+ maxTupleSize :: GHC.Internal.Types.Int
module GHC.Exception.Backtrace.Experimental where
-- Safety: None
@@ -11044,6 +11045,7 @@ module Prelude.Experimental where
type Unit# :: GHC.Internal.Types.ZeroBitType
data Unit# = ...
getSolo :: forall a. Solo a -> a
+ maxTupleSize :: GHC.Internal.Types.Int
module System.Mem.Experimental where
-- Safety: None
=====================================
testsuite/tests/interface-stability/ghc-prim-exports.stdout
=====================================
@@ -1232,6 +1232,7 @@ module GHC.Magic where
class DataToTag a where
dataToTag# :: a -> GHC.Internal.Prim.Int#
{-# MINIMAL dataToTag# #-}
+ considerAccessible :: GHC.Internal.Types.Bool
inline :: forall a. a -> a
lazy :: forall a. a -> a
noinline :: forall a. a -> a
@@ -3891,6 +3892,7 @@ module GHC.Tuple where
type Unit :: *
data Unit = ()
getSolo :: forall a. Solo a -> a
+ maxTupleSize :: GHC.Internal.Types.Int
module GHC.Types where
-- Safety: None
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f5cee2076e8b14fcce7798717d6c60…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f5cee2076e8b14fcce7798717d6c60…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26834] 2 commits: ghc-internal: refine List imports
by Teo Camarasu (@teo) 27 Jan '26
by Teo Camarasu (@teo) 27 Jan '26
27 Jan '26
Teo Camarasu pushed to branch wip/T26834 at Glasgow Haskell Compiler / GHC
Commits:
fabb5297 by Teo Camarasu at 2026-01-27T09:28:31+00:00
ghc-internal: refine List imports
- - - - -
87d4f2db by Teo Camarasu at 2026-01-27T09:28:31+00:00
Move MonadFix Identity into Monad.Fix
- - - - -
16 changed files:
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Functor/Identity.hs
- libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs
- libraries/ghc-internal/src/GHC/Internal/Data/String.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/ExecutionStack/Internal.hsc
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage.hs
- libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
- libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/Windows.hs
Changes:
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs
=====================================
@@ -40,6 +40,7 @@ import GHC.Internal.Generics
import GHC.Internal.List ( head, drop )
import GHC.Internal.Control.Monad.ST.Imp
import GHC.Internal.System.IO
+import GHC.Internal.Data.Functor.Identity (Identity(..))
-- | Monads having fixed points with a \'knot-tying\' semantics.
-- Instances of 'MonadFix' should satisfy the following laws:
@@ -171,3 +172,8 @@ instance (MonadFix f, MonadFix g) => MonadFix (f :*: g) where
-- | @since base-4.12.0.0
instance MonadFix Down where
mfix f = Down (fix (getDown . f))
+
+
+-- | @since base-4.8.0.0
+instance MonadFix Identity where
+ mfix f = Identity (fix (runIdentity . f))
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs
=====================================
@@ -28,7 +28,7 @@ import GHC.Internal.Data.Proxy
--import qualified Data.List.NonEmpty as NE
import GHC.Internal.Generics
import qualified GHC.Internal.Data.List.NonEmpty as NE
-import qualified GHC.Internal.Data.List as List
+import qualified GHC.Internal.List as List
import GHC.Internal.Data.Maybe
import GHC.Internal.Data.Tuple
--import Prelude
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
=====================================
@@ -117,7 +117,7 @@ import GHC.Internal.Data.Maybe
import GHC.Internal.Data.Monoid
import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
import GHC.Internal.Data.Ord
-import GHC.Internal.Data.List (findIndex)
+import GHC.Internal.Data.OldList (findIndex)
import GHC.Internal.Data.Typeable
import GHC.Internal.Data.Version( Version(..) )
import GHC.Internal.Base hiding (Any, IntRep, FloatRep, NonEmpty(..))
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Functor/Identity.hs
=====================================
@@ -33,7 +33,6 @@ module GHC.Internal.Data.Functor.Identity (
Identity(..),
) where
-import GHC.Internal.Control.Monad.Fix
import GHC.Internal.Data.Bits (Bits, FiniteBits)
import GHC.Internal.Data.Coerce
import GHC.Internal.Data.Foldable
@@ -143,7 +142,3 @@ instance Applicative Identity where
-- | @since base-4.8.0.0
instance Monad Identity where
m >>= k = k (runIdentity m)
-
--- | @since base-4.8.0.0
-instance MonadFix Identity where
- mfix f = Identity (fix (runIdentity . f))
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs
=====================================
@@ -8,7 +8,7 @@ module GHC.Internal.Data.List.NonEmpty
) where
import GHC.Internal.Data.NonEmpty (NonEmpty (..), map)
-import qualified GHC.Internal.Data.List as List
+import qualified GHC.Internal.List as List
-- | The 'zip' function takes two streams and returns a stream of
-- corresponding pairs.
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/String.hs
=====================================
@@ -35,7 +35,7 @@ module GHC.Internal.Data.String (
import GHC.Internal.Base
import GHC.Internal.Data.Functor.Const (Const (Const))
import GHC.Internal.Data.Functor.Identity (Identity (Identity))
-import GHC.Internal.Data.List (lines, words, unlines, unwords)
+import GHC.Internal.Data.OldList (lines, words, unlines, unwords)
-- | `IsString` is used in combination with the @-XOverloadedStrings@
-- language extension to convert the literals to different string types.
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
=====================================
@@ -40,7 +40,7 @@ import GHC.Internal.Data.Functor ( Functor(..) )
import GHC.Internal.Data.Bool ( (&&) )
import GHC.Internal.Data.Eq
import GHC.Internal.Int ( Int )
-import GHC.Internal.Data.List ( map, sort, concat, concatMap, intersperse, (++) )
+import GHC.Internal.Data.OldList ( map, sort, concat, concatMap, intersperse, (++) )
import GHC.Internal.Data.Ord
import GHC.Internal.Data.String ( String )
import GHC.Internal.Base ( Applicative(..) )
=====================================
libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
=====================================
@@ -103,7 +103,7 @@ import GHC.Internal.IORef
import GHC.Internal.Maybe
import GHC.Internal.Ptr
import GHC.Internal.Word
-import GHC.Internal.Data.OldList (deleteBy)
+import GHC.Internal.List (deleteBy)
import qualified GHC.Internal.Event.Array as A
import GHC.Internal.Base
import GHC.Internal.Conc.Bound
=====================================
libraries/ghc-internal/src/GHC/Internal/ExecutionStack/Internal.hsc
=====================================
@@ -39,7 +39,7 @@ module GHC.Internal.ExecutionStack.Internal (
import GHC.Internal.Data.Functor
import GHC.Internal.Data.Maybe
-import GHC.Internal.Data.List (reverse, null)
+import GHC.Internal.List (reverse, null)
import GHC.Internal.Word
import GHC.Internal.Foreign.C.Types
import GHC.Internal.Foreign.C.String (peekCString, CString)
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage.hs
=====================================
@@ -30,7 +30,7 @@ import GHC.Internal.IO.Encoding.Types
import GHC.Internal.IO.Buffer
import GHC.Internal.Data.Bits
import GHC.Internal.Data.Maybe
-import GHC.Internal.Data.OldList (lookup)
+import GHC.Internal.List (lookup)
import qualified GHC.Internal.IO.Encoding.CodePage.API as API
import GHC.Internal.IO.Encoding.CodePage.Table
=====================================
libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
=====================================
@@ -28,7 +28,7 @@ import GHC.Internal.Control.Exception
import GHC.Internal.Data.Foldable (Foldable(..))
import GHC.Internal.Base
import GHC.Internal.Unicode (isSpace)
-import GHC.Internal.Data.List (filter, unlines, concat, reverse)
+import GHC.Internal.Data.OldList (filter, unlines, concat, reverse)
import GHC.Internal.Text.Show (show)
import GHC.Internal.System.Environment (getArgs)
import GHC.Internal.System.Exit (exitFailure)
=====================================
libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
=====================================
@@ -36,7 +36,7 @@ import GHC.Internal.Num
import GHC.Internal.Data.Bits
import GHC.Internal.Data.Functor
import GHC.Internal.Data.Maybe (catMaybes)
-import GHC.Internal.Data.List
+import GHC.Internal.List
import GHC.Internal.Data.Tuple
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Foreign.Storable
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
=====================================
@@ -40,14 +40,14 @@ module GHC.Internal.System.Environment.Blank
) where
import GHC.Internal.Data.Functor
-import GHC.Internal.Data.List (elem, null, takeWhile)
+import GHC.Internal.List (elem, null, takeWhile)
import GHC.Internal.Foreign.C.String
import GHC.Internal.Base
#if defined(mingw32_HOST_OS)
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Windows
import GHC.Internal.Control.Monad
-import GHC.Internal.Data.List (lookup)
+import GHC.Internal.List (lookup)
#else
import GHC.Internal.Foreign.C.Error
import GHC.Internal.Foreign.C.Types
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
=====================================
@@ -53,7 +53,7 @@ import GHC.Internal.System.IO.Error (isDoesNotExistError)
import GHC.Internal.System.Posix.Internals
#elif defined(linux_HOST_OS) || defined(gnu_HOST_OS)
import GHC.Internal.Data.Functor
-import GHC.Internal.Data.List (isSuffixOf)
+import GHC.Internal.Data.OldList (isSuffixOf)
import GHC.Internal.Foreign.C.Types
import GHC.Internal.Foreign.C.Error
import GHC.Internal.Foreign.C.String
@@ -85,7 +85,7 @@ import GHC.Internal.System.Posix.Internals
import GHC.Internal.Control.Exception
import GHC.Internal.Control.Monad.Fail
import GHC.Internal.Data.Functor
-import GHC.Internal.Data.List (isPrefixOf, drop)
+import GHC.Internal.Data.OldList (isPrefixOf, drop)
import GHC.Internal.Word
import GHC.Internal.Foreign.C.String
import GHC.Internal.Foreign.Marshal.Array
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
=====================================
@@ -70,7 +70,7 @@ import GHC.Internal.Foreign.Storable
import qualified GHC.Internal.Foreign.C.String.Encoding as GHC
#else
import GHC.Internal.Int
-import GHC.Internal.Data.OldList (elem)
+import GHC.Internal.List (elem)
#endif
-- ---------------------------------------------------------------------------
=====================================
libraries/ghc-internal/src/GHC/Internal/Windows.hs
=====================================
@@ -80,7 +80,7 @@ module GHC.Internal.Windows (
import GHC.Internal.Data.Bits (finiteBitSize, shiftL, shiftR, (.|.), (.&.))
import GHC.Internal.Unicode (isSpace)
-import GHC.Internal.Data.OldList
+import GHC.Internal.List
import GHC.Internal.Data.Maybe
import GHC.Internal.Word
import GHC.Internal.Int
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a1f0bdcfc782163b20cb5ce6d5c91…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a1f0bdcfc782163b20cb5ce6d5c91…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
e3242e37 by sheaf at 2026-01-27T10:34:13+01:00
simplRec
- - - - -
1 changed file:
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
Changes:
=====================================
compiler/GHC/Core/Opt/Simplify/Iteration.hs
=====================================
@@ -2077,7 +2077,7 @@ simplNonRecJoinPoint env bndr rhs body cont
-- and wrap wrap_cont around the whole thing
; let (mult, res_ty)
-- SLD TODO
- | Just QuasiJoinPoint <- occInfoJoinPointType_maybe (idOccInfo bndr)
+ | Just QuasiJoinPoint <- joinId_maybe bndr
= (idMult bndr, peelJoinResTy (idJoinArity bndr) $ substTy env (idType bndr))
| otherwise
= (contHoleScaling cont, contResultType cont)
@@ -2102,7 +2102,7 @@ simplRecJoinPoint env pairs body cont
(mult, res_ty)
-- SLD TODO
| [b] <- bndrs
- , Just QuasiJoinPoint <- occInfoJoinPointType_maybe (idOccInfo b)
+ , Just QuasiJoinPoint <- joinId_maybe b
= (idMult b, peelJoinResTy (idJoinArity b) $ substTy env (idType b))
| otherwise
= (contHoleScaling cont, contResultType cont)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e3242e3706608000c4b6f79eff6c947…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e3242e3706608000c4b6f79eff6c947…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Add operations for obtaining operating-system handles
by Marge Bot (@marge-bot) 27 Jan '26
by Marge Bot (@marge-bot) 27 Jan '26
27 Jan '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
1fc0bd6a by Wolfgang Jeltsch at 2026-01-27T00:30:20-05:00
Add operations for obtaining operating-system handles
This contribution implements CLC proposal #369. It adds operations for
obtaining POSIX file descriptors and Windows handles that underlie
Haskell handles. Those operating system handles can also be obtained
without such additional operations, but this is more involved and, more
importantly, requires using internals.
- - - - -
bce2a8fa by Greg Steuck at 2026-01-27T00:30:29-05:00
Move flags to precede patterns for grep and read files directly
This makes the tests pass with non-GNU (i.e. POSIX-complicant) tools.
There's no reason to use cat and pipe where direct file argument works.
- - - - -
25 changed files:
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- + libraries/base/src/System/IO/OS.hs
- libraries/base/tests/IO/all.T
- + libraries/base/tests/IO/osHandles001FileDescriptors.hs
- + libraries/base/tests/IO/osHandles001FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles001WindowsHandles.hs
- + libraries/base/tests/IO/osHandles001WindowsHandles.stdout
- + libraries/base/tests/IO/osHandles002FileDescriptors.hs
- + libraries/base/tests/IO/osHandles002FileDescriptors.stderr
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdin
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles002WindowsHandles.hs
- + libraries/base/tests/IO/osHandles002WindowsHandles.stderr
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdin
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdout
- libraries/base/tests/perf/Makefile
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- testsuite/tests/driver/T16318/Makefile
- testsuite/tests/driver/T18125/Makefile
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
Changes:
=====================================
libraries/base/base.cabal.in
=====================================
@@ -255,6 +255,7 @@ Library
, System.Exit
, System.IO
, System.IO.Error
+ , System.IO.OS
, System.Mem
, System.Mem.StableName
, System.Posix.Internals
=====================================
libraries/base/changelog.md
=====================================
@@ -23,6 +23,7 @@
* `GHC.Conc.catchSTM` and `GHC.Conc.Sync.catchSTM` now attach `WhileHandling` annotation to exceptions thrown from the handler. ([GHC #25365](https://gitlab.haskell.org/ghc/ghc/-/issues/25365))
* Remove `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
* Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
+ * Add a new module `System.IO.OS` with operations for obtaining operating-system handles (file descriptors, Windows handles). ([CLC proposal #369](https://github.com/haskell/core-libraries-committee/issues/369))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/base/src/System/IO/OS.hs
=====================================
@@ -0,0 +1,62 @@
+{-# LANGUAGE Safe #-}
+
+{-|
+ This module bridges between Haskell handles and underlying operating-system
+ features.
+-}
+module System.IO.OS
+(
+ -- * Obtaining file descriptors and Windows handles
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+
+ -- ** Caveats
+ -- $with-ref-caveats
+)
+where
+
+import GHC.Internal.System.IO.OS
+ (
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+ )
+
+-- ** Caveats
+
+{-$with-ref-caveats
+ #with-ref-caveats#There are the following caveats regarding the above
+ operations:
+
+ * Flushing of buffers can fail if the given handle is readable but not
+ seekable.
+
+ * If one of these operations is performed as part of an action executed by
+ 'System.IO.Unsafe.unsafePerformIO',
+ 'System.IO.Unsafe.unsafeInterleaveIO', or one of their “dupable”
+ variants and the user-provided action receives an asychnchronous
+ exception and does not catch it, then the following happens:
+
+ - Before the overall computation is suspended, the blocking of handle
+ operations is removed.
+
+ - When the computation is later resumed due to another evaluation
+ attempt, the blocking of handle operations is reinstantiated, the
+ Haskell-managed buffers are flushed again, and the user-provided
+ action is run from the beginning.
+
+ Repeating the previously executed part of the user-provided action
+ cannot be avoided apparently. See the @[async]@ note in the source code
+ of "GHC.Internal.IO.Handle.Internals" for further explanation.
+-}
=====================================
libraries/base/tests/IO/all.T
=====================================
@@ -186,3 +186,15 @@ test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1)
test('T18832', only_ways(['threaded1']), compile_and_run, [''])
test('mkdirExists', [exit_code(1), when(opsys('mingw32'), ignore_stderr)], compile_and_run, [''])
+
+test('osHandles001FileDescriptors', omit_ways(['winio', 'winio_threaded']), compile_and_run, [''])
+test('osHandles001WindowsHandles', only_ways(['winio', 'winio_threaded']), compile_and_run, [''])
+test('osHandles002FileDescriptors', [when(opsys('mingw32'), skip), when(arch('javascript'), skip)], compile_and_run, [''])
+test('osHandles002WindowsHandles', only_ways(['winio', 'winio_threaded']), compile_and_run, [''])
+# It would be good to let `osHandles002FileDescriptors` run also on
+# Windows with the file-descriptor-based I/O manager. However, this
+# test, as it is currently implemented, requires the `unix` package.
+# That said, `UCRT.DLL`, which is used by GHC-generated Windows
+# executables, emulates part of POSIX, enough for this test. As a
+# result, this test could be generalized to also supporting Windows, but
+# this would likely involve creating bindings to C code.
=====================================
libraries/base/tests/IO/osHandles001FileDescriptors.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE TypeApplications #-}
+
+import Control.Monad (mapM_)
+import Control.Exception (SomeException, try)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+ )
+
+main :: IO ()
+main = mapM_ ((>>= print) . try @SomeException) $
+ [
+ withFileDescriptorReadingBiasedRaw stdin (return . show),
+ withFileDescriptorWritingBiasedRaw stdout (return . show),
+ withFileDescriptorWritingBiasedRaw stderr (return . show),
+ withWindowsHandleReadingBiasedRaw stdin (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stdout (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stderr (return . const "_")
+ ]
=====================================
libraries/base/tests/IO/osHandles001FileDescriptors.stdout
=====================================
@@ -0,0 +1,6 @@
+Right "0"
+Right "1"
+Right "2"
+Left <stdin>: withWindowsHandleReadingBiasedRaw: inappropriate type (handle does not use Windows handles)
+Left <stdout>: withWindowsHandleWritingBiasedRaw: inappropriate type (handle does not use Windows handles)
+Left <stderr>: withWindowsHandleWritingBiasedRaw: inappropriate type (handle does not use Windows handles)
=====================================
libraries/base/tests/IO/osHandles001WindowsHandles.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE TypeApplications #-}
+
+import Control.Monad (mapM_)
+import Control.Exception (SomeException, try)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+ )
+
+main :: IO ()
+main = mapM_ ((>>= print) . try @SomeException) $
+ [
+ withFileDescriptorReadingBiasedRaw stdin (return . show),
+ withFileDescriptorWritingBiasedRaw stdout (return . show),
+ withFileDescriptorWritingBiasedRaw stderr (return . show),
+ withWindowsHandleReadingBiasedRaw stdin (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stdout (return . const "_"),
+ withWindowsHandleWritingBiasedRaw stderr (return . const "_")
+ ]
=====================================
libraries/base/tests/IO/osHandles001WindowsHandles.stdout
=====================================
@@ -0,0 +1,6 @@
+Left <stdin>: withFileDescriptorReadingBiasedRaw: inappropriate type (handle does not use file descriptors)
+Left <stdout>: withFileDescriptorWritingBiasedRaw: inappropriate type (handle does not use file descriptors)
+Left <stderr>: withFileDescriptorWritingBiasedRaw: inappropriate type (handle does not use file descriptors)
+Right "_"
+Right "_"
+Right "_"
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.hs
=====================================
@@ -0,0 +1,28 @@
+import Data.Functor (void)
+import Data.ByteString.Char8 (pack)
+import System.Posix.Types (Fd (Fd), ByteCount)
+import System.Posix.IO.ByteString (fdRead, fdWrite)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased
+ )
+
+main :: IO ()
+main = withFileDescriptorReadingBiased stdin $ \ stdinFD ->
+ withFileDescriptorWritingBiased stdout $ \ stdoutFD ->
+ withFileDescriptorWritingBiased stderr $ \ stderrFD ->
+ do
+ regularMsg <- fdRead (Fd stdinFD) inputSizeApproximation
+ void $ fdWrite (Fd stdoutFD) regularMsg
+ void $ fdWrite (Fd stderrFD) (pack errorMsg)
+ where
+
+ inputSizeApproximation :: ByteCount
+ inputSizeApproximation = 100
+
+ errorMsg :: String
+ errorMsg = "And every single door\n\
+ \That I've walked through\n\
+ \Brings me back, back here again\n"
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.stderr
=====================================
@@ -0,0 +1,3 @@
+And every single door
+That I've walked through
+Brings me back, back here again
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.stdin
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/IO/osHandles002FileDescriptors.stdout
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.hs
=====================================
@@ -0,0 +1,49 @@
+import Control.Monad (zipWithM_)
+import Data.Functor (void)
+import Data.Char (ord)
+import Foreign.Marshal.Alloc (allocaBytes)
+import Foreign.Storable (pokeElemOff)
+import System.IO (stdin, stdout, stderr)
+import System.IO.OS
+ (
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased
+ )
+
+main :: IO ()
+main = withWindowsHandleReadingBiased stdin $ \ windowsStdin ->
+ withWindowsHandleWritingBiased stdout $ \ windowsStdout ->
+ withWindowsHandleWritingBiased stderr $ \ windowsStderr ->
+ do
+ withBuffer inputSizeApproximation $ \ bufferPtr -> do
+ inputSize <- win32_ReadFile windowsStdin
+ bufferPtr
+ inputSizeApproximation
+ Nothing
+ void $ win32_WriteFile windowsStdout
+ bufferPtr
+ inputSize
+ Nothing
+ withBuffer errorMsgSize $ \ bufferPtr -> do
+ zipWithM_ (pokeElemOff bufferPtr)
+ [0 ..]
+ (map (fromIntegral . ord) errorMsg)
+ void $ win32_WriteFile windowsStderr
+ bufferPtr
+ errorMsgSize
+ Nothing
+ where
+
+ withBuffer :: DWORD -> (Ptr Word8 -> IO a) -> IO a
+ withBuffer = allocaBytes . fromIntegral
+
+ inputSizeApproximation :: DWORD
+ inputSizeApproximation = 100
+
+ errorMsg :: String
+ errorMsg = "And every single door\n\
+ \That I've walked through\n\
+ \Brings me back, back here again\n"
+
+ errorMsgSize :: DWORD
+ errorMsgSize = fromIntegral (length errorMsg)
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.stderr
=====================================
@@ -0,0 +1,3 @@
+And every single door
+That I've walked through
+Brings me back, back here again
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.stdin
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/IO/osHandles002WindowsHandles.stdout
=====================================
@@ -0,0 +1 @@
+We've got to get in to get out
=====================================
libraries/base/tests/perf/Makefile
=====================================
@@ -12,4 +12,4 @@ T17752:
# All occurrences of elem should be optimized away.
# For strings these should result in loops after inlining foldCString.
# For lists it should result in a case expression.
- echo $$(cat T17752.dump-simpl | grep "elem" -A4 )
+ echo $$(grep -A4 "elem" T17752.dump-simpl)
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -328,6 +328,7 @@ Library
GHC.Internal.System.Exit
GHC.Internal.System.IO
GHC.Internal.System.IO.Error
+ GHC.Internal.System.IO.OS
GHC.Internal.System.Mem
GHC.Internal.System.Mem.StableName
GHC.Internal.System.Posix.Internals
=====================================
libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
=====================================
@@ -0,0 +1,323 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
+
+{-|
+ This module bridges between Haskell handles and underlying operating-system
+ features.
+-}
+module GHC.Internal.System.IO.OS
+(
+ -- * Obtaining file descriptors and Windows handles
+ withFileDescriptorReadingBiased,
+ withFileDescriptorWritingBiased,
+ withWindowsHandleReadingBiased,
+ withWindowsHandleWritingBiased,
+ withFileDescriptorReadingBiasedRaw,
+ withFileDescriptorWritingBiasedRaw,
+ withWindowsHandleReadingBiasedRaw,
+ withWindowsHandleWritingBiasedRaw
+
+ -- ** Caveats
+ -- $with-ref-caveats
+)
+where
+
+import GHC.Internal.Control.Monad (return)
+import GHC.Internal.Control.Concurrent.MVar (MVar)
+import GHC.Internal.Control.Exception (mask)
+import GHC.Internal.Data.Function (const, (.), ($))
+import GHC.Internal.Data.Functor (fmap)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.Data.Bool (otherwise)
+#endif
+import GHC.Internal.Data.Maybe (Maybe (Nothing), maybe)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.Data.Maybe (Maybe (Just))
+#endif
+import GHC.Internal.Data.List ((++))
+import GHC.Internal.Data.String (String)
+import GHC.Internal.Data.Typeable (Typeable, cast)
+import GHC.Internal.System.IO (IO)
+import GHC.Internal.IO.FD (fdFD)
+#if defined(mingw32_HOST_OS)
+import GHC.Internal.IO.Windows.Handle
+ (
+ NativeHandle,
+ ConsoleHandle,
+ IoHandle,
+ toHANDLE
+ )
+#endif
+import GHC.Internal.IO.Handle.Types
+ (
+ Handle (FileHandle, DuplexHandle),
+ Handle__ (Handle__, haDevice)
+ )
+import GHC.Internal.IO.Handle.Internals (withHandle_', flushBuffer)
+import GHC.Internal.IO.Exception
+ (
+ IOErrorType (InappropriateType),
+ IOException (IOError),
+ ioException
+ )
+import GHC.Internal.Foreign.Ptr (Ptr)
+import GHC.Internal.Foreign.C.Types (CInt)
+
+-- * Obtaining POSIX file descriptors and Windows handles
+
+{-|
+ Executes a user-provided action on an operating-system handle that underlies
+ a Haskell handle. Before the user-provided action is run, user-defined
+ preparation based on the handle state that contains the operating-system
+ handle is performed. While the user-provided action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withOSHandle :: String
+ -- ^ The name of the overall operation
+ -> (Handle -> MVar Handle__)
+ {-^
+ Obtaining of the handle state variable that holds the
+ operating-system handle
+ -}
+ -> (forall d. Typeable d => d -> IO a)
+ -- ^ Conversion of a device into an operating-system handle
+ -> (Handle__ -> IO ())
+ -- ^ The preparation
+ -> Handle
+ -- ^ The Haskell handle to use
+ -> (a -> IO r)
+ -- ^ The action to execute on the operating-system handle
+ -> IO r
+withOSHandle opName handleStateVar getOSHandle prepare handle act
+ = mask $ \ withOriginalMaskingState ->
+ withHandleState $ \ handleState@Handle__ {haDevice = dev} -> do
+ osHandle <- getOSHandle dev
+ prepare handleState
+ withOriginalMaskingState $ act osHandle
+ where
+
+ withHandleState = withHandle_' opName handle (handleStateVar handle)
+{-
+ The 'withHandle_'' operation, which we use here, already performs masking.
+ Still, we have to employ 'mask', in order do obtain the operation that
+ restores the original masking state. The user-provided action should be
+ executed with this original masking state, as there is no inherent reason to
+ generally perform it with masking in place. The masking that 'withHandle_''
+ performs is only for safely accessing handle state and thus constitutes an
+ implementation detail; it has nothing to do with the user-provided action.
+-}
+{-
+ The order of actions in 'withOSHandle' is such that any exception from
+ 'getOSHandle' is thrown before the user-defined preparation is performed.
+-}
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for reading if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarReadingBiased :: Handle -> MVar Handle__
+handleStateVarReadingBiased (FileHandle _ var) = var
+handleStateVarReadingBiased (DuplexHandle _ readingVar _) = readingVar
+
+{-|
+ Obtains the handle state variable that underlies a handle or specifically
+ the handle state variable for writing if the handle uses different state
+ variables for reading and writing.
+-}
+handleStateVarWritingBiased :: Handle -> MVar Handle__
+handleStateVarWritingBiased (FileHandle _ var) = var
+handleStateVarWritingBiased (DuplexHandle _ _ writingVar) = writingVar
+
+{-|
+ Yields the result of another operation if that operation succeeded, and
+ otherwise throws an exception that signals that the other operation failed
+ because some Haskell handle does not use an operating-system handle of a
+ required type.
+-}
+requiringOSHandleOfType :: String
+ -- ^ The name of the operating-system handle type
+ -> Maybe a
+ {-^
+ The result of the other operation if it succeeded
+ -}
+ -> IO a
+requiringOSHandleOfType osHandleTypeName
+ = maybe (ioException osHandleOfTypeRequired) return
+ where
+
+ osHandleOfTypeRequired :: IOException
+ osHandleOfTypeRequired
+ = IOError Nothing
+ InappropriateType
+ ""
+ ("handle does not use " ++ osHandleTypeName ++ "s")
+ Nothing
+ Nothing
+
+{-|
+ Obtains the POSIX file descriptor of a device if the device contains one,
+ and throws an exception otherwise.
+-}
+getFileDescriptor :: Typeable d => d -> IO CInt
+getFileDescriptor = requiringOSHandleOfType "POSIX file descriptor" .
+ fmap fdFD . cast
+
+{-|
+ Obtains the Windows handle of a device if the device contains one, and
+ throws an exception otherwise.
+-}
+getWindowsHandle :: Typeable d => d -> IO (Ptr ())
+getWindowsHandle = requiringOSHandleOfType "Windows handle" .
+ toMaybeWindowsHandle
+ where
+
+ toMaybeWindowsHandle :: Typeable d => d -> Maybe (Ptr ())
+#if defined(mingw32_HOST_OS)
+ toMaybeWindowsHandle dev
+ | Just nativeHandle <- cast dev :: Maybe (IoHandle NativeHandle)
+ = Just (toHANDLE nativeHandle)
+ | Just consoleHandle <- cast dev :: Maybe (IoHandle ConsoleHandle)
+ = Just (toHANDLE consoleHandle)
+ | otherwise
+ = Nothing
+ {-
+ This is inspired by the implementation of
+ 'System.Win32.Types.withHandleToHANDLENative'.
+ -}
+#else
+ toMaybeWindowsHandle _ = Nothing
+#endif
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for reading if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorReadingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiased = withOSHandle "withFileDescriptorReadingBiased"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the POSIX file descriptor that underlies
+ a handle or specifically on the POSIX file descriptor for writing if the
+ handle uses different file descriptors for reading and writing. The
+ Haskell-managed buffers related to the file descriptor are flushed before
+ the user-provided action is run. While this action is executed, further
+ operations on the handle are blocked to a degree that interference with this
+ action is prevented.
+
+ If the handle does not use POSIX file descriptors, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withFileDescriptorWritingBiased :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiased = withOSHandle "withFileDescriptorWritingBiased"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for reading if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleReadingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiased = withOSHandle "withWindowsHandleReadingBiased"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Executes a user-provided action on the Windows handle that underlies a
+ Haskell handle or specifically on the Windows handle for writing if the
+ Haskell handle uses different Windows handles for reading and writing. The
+ Haskell-managed buffers related to the Windows handle are flushed before the
+ user-provided action is run. While this action is executed, further
+ operations on the Haskell handle are blocked to a degree that interference
+ with this action is prevented.
+
+ If the Haskell handle does not use Windows handles, an exception is thrown.
+
+ See [below](#with-ref-caveats) for caveats regarding this operation.
+-}
+withWindowsHandleWritingBiased :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiased = withOSHandle "withWindowsHandleWritingBiased"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ flushBuffer
+
+{-|
+ Like 'withFileDescriptorReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorReadingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorReadingBiasedRaw
+ = withOSHandle "withFileDescriptorReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withFileDescriptorWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withFileDescriptorWritingBiasedRaw :: Handle -> (CInt -> IO r) -> IO r
+withFileDescriptorWritingBiasedRaw
+ = withOSHandle "withFileDescriptorWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getFileDescriptor
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleReadingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleReadingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleReadingBiasedRaw
+ = withOSHandle "withWindowsHandleReadingBiasedRaw"
+ handleStateVarReadingBiased
+ getWindowsHandle
+ (const $ return ())
+
+{-|
+ Like 'withWindowsHandleWritingBiased' except that Haskell-managed buffers
+ are not flushed.
+-}
+withWindowsHandleWritingBiasedRaw :: Handle -> (Ptr () -> IO r) -> IO r
+withWindowsHandleWritingBiasedRaw
+ = withOSHandle "withWindowsHandleWritingBiasedRaw"
+ handleStateVarWritingBiased
+ getWindowsHandle
+ (const $ return ())
+
+-- ** Caveats
+
+{-$with-ref-caveats
+ #with-ref-caveats#This subsection is just a dummy, whose purpose is to serve
+ as the target of the hyperlinks above. The real documentation of the caveats
+ is in the /Caveats/ subsection in the @base@ module @System.IO.OS@, which
+ re-exports the above operations.
+-}
=====================================
testsuite/tests/driver/T16318/Makefile
=====================================
@@ -7,5 +7,5 @@ test_pe = test-package-environment
T16318:
"$(GHC_PKG)" field base id --simple-output > $(test_pe)
"$(TEST_HC)" $(TEST_HC_OPTS) -v1 -ignore-dot-ghci -package-env $(test_pe) -e "putStrLn \"Hello\"" > out 2>&1
- C=`cat out | grep "Loaded package environment" -c` ; \
+ C=`grep -c "Loaded package environment" out` ; \
if [ $$C != "1" ]; then false; fi
=====================================
testsuite/tests/driver/T18125/Makefile
=====================================
@@ -9,5 +9,5 @@ T18125:
"$(GHC_PKG)" field base id --simple-output > $(test_pe)
"$(GHC_PKG)" field $(test_lib) id --simple-outpu >> $(test_pe)
"$(TEST_HC)" $(TEST_HC_OPTS) -Wunused-packages -package-env $(test_pe) T18125.hs > out 2>&1
- C=`cat out | grep "$(test_lib)" -c` ; \
+ C=`grep -c "$(test_lib)" out` ; \
if [ $$C != "1" ]; then false; fi
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -10048,6 +10048,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -10086,6 +10086,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -10328,6 +10328,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -10048,6 +10048,17 @@ module System.IO.Error where
userError :: GHC.Internal.Base.String -> IOError
userErrorType :: IOErrorType
+module System.IO.OS where
+ -- Safety: Safe
+ withFileDescriptorReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withFileDescriptorWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Foreign.C.Types.CInt -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleReadingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiased :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+ withWindowsHandleWritingBiasedRaw :: forall r. GHC.Internal.IO.Handle.Types.Handle -> (GHC.Internal.Ptr.Ptr () -> GHC.Internal.Types.IO r) -> GHC.Internal.Types.IO r
+
module System.IO.Unsafe where
-- Safety: Unsafe
unsafeDupablePerformIO :: forall a. GHC.Internal.Types.IO a -> a
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0b05ae7f3bab12fbb43cebdf18148e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0b05ae7f3bab12fbb43cebdf18148e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/26699] Refactoring after adding TTG extension
by recursion-ninja (@recursion-ninja) 27 Jan '26
by recursion-ninja (@recursion-ninja) 27 Jan '26
27 Jan '26
recursion-ninja pushed to branch wip/26699 at Glasgow Haskell Compiler / GHC
Commits:
631825ab by Recursion Ninja at 2026-01-26T19:24:37-05:00
Refactoring after adding TTG extension
- - - - -
22 changed files:
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Extension.hs
- − compiler/GHC/Hs/Extension.hs-boot
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Parser.y
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/ImportLevel.hs
- − compiler/GHC/Types/Name/RdrName.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/OverlapFlag.hs
- compiler/GHC/Types/OverlapMode.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- + compiler/Language/Haskell/Syntax/Decls/Overlap.hs
- ghc/GHCi/UI.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
Changes:
=====================================
compiler/GHC/Hs/Decls.hs
=====================================
@@ -101,6 +101,7 @@ module GHC.Hs.Decls (
import GHC.Prelude
import Language.Haskell.Syntax.Decls
+import Language.Haskell.Syntax.Decls.Overlap (OverlapMode(..))
import Language.Haskell.Syntax.Extension
import {-# SOURCE #-} GHC.Hs.Expr ( pprExpr, pprUntypedSplice )
=====================================
compiler/GHC/Hs/Extension.hs
=====================================
@@ -16,10 +16,11 @@ import GHC.Prelude
import Data.Data hiding ( Fixity )
import Language.Haskell.Syntax.Extension
import GHC.Types.Name
-import GHC.Types.Name.RdrName
+import GHC.Types.Name.Reader
import GHC.Types.Var
import GHC.Utils.Outputable hiding ((<>))
import GHC.Types.SrcLoc (GenLocated(..), unLoc)
+import GHC.Utils.Panic
import GHC.Parser.Annotation
{-
@@ -152,9 +153,9 @@ data GhcPass (c :: Pass) where
-- This really should never be entered, but the data-deriving machinery
-- needs the instance to exist.
instance Typeable p => Data (GhcPass p) where
- gunfold _ _ _ = error "instance Data GhcPass"
- toConstr _ = error "instance Data GhcPass"
- dataTypeOf _ = error "instance Data GhcPass"
+ gunfold _ _ _ = panic "instance Data GhcPass"
+ toConstr _ = panic "instance Data GhcPass"
+ dataTypeOf _ = panic "instance Data GhcPass"
data Pass = Parsed | Renamed | Typechecked
deriving (Data)
=====================================
compiler/GHC/Hs/Extension.hs-boot deleted
=====================================
@@ -1,34 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE RoleAnnotations #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE UndecidableSuperClasses #-} -- for IsPass; see Note [NoGhcTc]
-
-module GHC.Hs.Extension where
-
-import Data.Type.Equality (type (~))
-
--- | Used as a data type index for the hsSyn AST; also serves
--- as a singleton type for Pass
-data GhcPass (c :: Pass) where
- GhcPs :: GhcPass 'Parsed
- GhcRn :: GhcPass 'Renamed
- GhcTc :: GhcPass 'Typechecked
-
-data Pass = Parsed | Renamed | Typechecked
-
--- Type synonyms as a shorthand for tagging
-type GhcPs = GhcPass 'Parsed -- Output of parser
-type GhcRn = GhcPass 'Renamed -- Output of renamer
-type GhcTc = GhcPass 'Typechecked -- Output of typechecker
-
-type family NoGhcTcPass (p :: Pass) :: Pass where
- NoGhcTcPass 'Typechecked = 'Renamed
- NoGhcTcPass other = other
-
-class ( NoGhcTcPass (NoGhcTcPass p) ~ NoGhcTcPass p
- , IsPass (NoGhcTcPass p)
- ) => IsPass p where
- ghcPass :: GhcPass p
=====================================
compiler/GHC/Hs/Instances.hs
=====================================
@@ -32,8 +32,8 @@ import GHC.Parser.Annotation
import GHC.Types.Name.Reader (WithUserRdr(..))
import GHC.Types.InlinePragma (ActivationGhc)
import GHC.Data.BooleanFormula (BooleanFormula(..))
-import Language.Haskell.Syntax.Basic
import Language.Haskell.Syntax.Decls
+import Language.Haskell.Syntax.Decls.Overlap (OverlapMode(..))
import Language.Haskell.Syntax.Extension (Anno)
import Language.Haskell.Syntax.Binds.InlinePragma (ActivationX(..), InlinePragma(..))
=====================================
compiler/GHC/HsToCore/Quote.hs
=====================================
@@ -72,6 +72,7 @@ import GHC.Types.ForeignCall
import GHC.Types.Var
import GHC.Types.Id
import GHC.Types.InlinePragma
+import GHC.Types.OverlapMode
import GHC.Types.SourceText
import GHC.Types.TyThing
import GHC.Types.Name hiding( varName, tcName )
=====================================
compiler/GHC/Parser.y
=====================================
@@ -70,6 +70,7 @@ import GHC.Types.Error ( GhcHint(..) )
import GHC.Types.Fixity
import GHC.Types.ForeignCall
import GHC.Types.InlinePragma
+import GHC.Types.OverlapMode
import GHC.Types.SourceFile
import GHC.Types.SourceText
import GHC.Types.PkgQual
=====================================
compiler/GHC/ThToHs.hs
=====================================
@@ -39,10 +39,11 @@ import qualified GHC.Core.Coercion as Coercion ( Role(..) )
import GHC.Builtin.Types
import GHC.Builtin.Types.Prim( fUNTyCon )
import GHC.Types.Basic as Hs
-import GHC.Types.InlinePragma as Hs
import GHC.Types.ForeignCall
-import GHC.Types.Unique
+import GHC.Types.InlinePragma as Hs
+import GHC.Types.OverlapMode as Hs
import GHC.Types.SourceText
+import GHC.Types.Unique
import GHC.Utils.Lexeme
import GHC.Utils.Misc
import GHC.Data.FastString
=====================================
compiler/GHC/Types/ImportLevel.hs
=====================================
@@ -1,7 +1,14 @@
{-# LANGUAGE DerivingVia #-}
module GHC.Types.ImportLevel (
- ImportLevel(..), convImportLevel, convImportLevelSpec, allImportLevels,
+ -- * ImportLevel
+ -- ** Data-type
+ ImportLevel(..),
+ -- ** Enumeration
+ allImportLevels,
+ -- ** Conversion
+ convImportLevel,
+ convImportLevelSpec
) where
import GHC.Prelude
=====================================
compiler/GHC/Types/Name/RdrName.hs deleted
=====================================
@@ -1,202 +0,0 @@
-{-
-(c) The University of Glasgow 2006
-(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
--}
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE PatternSynonyms #-}
-
--- |
--- Export /only/ the 'RdrName' data-type.
---
--- Since 'RdrName' is an integral data-type found in many places throughout
--- the compiler, importing a module which exposes 'RdrName' can cause module
--- import cycles. By having a dedicated module which exports the bare minimum
--- necessary to expose the data-type definition, these module import cycles
--- can easily be avoided!
-module GHC.Types.Name.RdrName (
- -- * The main type
- RdrName(..),
- WithUserRdr(..),
- isExact_maybe,
- rdrNameOcc,
- ) where
-
-import GHC.Prelude
-
-import GHC.Types.Name
-import GHC.Unit.Module
-import GHC.Utils.Outputable
-
-import Data.Data
-import qualified Data.Semigroup as S
-
-{-
-************************************************************************
-* *
-\subsection{The main data type}
-* *
-************************************************************************
--}
-
--- | Reader Name
---
--- Do not use the data constructors of RdrName directly: prefer the family
--- of functions that creates them, such as 'mkRdrUnqual'
---
--- - Note: A Located RdrName will only have API Annotations if it is a
--- compound one,
--- e.g.
---
--- > `bar`
--- > ( ~ )
---
-data RdrName
- = Unqual OccName
- -- ^ Unqualified name
- --
- -- Used for ordinary, unqualified occurrences, e.g. @x@, @y@ or @Foo@.
- -- Create such a 'RdrName' with 'mkRdrUnqual'
-
- | Qual ModuleName OccName
- -- ^ Qualified name
- --
- -- A qualified name written by the user in
- -- /source/ code. The module isn't necessarily
- -- the module where the thing is defined;
- -- just the one from which it is imported.
- -- Examples are @Bar.x@, @Bar.y@ or @Bar.Foo@.
- -- Create such a 'RdrName' with 'mkRdrQual'
-
- | Orig Module OccName
- -- ^ Original name
- --
- -- An original name; the module is the /defining/ module.
- -- This is used when GHC generates code that will be fed
- -- into the renamer (e.g. from deriving clauses), but where
- -- we want to say \"Use Prelude.map dammit\". One of these
- -- can be created with 'mkOrig'
-
- | Exact Name
- -- ^ Exact name
- --
- -- We know exactly the 'Name'. This is used:
- --
- -- (1) When the parser parses built-in syntax like @[]@
- -- and @(,)@, but wants a 'RdrName' from it
- --
- -- (2) By Template Haskell, when TH has generated a unique name
- --
- -- Such a 'RdrName' can be created by using 'getRdrName' on a 'Name'
- deriving Data
-
-{-
-************************************************************************
-* *
-\subsection{Instances}
-* *
-************************************************************************
--}
-
-instance Eq RdrName where
- (Exact n1) == (Exact n2) = n1==n2
- -- Convert exact to orig
- (Exact n1) == r2@(Orig _ _) = nukeExact n1 == r2
- r1@(Orig _ _) == (Exact n2) = r1 == nukeExact n2
-
- (Orig m1 o1) == (Orig m2 o2) = m1==m2 && o1==o2
- (Qual m1 o1) == (Qual m2 o2) = m1==m2 && o1==o2
- (Unqual o1) == (Unqual o2) = o1==o2
- _ == _ = False
-
-instance HasOccName RdrName where
- occName = rdrNameOcc
-
-instance Ord RdrName where
- a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False }
- a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False }
- a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True }
- a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True }
-
- -- Exact < Unqual < Qual < Orig
- -- [Note: Apr 2004] We used to use nukeExact to convert Exact to Orig
- -- before comparing so that Prelude.map == the exact Prelude.map, but
- -- that meant that we reported duplicates when renaming bindings
- -- generated by Template Haskell; e.g
- -- do { n1 <- newName "foo"; n2 <- newName "foo";
- -- <decl involving n1,n2> }
- -- I think we can do without this conversion
- compare (Exact n1) (Exact n2) = n1 `compare` n2
- compare (Exact _) _ = LT
-
- compare (Unqual _) (Exact _) = GT
- compare (Unqual o1) (Unqual o2) = o1 `compare` o2
- compare (Unqual _) _ = LT
-
- compare (Qual _ _) (Exact _) = GT
- compare (Qual _ _) (Unqual _) = GT
- compare (Qual m1 o1) (Qual m2 o2) = compare o1 o2 S.<> compare m1 m2
- compare (Qual _ _) (Orig _ _) = LT
-
- compare (Orig m1 o1) (Orig m2 o2) = compare o1 o2 S.<> compare m1 m2
- compare (Orig _ _) _ = GT
-
-instance Outputable RdrName where
- ppr (Exact name) = ppr name
- ppr (Unqual occ) = ppr occ
- ppr (Qual mod occ) = ppr mod <> dot <> ppr occ
- ppr (Orig mod occ) = getPprStyle (\sty -> pprModulePrefix sty mod Nothing occ <> ppr occ)
-
-instance OutputableBndr RdrName where
- pprBndr _ n
- | isTvOcc (rdrNameOcc n) = char '@' <> ppr n
- | otherwise = ppr n
-
- pprInfixOcc rdr = pprInfixVar (isSymOcc (rdrNameOcc rdr)) (ppr rdr)
- pprPrefixOcc rdr
- | Just name <- isExact_maybe rdr = pprPrefixName name
- -- pprPrefixName has some special cases, so
- -- we delegate to them rather than reproduce them
- | otherwise = pprPrefixVar (isSymOcc (rdrNameOcc rdr)) (ppr rdr)
-
-isExact_maybe :: RdrName -> Maybe Name
-isExact_maybe (Exact n) = Just n
-isExact_maybe _ = Nothing
-
-nukeExact :: Name -> RdrName
-nukeExact n
- | isExternalName n = Orig (nameModule n) (nameOccName n)
- | otherwise = Unqual (nameOccName n)
-
-rdrNameOcc :: RdrName -> OccName
-rdrNameOcc (Qual _ occ) = occ
-rdrNameOcc (Unqual occ) = occ
-rdrNameOcc (Orig _ occ) = occ
-rdrNameOcc (Exact name) = nameOccName name
-
-rdrQual_maybe :: RdrName -> Maybe ModuleName
-rdrQual_maybe = \case
- Qual q _ -> Just q
- _ -> Nothing
-
---------------------------------------------------------------------------------
--- Preserving user-written qualification
-
--- | 'WithUserRdr' allows us to keep track of the original user-written
--- 'RdrName', and in particular, any user-written module qualification.
---
--- See Note [IdOcc] in Language.Haskell.Syntax.Extension.
-data WithUserRdr a = WithUserRdr RdrName a
- deriving stock (Functor, Foldable, Traversable)
-
-instance NamedThing a => NamedThing (WithUserRdr a) where
- getName (WithUserRdr _rdr a) = getName a
-instance Outputable (WithUserRdr Name) where
- ppr (WithUserRdr rdr name) =
- pprName_userQual (rdrQual_maybe rdr) name
-instance OutputableBndr (WithUserRdr Name) where
- pprBndr _ (WithUserRdr rdr name) =
- pprName_userQual (rdrQual_maybe rdr) name
- pprInfixOcc :: WithUserRdr Name -> SDoc
- pprInfixOcc = pprInfixName
- pprPrefixOcc = pprPrefixName
=====================================
compiler/GHC/Types/Name/Reader.hs
=====================================
@@ -117,13 +117,12 @@ import GHC.Data.FastString
import GHC.Data.Maybe
import GHC.Types.Avail
-import GHC.Types.Basic
+import GHC.Types.Basic ( TyConFlavour(..), tyConFlavourAssoc_maybe )
import GHC.Types.FieldLabel
import GHC.Types.GREInfo
import GHC.Types.ImportLevel
import GHC.Types.Name
import GHC.Types.Name.Env
-import GHC.Types.Name.RdrName
import GHC.Types.Name.Set
import GHC.Types.PkgQual
import GHC.Types.SrcLoc as SrcLoc
@@ -152,6 +151,65 @@ import qualified Data.Map.Strict as Map
import qualified Data.Semigroup as S
import System.IO.Unsafe ( unsafePerformIO )
+{-
+************************************************************************
+* *
+\subsection{The main data type}
+* *
+************************************************************************
+-}
+
+-- | Reader Name
+--
+-- Do not use the data constructors of RdrName directly: prefer the family
+-- of functions that creates them, such as 'mkRdrUnqual'
+--
+-- - Note: A Located RdrName will only have API Annotations if it is a
+-- compound one,
+-- e.g.
+--
+-- > `bar`
+-- > ( ~ )
+--
+data RdrName
+ = Unqual OccName
+ -- ^ Unqualified name
+ --
+ -- Used for ordinary, unqualified occurrences, e.g. @x@, @y@ or @Foo@.
+ -- Create such a 'RdrName' with 'mkRdrUnqual'
+
+ | Qual ModuleName OccName
+ -- ^ Qualified name
+ --
+ -- A qualified name written by the user in
+ -- /source/ code. The module isn't necessarily
+ -- the module where the thing is defined;
+ -- just the one from which it is imported.
+ -- Examples are @Bar.x@, @Bar.y@ or @Bar.Foo@.
+ -- Create such a 'RdrName' with 'mkRdrQual'
+
+ | Orig Module OccName
+ -- ^ Original name
+ --
+ -- An original name; the module is the /defining/ module.
+ -- This is used when GHC generates code that will be fed
+ -- into the renamer (e.g. from deriving clauses), but where
+ -- we want to say \"Use Prelude.map dammit\". One of these
+ -- can be created with 'mkOrig'
+
+ | Exact Name
+ -- ^ Exact name
+ --
+ -- We know exactly the 'Name'. This is used:
+ --
+ -- (1) When the parser parses built-in syntax like @[]@
+ -- and @(,)@, but wants a 'RdrName' from it
+ --
+ -- (2) By Template Haskell, when TH has generated a unique name
+ --
+ -- Such a 'RdrName' can be created by using 'getRdrName' on a 'Name'
+ deriving Data
+
{-
************************************************************************
* *
@@ -160,6 +218,15 @@ import System.IO.Unsafe ( unsafePerformIO )
************************************************************************
-}
+instance HasOccName RdrName where
+ occName = rdrNameOcc
+
+rdrNameOcc :: RdrName -> OccName
+rdrNameOcc (Qual _ occ) = occ
+rdrNameOcc (Unqual occ) = occ
+rdrNameOcc (Orig _ occ) = occ
+rdrNameOcc (Exact name) = nameOccName name
+
rdrNameSpace :: RdrName -> NameSpace
rdrNameSpace = occNameSpace . rdrNameOcc
@@ -226,6 +293,11 @@ nameRdrName name = Exact name
-- unique is still there for debug printing, particularly
-- of Types (which are converted to IfaceTypes before printing)
+nukeExact :: Name -> RdrName
+nukeExact n
+ | isExternalName n = Orig (nameModule n) (nameOccName n)
+ | otherwise = Unqual (nameOccName n)
+
isRdrDataCon :: RdrName -> Bool
isRdrTyVar :: RdrName -> Bool
isRdrTc :: RdrName -> Bool
@@ -263,6 +335,76 @@ isExact :: RdrName -> Bool
isExact (Exact _) = True
isExact _ = False
+isExact_maybe :: RdrName -> Maybe Name
+isExact_maybe (Exact n) = Just n
+isExact_maybe _ = Nothing
+
+{-
+************************************************************************
+* *
+\subsection{Instances}
+* *
+************************************************************************
+-}
+
+instance Outputable RdrName where
+ ppr (Exact name) = ppr name
+ ppr (Unqual occ) = ppr occ
+ ppr (Qual mod occ) = ppr mod <> dot <> ppr occ
+ ppr (Orig mod occ) = getPprStyle (\sty -> pprModulePrefix sty mod Nothing occ <> ppr occ)
+
+instance OutputableBndr RdrName where
+ pprBndr _ n
+ | isTvOcc (rdrNameOcc n) = char '@' <> ppr n
+ | otherwise = ppr n
+
+ pprInfixOcc rdr = pprInfixVar (isSymOcc (rdrNameOcc rdr)) (ppr rdr)
+ pprPrefixOcc rdr
+ | Just name <- isExact_maybe rdr = pprPrefixName name
+ -- pprPrefixName has some special cases, so
+ -- we delegate to them rather than reproduce them
+ | otherwise = pprPrefixVar (isSymOcc (rdrNameOcc rdr)) (ppr rdr)
+
+instance Eq RdrName where
+ (Exact n1) == (Exact n2) = n1==n2
+ -- Convert exact to orig
+ (Exact n1) == r2@(Orig _ _) = nukeExact n1 == r2
+ r1@(Orig _ _) == (Exact n2) = r1 == nukeExact n2
+
+ (Orig m1 o1) == (Orig m2 o2) = m1==m2 && o1==o2
+ (Qual m1 o1) == (Qual m2 o2) = m1==m2 && o1==o2
+ (Unqual o1) == (Unqual o2) = o1==o2
+ _ == _ = False
+
+instance Ord RdrName where
+ a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False }
+ a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False }
+ a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True }
+ a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True }
+
+ -- Exact < Unqual < Qual < Orig
+ -- [Note: Apr 2004] We used to use nukeExact to convert Exact to Orig
+ -- before comparing so that Prelude.map == the exact Prelude.map, but
+ -- that meant that we reported duplicates when renaming bindings
+ -- generated by Template Haskell; e.g
+ -- do { n1 <- newName "foo"; n2 <- newName "foo";
+ -- <decl involving n1,n2> }
+ -- I think we can do without this conversion
+ compare (Exact n1) (Exact n2) = n1 `compare` n2
+ compare (Exact _) _ = LT
+
+ compare (Unqual _) (Exact _) = GT
+ compare (Unqual o1) (Unqual o2) = o1 `compare` o2
+ compare (Unqual _) _ = LT
+
+ compare (Qual _ _) (Exact _) = GT
+ compare (Qual _ _) (Unqual _) = GT
+ compare (Qual m1 o1) (Qual m2 o2) = compare o1 o2 S.<> compare m1 m2
+ compare (Qual _ _) (Orig _ _) = LT
+
+ compare (Orig m1 o1) (Orig m2 o2) = compare o1 o2 S.<> compare m1 m2
+ compare (Orig _ _) _ = GT
+
{-
************************************************************************
* *
@@ -2076,6 +2218,29 @@ pprLoc (UnhelpfulSpan {}) = empty
opIsAt :: RdrName -> Bool
opIsAt e = e == mkUnqual varName (fsLit "@")
+
+--------------------------------------------------------------------------------
+-- Preserving user-written qualification
+
+-- | 'WithUserRdr' allows us to keep track of the original user-written
+-- 'RdrName', and in particular, any user-written module qualification.
+--
+-- See Note [IdOcc] in Language.Haskell.Syntax.Extension.
+data WithUserRdr a = WithUserRdr RdrName a
+ deriving stock (Functor, Foldable, Traversable)
+
+instance NamedThing a => NamedThing (WithUserRdr a) where
+ getName (WithUserRdr _rdr a) = getName a
+instance Outputable (WithUserRdr Name) where
+ ppr (WithUserRdr rdr name) =
+ pprName_userQual (rdrQual_maybe rdr) name
+instance OutputableBndr (WithUserRdr Name) where
+ pprBndr _ (WithUserRdr rdr name) =
+ pprName_userQual (rdrQual_maybe rdr) name
+ pprInfixOcc :: WithUserRdr Name -> SDoc
+ pprInfixOcc = pprInfixName
+ pprPrefixOcc = pprPrefixName
+
unLocWithUserRdr :: GenLocated l (WithUserRdr a) -> a
unLocWithUserRdr (L _ (WithUserRdr _ a)) = a
@@ -2084,3 +2249,10 @@ noUserRdr n = WithUserRdr (nameRdrName n) n
userRdrName :: WithUserRdr Name -> RdrName
userRdrName (WithUserRdr rdr _) = rdr
+
+rdrQual_maybe :: RdrName -> Maybe ModuleName
+rdrQual_maybe = \case
+ Qual q _ -> Just q
+ _ -> Nothing
+
+--------------------------------------------------------------------------------
=====================================
compiler/GHC/Types/OverlapFlag.hs
=====================================
@@ -41,7 +41,7 @@ import GHC.Utils.Binary
import GHC.Utils.Outputable
import GHC.Types.OverlapMode (changeOverlapModePass)
-import Language.Haskell.Syntax.Basic (OverlapMode(..))
+import Language.Haskell.Syntax.Decls.Overlap (OverlapMode(..))
import Control.DeepSeq (NFData(..))
=====================================
compiler/GHC/Types/OverlapMode.hs
=====================================
@@ -5,6 +5,13 @@
{-# LANGUAGE TypeFamilies #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-
+ * (type class): Binary OverlapMode
+ * (type family): XOverlapMode (GhcPass p)
+ * (type family): XXOverlapMode (GhcPass p)
+-}
+
module GHC.Types.OverlapMode (
-- * OverlapMode
-- ** Data-type
@@ -21,15 +28,13 @@ module GHC.Types.OverlapMode (
import GHC.Prelude
-import {-# SOURCE #-} GHC.Hs.Extension (GhcPass)
-
+import GHC.Hs.Extension (GhcPass)
import GHC.Types.SourceText
+import GHC.Utils.Binary
-import Language.Haskell.Syntax.Basic (OverlapMode(..))
+import Language.Haskell.Syntax.Decls.Overlap (OverlapMode(..))
import Language.Haskell.Syntax.Extension
-import Control.DeepSeq ( NFData(..) )
-
type instance XOverlapMode (GhcPass _) = SourceText
type instance XXOverlapMode (GhcPass _) = DataConCantHappen
@@ -77,3 +82,21 @@ hasNonCanonicalFlag :: OverlapMode (GhcPass p) -> Bool
hasNonCanonicalFlag = \case
NonCanonical{} -> True
_ -> False
+
+instance Binary (OverlapMode (GhcPass p)) where
+ put_ bh (NoOverlap s) = putByte bh 0 >> put_ bh s
+ put_ bh (Overlaps s) = putByte bh 1 >> put_ bh s
+ put_ bh (Incoherent s) = putByte bh 2 >> put_ bh s
+ put_ bh (Overlapping s) = putByte bh 3 >> put_ bh s
+ put_ bh (Overlappable s) = putByte bh 4 >> put_ bh s
+ put_ bh (NonCanonical s) = putByte bh 5 >> put_ bh s
+
+ get bh = do
+ h <- getByte bh
+ case h of
+ 0 -> (get bh) >>= \s -> return $ NoOverlap s
+ 1 -> (get bh) >>= \s -> return $ Overlaps s
+ 2 -> (get bh) >>= \s -> return $ Incoherent s
+ 3 -> (get bh) >>= \s -> return $ Overlapping s
+ 4 -> (get bh) >>= \s -> return $ Overlappable s
+ _ -> (get bh) >>= \s -> return $ NonCanonical s
=====================================
compiler/GHC/Types/SourceText.hs
=====================================
@@ -32,6 +32,7 @@ import GHC.Prelude
import GHC.Data.FastString
import GHC.Utils.Outputable
+import GHC.Utils.Binary
import GHC.Utils.Panic
import Data.Function (on)
@@ -112,6 +113,21 @@ instance NFData SourceText where
SourceText s -> rnf s
NoSourceText -> ()
+instance Binary SourceText where
+ put_ bh NoSourceText = putByte bh 0
+ put_ bh (SourceText s) = do
+ putByte bh 1
+ put_ bh s
+
+ get bh = do
+ h <- getByte bh
+ case h of
+ 0 -> return NoSourceText
+ 1 -> do
+ s <- get bh
+ return (SourceText s)
+ _ -> panic $ "Binary SourceText:" ++ show h
+
-- | Special combinator for showing string literals.
pprWithSourceText :: SourceText -> SDoc -> SDoc
pprWithSourceText NoSourceText d = d
=====================================
compiler/GHC/Unit/Types.hs
=====================================
@@ -82,6 +82,7 @@ import GHC.Prelude
import GHC.Types.Unique
import GHC.Types.Unique.DSet
+import GHC.Utils.Binary
import GHC.Utils.Outputable
import GHC.Data.FastString
import GHC.Utils.Encoding
@@ -135,6 +136,11 @@ mkModule = Module
instance Uniquable Module where
getUnique (Module p n) = getUnique (unitFS p `appendFS` moduleNameFS n)
+instance Binary a => Binary (GenModule a) where
+ put_ bh (Module p n) = put_ bh p >> put_ bh n
+ -- Module has strict fields, so use $! in order not to allocate a thunk
+ get bh = do p <- get bh; n <- get bh; return $! Module p n
+
instance NFData (GenModule a) where
rnf (Module unit name) = unit `seq` name `seq` ()
@@ -293,6 +299,23 @@ instance Eq (GenInstantiatedUnit unit) where
instance Ord (GenInstantiatedUnit unit) where
u1 `compare` u2 = instUnitFS u1 `lexicalCompareFS` instUnitFS u2
+instance Binary InstantiatedUnit where
+ put_ bh indef = do
+ put_ bh (instUnitInstanceOf indef)
+ put_ bh (instUnitInsts indef)
+ get bh = do
+ cid <- get bh
+ insts <- get bh
+ let fs = mkInstantiatedUnitHash cid insts
+ -- InstantiatedUnit has strict fields, so use $! in order not to allocate a thunk
+ return $! InstantiatedUnit {
+ instUnitInstanceOf = cid,
+ instUnitInsts = insts,
+ instUnitHoles = unionManyUniqDSets (map (moduleFreeHoles.snd) insts),
+ instUnitFS = fs,
+ instUnitKey = getUnique fs
+ }
+
instance IsUnitId u => Eq (GenUnit u) where
uid1 == uid2 = unitUnique uid1 == unitUnique uid2
@@ -326,6 +349,24 @@ pprUnit HoleUnit = ftext holeFS
instance Show Unit where
show = unitString
+-- Performance: would prefer to have a NameCache like thing
+instance Binary Unit where
+ put_ bh (RealUnit def_uid) = do
+ putByte bh 0
+ put_ bh def_uid
+ put_ bh (VirtUnit indef_uid) = do
+ putByte bh 1
+ put_ bh indef_uid
+ put_ bh HoleUnit =
+ putByte bh 2
+ get bh = do b <- getByte bh
+ u <- case b of
+ 0 -> fmap RealUnit (get bh)
+ 1 -> fmap VirtUnit (get bh)
+ _ -> pure HoleUnit
+ -- Unit has strict fields that need forcing; otherwise we allocate a thunk.
+ pure $! u
+
-- | Retrieve the set of free module holes of a 'Unit'.
unitFreeModuleHoles :: GenUnit u -> UniqDSet ModuleName
unitFreeModuleHoles (VirtUnit x) = instUnitHoles x
@@ -468,6 +509,10 @@ newtype UnitId = UnitId
instance NFData UnitId where
rnf (UnitId fs) = rnf fs `seq` ()
+instance Binary UnitId where
+ put_ bh (UnitId fs) = put_ bh fs
+ get bh = do fs <- get bh; return (UnitId fs)
+
instance Eq UnitId where
uid1 == uid2 = getUnique uid1 == getUnique uid2
@@ -503,7 +548,7 @@ stringToUnitId = UnitId . mkFastString
-- | A definite unit (i.e. without any free module hole)
newtype Definite unit = Definite { unDefinite :: unit }
deriving (Functor)
- deriving newtype (Eq, Ord, Outputable, Uniquable, IsUnitId)
+ deriving newtype (Eq, Ord, Outputable, Binary, Uniquable, IsUnitId)
---------------------------------------------------------------------
-- WIRED-IN UNITS
@@ -651,6 +696,15 @@ type ModuleNameWithIsBoot = GenWithIsBoot ModuleName
type ModuleWithIsBoot = GenWithIsBoot Module
+instance Binary a => Binary (GenWithIsBoot a) where
+ put_ bh (GWIB { gwib_mod, gwib_isBoot }) = do
+ put_ bh gwib_mod
+ put_ bh gwib_isBoot
+ get bh = do
+ gwib_mod <- get bh
+ gwib_isBoot <- get bh
+ pure $ GWIB { gwib_mod, gwib_isBoot }
+
instance Outputable a => Outputable (GenWithIsBoot a) where
ppr (GWIB { gwib_mod, gwib_isBoot }) = hsep $ ppr gwib_mod : case gwib_isBoot of
IsBoot -> [ text "{-# SOURCE #-}" ]
=====================================
compiler/GHC/Utils/Binary.hs
=====================================
@@ -120,8 +120,8 @@ import GHC.Prelude
import Language.Haskell.Syntax.Basic
import Language.Haskell.Syntax.Binds.InlinePragma
import Language.Haskell.Syntax.Module.Name (ModuleName(..))
+import Language.Haskell.Syntax.ImpExp.IsBoot (IsBootInterface(..))
-import {-# SOURCE #-} GHC.Hs.Extension (GhcPass)
import {-# SOURCE #-} GHC.Types.Name (Name)
import GHC.Data.FastString
import GHC.Data.TrieMap
@@ -130,19 +130,14 @@ import GHC.Utils.Panic.Plain
import GHC.Types.Unique.FM
import GHC.Data.FastMutInt
import GHC.Utils.Fingerprint
-import GHC.Types.OverlapMode
-import GHC.Types.SourceText
import GHC.Types.SrcLoc
import GHC.Types.Unique
-import GHC.Unit.Types
import qualified GHC.Data.Strict as Strict
import GHC.Utils.Outputable( JoinPointHood(..) )
import GHCi.FFI
import GHCi.Message
-import GHC.Types.Unique.DSet ( unionManyUniqDSets )
-
-import Control.DeepSeq ( NFData(..) )
+import Control.DeepSeq
import Control.Monad ( when, (<$!>), unless, forM_, void )
import Foreign hiding (bit, setBit, clearBit, shiftL, shiftR, void)
import Data.Array
@@ -2017,85 +2012,6 @@ instance NFData a => NFData (FingerprintWithValue a) where
rnf (FingerprintWithValue fp mflags)
= rnf fp `seq` rnf mflags `seq` ()
-instance Binary SourceText where
- put_ bh NoSourceText = putByte bh 0
- put_ bh (SourceText s) = do
- putByte bh 1
- put_ bh s
-
- get bh = do
- h <- getByte bh
- case h of
- 0 -> return NoSourceText
- 1 -> do
- s <- get bh
- return (SourceText s)
- _ -> panic $ "Binary SourceText:" ++ show h
-
---------------------------------------------------------------------------------
--- Instances for the GHC.Unit.Types module
---------------------------------------------------------------------------------
-
-instance Binary a => Binary (GenModule a) where
- put_ bh (Module p n) = put_ bh p >> put_ bh n
- -- Module has strict fields, so use $! in order not to allocate a thunk
- get bh = do p <- get bh; n <- get bh; return $! Module p n
-
-instance Binary InstantiatedUnit where
- put_ bh indef = do
- put_ bh (instUnitInstanceOf indef)
- put_ bh (instUnitInsts indef)
- get bh = do
- cid <- get bh
- insts <- get bh
- let fs = mkInstantiatedUnitHash cid insts
- -- InstantiatedUnit has strict fields, so use $! in order not to allocate a t\
-hunk
- return $! InstantiatedUnit {
- instUnitInstanceOf = cid,
- instUnitInsts = insts,
- instUnitHoles = unionManyUniqDSets (map (moduleFreeHoles.snd) ins\
-ts),
- instUnitFS = fs,
- instUnitKey = getUnique fs
- }
-
--- Performance: would prefer to have a NameCache like thing
-instance Binary Unit where
- put_ bh (RealUnit def_uid) = do
- putByte bh 0
- put_ bh def_uid
- put_ bh (VirtUnit indef_uid) = do
- putByte bh 1
- put_ bh indef_uid
- put_ bh HoleUnit =
- putByte bh 2
- get bh = do b <- getByte bh
- u <- case b of
- 0 -> fmap RealUnit (get bh)
- 1 -> fmap VirtUnit (get bh)
- _ -> pure HoleUnit
- -- Unit has strict fields that need forcing; otherwise we allocate \
-a thunk.
- pure $! u
-
-instance Binary UnitId where
- put_ bh (UnitId fs) = put_ bh fs
- get bh = do fs <- get bh; return (UnitId fs)
-
-instance Binary a => Binary (GenWithIsBoot a) where
- put_ bh (GWIB { gwib_mod, gwib_isBoot }) = do
- put_ bh gwib_mod
- put_ bh gwib_isBoot
- get bh = do
- gwib_mod <- get bh
- gwib_isBoot <- get bh
- pure $ GWIB { gwib_mod, gwib_isBoot }
-
-deriving newtype instance Binary x => Binary (Definite x)
-
---------------------------------------------------------------------------------
-
instance Binary Boxity where -- implemented via isBoxed-isomorphism to Bool
put_ bh = put_ bh . isBoxed
get bh = do
@@ -2164,21 +2080,3 @@ instance Binary RuleMatchInfo where
h <- getByte bh
if h == 1 then pure ConLike
else pure FunLike
-
-instance Binary (OverlapMode (GhcPass p)) where
- put_ bh (NoOverlap s) = putByte bh 0 >> put_ bh s
- put_ bh (Overlaps s) = putByte bh 1 >> put_ bh s
- put_ bh (Incoherent s) = putByte bh 2 >> put_ bh s
- put_ bh (Overlapping s) = putByte bh 3 >> put_ bh s
- put_ bh (Overlappable s) = putByte bh 4 >> put_ bh s
- put_ bh (NonCanonical s) = putByte bh 5 >> put_ bh s
-
- get bh = do
- h <- getByte bh
- case h of
- 0 -> (get bh) >>= \s -> return $ NoOverlap s
- 1 -> (get bh) >>= \s -> return $ Overlaps s
- 2 -> (get bh) >>= \s -> return $ Incoherent s
- 3 -> (get bh) >>= \s -> return $ Overlapping s
- 4 -> (get bh) >>= \s -> return $ Overlappable s
- _ -> (get bh) >>= \s -> return $ NonCanonical s
=====================================
compiler/GHC/Utils/Outputable.hs
=====================================
@@ -114,6 +114,7 @@ import {-# SOURCE #-} GHC.Types.Name.Occurrence( OccName )
import Language.Haskell.Syntax.Basic
import Language.Haskell.Syntax.Binds.InlinePragma
+import Language.Haskell.Syntax.Decls.Overlap ( OverlapMode(..) )
import Language.Haskell.Syntax.Module.Name ( ModuleName(..) )
import GHC.Prelude.Basic
=====================================
compiler/Language/Haskell/Syntax/Basic.hs
=====================================
@@ -3,8 +3,11 @@
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE UndecidableInstances #-} -- Eq XOverlapMode, NFData OverlapMode
+-- | Data-type defintions of the Abstrast Sytntax Tree
+-- which *do not* have any /Trees That Grow/ extension points.
module Language.Haskell.Syntax.Basic where
+import Control.DeepSeq
import Data.Data (Data)
import Data.Eq
import Data.Ord
@@ -12,8 +15,6 @@ import Data.Bool
import Prelude
import GHC.Data.FastString (FastString)
-import Language.Haskell.Syntax.Extension
-import Control.DeepSeq
{-
************************************************************************
@@ -161,81 +162,3 @@ data Fixity = Fixity Int FixityDirection
instance NFData Fixity where
rnf (Fixity i d) = rnf i `seq` rnf d `seq` ()
-
-data OverlapMode pass -- See Note [Rules for instance lookup] in GHC.Core.InstEnv
- = NoOverlap (XOverlapMode pass)
- -- See Note [Pragma source text]
- -- ^ This instance must not overlap another `NoOverlap` instance.
- -- However, it may be overlapped by `Overlapping` instances,
- -- and it may overlap `Overlappable` instances.
-
-
- | Overlappable (XOverlapMode pass)
- -- See Note [Pragma source text]
- -- ^ Silently ignore this instance if you find a
- -- more specific one that matches the constraint
- -- you are trying to resolve
- --
- -- Example: constraint (Foo [Int])
- -- instance Foo [Int]
- -- instance {-# OVERLAPPABLE #-} Foo [a]
- --
- -- Since the second instance has the Overlappable flag,
- -- the first instance will be chosen (otherwise
- -- its ambiguous which to choose)
-
- | Overlapping (XOverlapMode pass)
- -- See Note [Pragma source text]
- -- ^ Silently ignore any more general instances that may be
- -- used to solve the constraint.
- --
- -- Example: constraint (Foo [Int])
- -- instance {-# OVERLAPPING #-} Foo [Int]
- -- instance Foo [a]
- --
- -- Since the first instance has the Overlapping flag,
- -- the second---more general---instance will be ignored (otherwise
- -- it is ambiguous which to choose)
-
- | Overlaps (XOverlapMode pass)
- -- See Note [Pragma source text]
- -- ^ Equivalent to having both `Overlapping` and `Overlappable` flags.
-
- | Incoherent (XOverlapMode pass)
- -- See Note [Pragma source text]
- -- ^ Behave like Overlappable and Overlapping, and in addition pick
- -- an arbitrary one if there are multiple matching candidates, and
- -- don't worry about later instantiation
- --
- -- Example: constraint (Foo [b])
- -- instance {-# INCOHERENT -} Foo [Int]
- -- instance Foo [a]
- -- Without the Incoherent flag, we'd complain that
- -- instantiating 'b' would change which instance
- -- was chosen. See also Note [Incoherent instances] in "GHC.Core.InstEnv"
-
- | NonCanonical (XOverlapMode pass)
- -- ^ Behave like Incoherent, but the instance choice is observable
- -- by the program behaviour. See Note [Coherence and specialisation: overview].
- --
- -- We don't have surface syntax for the distinction between
- -- Incoherent and NonCanonical instances; instead, the flag
- -- `-f{no-}specialise-incoherents` (on by default) controls
- -- whether `INCOHERENT` instances are regarded as Incoherent or
- -- NonCanonical.
-
- | XOverlapMode !(XXOverlapMode pass)
- -- ^ The /Trees That Grow/ extension point constructor.
-
-deriving instance ( Eq (XOverlapMode pass)
- , Eq (XXOverlapMode pass)) => Eq (OverlapMode pass)
-
-instance ( NFData (XOverlapMode pass)
- , XXOverlapMode pass ~ DataConCantHappen) => NFData (OverlapMode pass) where
- rnf = \case
- NoOverlap s -> rnf s
- Overlappable s -> rnf s
- Overlapping s -> rnf s
- Overlaps s -> rnf s
- Incoherent s -> rnf s
- NonCanonical s -> rnf s
=====================================
compiler/Language/Haskell/Syntax/Decls.hs
=====================================
@@ -88,16 +88,17 @@ module Language.Haskell.Syntax.Decls (
-- friends:
import {-# SOURCE #-} Language.Haskell.Syntax.Expr
- ( HsExpr, HsUntypedSplice )
+ (HsExpr, HsUntypedSplice)
-- Because Expr imports Decls via HsBracket
-import Language.Haskell.Syntax.Basic (OverlapMode, RuleName, TopLevelFlag)
+import Language.Haskell.Syntax.Basic
+ (LexicalFixity, Role, RuleName, TopLevelFlag)
import Language.Haskell.Syntax.Binds
import Language.Haskell.Syntax.Binds.InlinePragma (Activation)
+import Language.Haskell.Syntax.Decls.Overlap (OverlapMode)
import Language.Haskell.Syntax.Extension
-import Language.Haskell.Syntax.Type
-import Language.Haskell.Syntax.Basic (Role, LexicalFixity)
import Language.Haskell.Syntax.Specificity (Specificity)
+import Language.Haskell.Syntax.Type
import GHC.Types.ForeignCall (CType, CCallConv, Safety, Header, CLabelString, CCallTarget, CExportSpec)
@@ -118,7 +119,7 @@ import Prelude (Show)
import Data.Foldable
import Data.Traversable
import Data.List.NonEmpty (NonEmpty (..))
-import GHC.Generics ( Generic )
+import GHC.Generics (Generic)
{-
=====================================
compiler/Language/Haskell/Syntax/Decls/Overlap.hs
=====================================
@@ -0,0 +1,96 @@
+{-# LANGUAGE GeneralisedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverlappingInstances #-}
+{-# LANGUAGE UndecidableInstances #-} -- Eq XOverlapMode, NFData OverlapMode
+
+{- |
+Data-type describing the state of "overlapping instances" for a type.
+-}
+module Language.Haskell.Syntax.Decls.Overlap where
+
+import Control.DeepSeq
+import Data.Eq
+import Prelude
+
+import Language.Haskell.Syntax.Extension
+
+-- | The status of overlapping instances /(including no overlap)/ for a type.
+data OverlapMode pass -- See Note [Rules for instance lookup] in GHC.Core.InstEnv
+ = NoOverlap (XOverlapMode pass)
+ -- See Note [Pragma source text]
+ -- ^ This instance must not overlap another `NoOverlap` instance.
+ -- However, it may be overlapped by `Overlapping` instances,
+ -- and it may overlap `Overlappable` instances.
+
+
+ | Overlappable (XOverlapMode pass)
+ -- See Note [Pragma source text]
+ -- ^ Silently ignore this instance if you find a
+ -- more specific one that matches the constraint
+ -- you are trying to resolve
+ --
+ -- Example: constraint (Foo [Int])
+ -- instance Foo [Int]
+ -- instance {-# OVERLAPPABLE #-} Foo [a]
+ --
+ -- Since the second instance has the Overlappable flag,
+ -- the first instance will be chosen (otherwise
+ -- its ambiguous which to choose)
+
+ | Overlapping (XOverlapMode pass)
+ -- See Note [Pragma source text]
+ -- ^ Silently ignore any more general instances that may be
+ -- used to solve the constraint.
+ --
+ -- Example: constraint (Foo [Int])
+ -- instance {-# OVERLAPPING #-} Foo [Int]
+ -- instance Foo [a]
+ --
+ -- Since the first instance has the Overlapping flag,
+ -- the second---more general---instance will be ignored (otherwise
+ -- it is ambiguous which to choose)
+
+ | Overlaps (XOverlapMode pass)
+ -- See Note [Pragma source text]
+ -- ^ Equivalent to having both `Overlapping` and `Overlappable` flags.
+
+ | Incoherent (XOverlapMode pass)
+ -- See Note [Pragma source text]
+ -- ^ Behave like Overlappable and Overlapping, and in addition pick
+ -- an arbitrary one if there are multiple matching candidates, and
+ -- don't worry about later instantiation
+ --
+ -- Example: constraint (Foo [b])
+ -- instance {-# INCOHERENT -} Foo [Int]
+ -- instance Foo [a]
+ -- Without the Incoherent flag, we'd complain that
+ -- instantiating 'b' would change which instance
+ -- was chosen. See also Note [Incoherent instances] in "GHC.Core.InstEnv"
+
+ | NonCanonical (XOverlapMode pass)
+ -- ^ Behave like Incoherent, but the instance choice is observable
+ -- by the program behaviour. See Note [Coherence and specialisation: overview].
+ --
+ -- We don't have surface syntax for the distinction between
+ -- Incoherent and NonCanonical instances; instead, the flag
+ -- `-f{no-}specialise-incoherents` (on by default) controls
+ -- whether `INCOHERENT` instances are regarded as Incoherent or
+ -- NonCanonical.
+
+ | XOverlapMode !(XXOverlapMode pass)
+ -- ^ The /Trees That Grow/ extension point constructor.
+
+deriving instance ( Eq (XOverlapMode pass)
+ , Eq (XXOverlapMode pass)
+ ) => Eq (OverlapMode pass)
+
+instance ( NFData (XOverlapMode pass)
+ , XXOverlapMode pass ~ DataConCantHappen
+ ) => NFData (OverlapMode pass) where
+ rnf = \case
+ NoOverlap s -> rnf s
+ Overlappable s -> rnf s
+ Overlapping s -> rnf s
+ Overlaps s -> rnf s
+ Incoherent s -> rnf s
+ NonCanonical s -> rnf s
=====================================
ghc/GHCi/UI.hs
=====================================
@@ -75,6 +75,7 @@ import GHC.Core.TyCo.Ppr
import GHC.Types.SafeHaskell ( getSafeMode )
import GHC.Types.SourceError ( SourceError, initSourceErrorContext )
import GHC.Types.Name
+import GHC.Types.ImportLevel ( convImportLevel )
import GHC.Types.Var ( varType )
import GHC.Iface.Syntax ( showToHeader )
import GHC.Builtin.Names
=====================================
utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
=====================================
@@ -40,7 +40,7 @@ import GHC.Driver.DynFlags (getDynFlags)
import GHC.Types.Basic (TupleSort (..))
import GHC.Types.Name
import GHC.Types.Name.Reader (RdrName (Exact))
-import GHC.Types.OverlapMode (changeOverlapModeType)
+import GHC.Types.OverlapMode (OverlapMode, changeOverlapModeType)
import Language.Haskell.Syntax.BooleanFormula(BooleanFormula(..))
import Haddock.Backends.Hoogle (ppExportD)
=====================================
utils/haddock/haddock-api/src/Haddock/Types.hs
=====================================
@@ -59,6 +59,7 @@ import GHC.Core.InstEnv (is_dfun_name)
import GHC.Types.Name (stableNameCmp)
import GHC.Types.Name.Occurrence
import GHC.Types.Name.Reader (RdrName (..))
+import GHC.Types.OverlapMode (OverlapMode)
import GHC.Types.SrcLoc (srcSpanToRealSrcSpan)
import GHC.Types.Var (Specificity)
import GHC.Utils.Outputable
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/631825abd5f66565616eaa5e314f1ea…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/631825abd5f66565616eaa5e314f1ea…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Move flags to precede patterns for grep and read files directly
by Marge Bot (@marge-bot) 26 Jan '26
by Marge Bot (@marge-bot) 26 Jan '26
26 Jan '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
4d17cac9 by Greg Steuck at 2026-01-26T18:32:42-05:00
Move flags to precede patterns for grep and read files directly
This makes the tests pass with non-GNU (i.e. POSIX-complicant) tools.
There's no reason to use cat and pipe where direct file argument works.
- - - - -
0b05ae7f by Matthew Pickering at 2026-01-26T18:32:42-05:00
Evaluate backtraces for "error" exceptions at the moment they are thrown
See Note [Capturing the backtrace in throw] and
Note [Hiding precise exception signature in throw] which explain the
implementation.
This commit makes `error` and `throw` behave the same with regard to
backtraces. Previously, exceptions raised by `error` would not contain
useful IPE backtraces.
I did try and implement `error` in terms of `throw` but it started to
involve putting diverging functions into hs-boot files, which seemed to
risky if the compiler wouldn't be able to see if applying a function
would diverge.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/383
Fixes #26751
- - - - -
12 changed files:
- libraries/base/changelog.md
- libraries/base/tests/perf/Makefile
- libraries/ghc-internal/src/GHC/Internal/Err.hs
- libraries/ghc-internal/tests/stack-annotation/all.T
- + libraries/ghc-internal/tests/stack-annotation/ann_frame005.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- testsuite/tests/driver/T16318/Makefile
- testsuite/tests/driver/T18125/Makefile
- testsuite/tests/ghci.debugger/scripts/T8487.stdout
- testsuite/tests/ghci.debugger/scripts/break011.stdout
- testsuite/tests/ghci.debugger/scripts/break017.stdout
- testsuite/tests/ghci.debugger/scripts/break025.stdout
Changes:
=====================================
libraries/base/changelog.md
=====================================
@@ -23,6 +23,7 @@
* `GHC.Conc.catchSTM` and `GHC.Conc.Sync.catchSTM` now attach `WhileHandling` annotation to exceptions thrown from the handler. ([GHC #25365](https://gitlab.haskell.org/ghc/ghc/-/issues/25365))
* Remove `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
* Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
+ * Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/base/tests/perf/Makefile
=====================================
@@ -12,4 +12,4 @@ T17752:
# All occurrences of elem should be optimized away.
# For strings these should result in loops after inlining foldCString.
# For lists it should result in a case expression.
- echo $$(cat T17752.dump-simpl | grep "elem" -A4 )
+ echo $$(grep -A4 "elem" T17752.dump-simpl)
=====================================
libraries/ghc-internal/src/GHC/Internal/Err.hs
=====================================
@@ -1,6 +1,7 @@
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude, MagicHash, ImplicitParams #-}
{-# LANGUAGE RankNTypes, PolyKinds, DataKinds #-}
+{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_HADDOCK not-home #-}
-----------------------------------------------------------------------------
@@ -25,6 +26,7 @@
module GHC.Internal.Err( absentErr, error, errorWithoutStackTrace, undefined ) where
import GHC.Internal.Types (Char, RuntimeRep)
import GHC.Internal.Stack.Types
+import GHC.Internal.Magic
import GHC.Internal.Prim
import {-# SOURCE #-} GHC.Internal.Exception
( errorCallWithCallStackException
@@ -33,7 +35,10 @@ import {-# SOURCE #-} GHC.Internal.Exception
-- | 'error' stops execution and displays an error message.
error :: forall (r :: RuntimeRep). forall (a :: TYPE r).
HasCallStack => [Char] -> a
-error s = raise# (errorCallWithCallStackException s ?callStack)
+error s =
+ -- See Note [Capturing the backtrace in throw] and Note [Hiding precise exception signature in throw]
+ let !se = noinline (errorCallWithCallStackException s ?callStack)
+ in raise# se
-- Bleh, we should be using 'GHC.Internal.Stack.callStack' instead of
-- '?callStack' here, but 'GHC.Internal.Stack.callStack' depends on
-- 'GHC.Internal.Stack.popCallStack', which is partial and depends on
@@ -73,7 +78,10 @@ undefined :: forall (r :: RuntimeRep). forall (a :: TYPE r).
-- nor wanted (see #19886). We’d like to use withFrozenCallStack, but that
-- is not available in this module yet, and making it so is hard. So let’s just
-- use raise# directly.
-undefined = raise# (errorCallWithCallStackException "Prelude.undefined" ?callStack)
+undefined =
+ -- See Note [Capturing the backtrace in throw] and Note [Hiding precise exception signature in throw]
+ let !se = noinline (errorCallWithCallStackException "Prelude.undefined" ?callStack)
+ in raise# se
-- | Used for compiler-generated error message;
-- encoding saves bytes of string junk.
=====================================
libraries/ghc-internal/tests/stack-annotation/all.T
=====================================
@@ -8,3 +8,4 @@ test('ann_frame001', ann_frame_opts, compile_and_run, [''])
test('ann_frame002', ann_frame_opts, compile_and_run, [''])
test('ann_frame003', ann_frame_opts, compile_and_run, [''])
test('ann_frame004', ann_frame_opts, compile_and_run, [''])
+test('ann_frame005', ann_frame_opts, compile_and_run, [''])
=====================================
libraries/ghc-internal/tests/stack-annotation/ann_frame005.hs
=====================================
@@ -0,0 +1,73 @@
+import Control.Concurrent.STM
+import Control.Exception
+import Control.Exception.Backtrace (BacktraceMechanism(IPEBacktrace), setBacktraceMechanismState)
+import Control.Exception.Context (displayExceptionContext)
+import Control.Monad
+import Data.List (isInfixOf)
+import TestUtils
+
+data SimpleBoom = SimpleBoom deriving (Show)
+
+instance Exception SimpleBoom
+
+main :: IO ()
+main = do
+ setBacktraceMechanismState IPEBacktrace True
+ mapM_ (uncurry runCase)
+ [ ("throwIO SimpleBoom", throwIOAction)
+ , ("undefined", undefinedAction)
+ , ("error", errorAction)
+ , ("throwSTM", throwSTMAction)
+ ]
+
+runCase :: String -> IO () -> IO ()
+runCase label action = do
+ putStrLn ("=== " ++ label ++ " ===")
+ annotateCallStackIO $
+ annotateStackStringIO ("catch site for " ++ label) $
+ catch action (handler label)
+
+throwIOAction :: IO ()
+throwIOAction =
+ annotateStackStringIO "raising action" $
+ annotateStackStringIO "throwIO SimpleBoom" $
+ throwIO SimpleBoom
+
+undefinedAction :: IO ()
+undefinedAction =
+ annotateStackStringIO "raising undefined action" $
+ void $
+ evaluate $
+ annotateStackString "undefined thunk" (undefined :: Int)
+
+errorAction :: IO ()
+errorAction =
+ annotateStackStringIO "raising error action" $
+ void $
+ evaluate $
+ annotateStackString "error thunk" (error "error from annotateStackString" :: Int)
+
+throwSTMAction :: IO ()
+throwSTMAction =
+ annotateStackStringIO "raising throwSTM action" $
+ atomically $
+ annotateStackString "throwSTM SimpleBoom" $
+ throwSTM SimpleBoom
+
+handler :: String -> SomeException -> IO ()
+handler label se =
+ annotateStackStringIO ("handler for " ++ label) $
+ annotateStackStringIO ("forcing SomeException for " ++ label) $ do
+ message <- evaluate (displayException se)
+ putStrLn ("Caught exception: " ++ message)
+ let ctx = displayExceptionContext (someExceptionContext se)
+ ctxLines = lines ctx
+ putStrLn "Exception context:"
+ case ctxLines of
+ [] -> putStrLn "<empty>"
+ ls -> mapM_ (putStrLn . ("- " ++)) ls
+ let handlerTag = "handler for " ++ label
+ -- Check that the callstack is from the callsite, not the handling site
+ when (any (handlerTag `isInfixOf`) ctxLines) $
+ error $ "handler annotation leaked into context for " ++ label
+ putStrLn "Handler annotation not present in context"
=====================================
libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
=====================================
@@ -0,0 +1,45 @@
+=== throwIO SimpleBoom ===
+Caught exception: SimpleBoom
+Exception context:
+- IPE backtrace:
+- throwIO SimpleBoom
+- raising action
+- catch site for throwIO SimpleBoom
+- annotateCallStackIO, called at ann_frame005.hs:26:3 in main:Main
+- HasCallStack backtrace:
+- throwIO, called at ann_frame005.hs:34:7 in main:Main
+Handler annotation not present in context
+=== undefined ===
+Caught exception: Prelude.undefined
+Exception context:
+- IPE backtrace:
+- undefined thunk
+- raising undefined action
+- catch site for undefined
+- annotateCallStackIO, called at ann_frame005.hs:26:3 in main:Main
+- HasCallStack backtrace:
+- undefined, called at ann_frame005.hs:41:48 in main:Main
+Handler annotation not present in context
+=== error ===
+Caught exception: error from annotateStackString
+Exception context:
+- IPE backtrace:
+- error thunk
+- raising error action
+- catch site for error
+- annotateCallStackIO, called at ann_frame005.hs:26:3 in main:Main
+- HasCallStack backtrace:
+- error, called at ann_frame005.hs:48:44 in main:Main
+Handler annotation not present in context
+=== throwSTM ===
+Caught exception: SimpleBoom
+Exception context:
+- IPE backtrace:
+- raising throwSTM action
+- catch site for throwSTM
+- annotateCallStackIO, called at ann_frame005.hs:26:3 in main:Main
+- HasCallStack backtrace:
+- collectExceptionAnnotation, called at libraries/ghc-internal/src/GHC/Internal/Exception.hs:170:37 in ghc-internal:GHC.Internal.Exception
+- toExceptionWithBacktrace, called at libraries/ghc-internal/src/GHC/Internal/STM.hs:190:26 in ghc-internal:GHC.Internal.STM
+- throwSTM, called at ann_frame005.hs:55:9 in main:Main
+Handler annotation not present in context
=====================================
testsuite/tests/driver/T16318/Makefile
=====================================
@@ -7,5 +7,5 @@ test_pe = test-package-environment
T16318:
"$(GHC_PKG)" field base id --simple-output > $(test_pe)
"$(TEST_HC)" $(TEST_HC_OPTS) -v1 -ignore-dot-ghci -package-env $(test_pe) -e "putStrLn \"Hello\"" > out 2>&1
- C=`cat out | grep "Loaded package environment" -c` ; \
+ C=`grep -c "Loaded package environment" out` ; \
if [ $$C != "1" ]; then false; fi
=====================================
testsuite/tests/driver/T18125/Makefile
=====================================
@@ -9,5 +9,5 @@ T18125:
"$(GHC_PKG)" field base id --simple-output > $(test_pe)
"$(GHC_PKG)" field $(test_lib) id --simple-outpu >> $(test_pe)
"$(TEST_HC)" $(TEST_HC_OPTS) -Wunused-packages -package-env $(test_pe) T18125.hs > out 2>&1
- C=`cat out | grep "$(test_lib)" -c` ; \
+ C=`grep -c "$(test_lib)" out` ; \
if [ $$C != "1" ]; then false; fi
=====================================
testsuite/tests/ghci.debugger/scripts/T8487.stdout
=====================================
@@ -1,4 +1,5 @@
Breakpoint 0 activated at T8487.hs:(5,8)-(7,53)
Stopped in Main.f, T8487.hs:(5,8)-(7,53)
_result :: IO String = _
-ma :: Either SomeException String = Left _
+ma :: Either SomeException String = Left
+ (SomeException (ErrorCall ...))
=====================================
testsuite/tests/ghci.debugger/scripts/break011.stdout
=====================================
@@ -4,9 +4,10 @@ HasCallStack backtrace:
error, called at <interactive>:2:1 in interactive:Ghci1
Stopped in <exception thrown>, <unknown>
-_exception :: e = _
+_exception :: e = GHC.Internal.Exception.Type.SomeException
+ (GHC.Internal.Exception.ErrorCall _)
Stopped in <exception thrown>, <unknown>
-_exception :: e = _
+_exception :: e = SomeException (ErrorCall _)
-1 : main (Test7.hs:2:18-28)
-2 : main (Test7.hs:2:8-29)
<end of history>
@@ -26,7 +27,7 @@ _exception :: SomeException = SomeException (ErrorCall "foo")
*** Exception: foo
HasCallStack backtrace:
- error, called at Test7.hs:2:18 in main:Main
+ error, called at Test7.hs:2:18 in interactive-session:Main
Stopped in <exception thrown>, <unknown>
_exception :: e = _
@@ -35,5 +36,5 @@ _exception :: e = _
*** Exception: foo
HasCallStack backtrace:
- error, called at Test7.hs:2:18 in main:Main
+ error, called at Test7.hs:2:18 in interactive-session:Main
=====================================
testsuite/tests/ghci.debugger/scripts/break017.stdout
=====================================
@@ -1,5 +1,6 @@
"Stopped in <exception thrown>, <unknown>
-_exception :: e = _
+_exception :: e = GHC.Internal.Exception.Type.SomeException
+ (GHC.Internal.Exception.ErrorCall _)
Logged breakpoint at QSort.hs:6:32-34
_result :: Char -> Bool
a :: Char
=====================================
testsuite/tests/ghci.debugger/scripts/break025.stdout
=====================================
@@ -1,3 +1,4 @@
Stopped in <exception thrown>, <unknown>
-_exception :: e = _
+_exception :: e = GHC.Internal.Exception.Type.SomeException
+ (GHC.Internal.Exception.ErrorCall _)
()
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a56b0585109fb60738130e6be0d2fc…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a56b0585109fb60738130e6be0d2fc…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
26 Jan '26
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
e4500d48 by sheaf at 2026-01-26T23:46:57+01:00
fix fix
- - - - -
5239e258 by sheaf at 2026-01-27T00:01:20+01:00
working?
- - - - -
4 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
Changes:
=====================================
compiler/GHC/Core/Lint.hs
=====================================
@@ -1151,7 +1151,11 @@ lintJoinBndrType :: OutType -- Type of the body
-- E.g. join j x = rhs in body
-- The type of 'rhs' must be the same as the type of 'body'
lintJoinBndrType body_ty bndr
- | JoinPoint { joinPointArity = arity } <- idJoinPointHood bndr
+ | JoinPoint
+ { joinPointArity = arity
+ , joinPointType = TrueJoinPoint
+ -- SLD TODO: quasi join points can have intervening casts
+ } <- idJoinPointHood bndr
, let bndr_ty = idType bndr
, (bndrs, res) <- splitPiTys bndr_ty
= do let msg =
=====================================
compiler/GHC/Core/Opt/OccurAnal.hs
=====================================
@@ -1127,7 +1127,7 @@ occAnalNonRecRhs !env lvl imp_rule_edges mb_join bndr rhs
-- returned by of occAnalLamTail. It's totally OK for them to mismatch;
-- hence adjust the UDs from the RHS
- WUD adj_rhs_uds final_rhs = adjustNonRecRhs (joinPointHoodArity mb_join) $
+ WUD adj_rhs_uds final_rhs = adjustNonRecRhs mb_join $
occAnalLamTail rhs_env rhs
final_bndr_with_rules
| noBinderSwaps env = bndr -- See Note [Unfoldings and rules]
@@ -1217,7 +1217,7 @@ occAnalRec !_ lvl
= WUD body_uds binds
| otherwise
= let (bndr', mb_join) = tagNonRecBinder lvl occ bndr
- !(WUD rhs_uds' rhs') = adjustNonRecRhs (joinPointHoodArity mb_join) wtuds
+ !(WUD rhs_uds' rhs') = adjustNonRecRhs mb_join wtuds
in WUD (body_uds `andUDs` rhs_uds')
(NonRec bndr' rhs' : binds)
where
@@ -2621,7 +2621,7 @@ occAnal env app@(App _ _)
= occAnalApp env (collectArgsTicks tickishFloatable app)
occAnal env expr@(Lam {})
- = adjustNonRecRhs Nothing $ -- Nothing <=> markAllManyNonTail
+ = adjustNonRecRhs NotJoinPoint $ -- NotJoinPoint <=> markAllManyNonTail
occAnalLamTail env expr
occAnal env (Case scrut bndr ty alts)
@@ -2749,7 +2749,7 @@ occAnalApp env (Var fun, args, ticks)
-- This caused #18296
| fun `hasKey` runRWKey
, [t1, t2, arg] <- args
- , WUD usage arg' <- adjustNonRecRhs (Just 1) $ occAnalLamTail env arg
+ , WUD usage arg' <- adjustNonRecRhs (JoinPoint TrueJoinPoint 1) $ occAnalLamTail env arg
= let app_out = mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']
in WUD usage app_out
@@ -3975,21 +3975,21 @@ lookupOccInfoByUnique (UD { ud_env = env
-------------------
-- See Note [Adjusting right-hand sides]
-adjustNonRecRhs :: Maybe JoinArity
+adjustNonRecRhs :: JoinPointHood
-> WithTailUsageDetails CoreExpr
-> WithUsageDetails CoreExpr
-- ^ This function concentrates shared logic between occAnalNonRecBind and the
-- AcyclicSCC case of occAnalRec.
-- It returns the adjusted rhs UsageDetails combined with the body usage
-adjustNonRecRhs mb_join_arity (WTUD (TUD rhs_ja uds) rhs)
+adjustNonRecRhs mb_join (WTUD (TUD rhs_ja uds) rhs)
= WUD (adjustTailUsage exact_join rhs uds) rhs
where
exact_join =
- case mb_join_arity of
- Nothing -> Nothing
- Just ja' ->
+ case mb_join of
+ NotJoinPoint -> Nothing
+ JoinPoint { joinPointArity = ja', joinPointType = ty } ->
if ja' == rhs_ja
- then Just TrueJoinPoint
+ then Just ty
else Nothing
adjustTailUsage :: HasDebugCallStack
@@ -4120,11 +4120,8 @@ decideRecJoinPointHood :: TopLevelFlag -> UsageDetails
-> [CoreBndr] -> Maybe JoinPointType
decideRecJoinPointHood lvl usage bndrs = do
bndrsNE <- NE.nonEmpty bndrs
- res <- Semi.sconcat <$> traverse ok bndrsNE -- Invariant 3: Either all are join points or none are
- pprTraceM "decideRecJoinPointHood" $
- vcat [ text "bndrs:" <+> ppr bndrs
- , text "res:" <+> ppr res ]
- return res
+ -- Invariant 3: Either all are join points or none are
+ Semi.sconcat <$> traverse ok bndrsNE
where
ok bndr = okForJoinPoint lvl bndr (lookupTailCallInfo usage bndr)
@@ -4132,10 +4129,11 @@ okForJoinPoint :: TopLevelFlag -> Id -> TailCallInfo -> Maybe JoinPointType
-- See Note [Invariants on join points]; invariants cited by number below.
-- Invariant 2 is always satisfiable by the simplifier by eta expansion.
okForJoinPoint lvl bndr tail_call_info
- | Just join_ty <- joinId_maybe bndr
+ | isJoinId bndr
-- A current join point should still be one!
= warnPprTrace lost_join "Lost join point" lost_join_doc $
- Just join_ty
+ mb_valid_join
+ -- NB: we might downgrade 'TrueJoinPoint' to 'QuasiJoinPoint'.
| otherwise
= mb_valid_join
where
=====================================
compiler/GHC/Core/Opt/SetLevels.hs
=====================================
@@ -1895,7 +1895,7 @@ newPolyBndrs dest_lvl
, not dest_is_top
= asJoinId new_bndr
join_ty
- ( join_arity + length abs_vars )
+ (join_arity + length abs_vars)
| otherwise
= new_bndr
=====================================
compiler/GHC/Core/Opt/Simplify/Iteration.hs
=====================================
@@ -2088,7 +2088,7 @@ simplNonRecJoinPoint env bndr rhs body cont
; return (floats1 `addFloats` floats2, body') }
where
do_case_case
- | Just TrueJoinPoint <- occInfoJoinPointType_maybe (idOccInfo bndr)
+ | Just TrueJoinPoint <- joinId_maybe bndr
= seCaseCase env
| otherwise
= False
@@ -2114,7 +2114,7 @@ simplRecJoinPoint env pairs body cont
; return (floats1 `addFloats` floats2, body') }
where
do_case_case =
- if all ((== Just TrueJoinPoint) . occInfoJoinPointType_maybe . idOccInfo . fst) pairs
+ if all ((== Just TrueJoinPoint) . joinId_maybe . fst) pairs
then seCaseCase env
else False
@@ -2154,15 +2154,15 @@ trimJoinCont :: Id -- Used only in error message
trimJoinCont _ NotJoinPoint cont
= cont -- Not a jump
trimJoinCont var (JoinPoint { joinPointType = join_ty, joinPointArity = arity }) cont
- | QuasiJoinPoint <- join_ty
- -- SLD TODO
- = cont
- | otherwise
= trim arity cont
where
trim 0 cont@(Stop {})
= cont
trim 0 cont
+ | QuasiJoinPoint <- join_ty
+ -- SLD TODO explain
+ = cont
+ | otherwise
= mkBoringStop (contResultType cont)
trim n cont@(ApplyToVal { sc_cont = k })
= cont { sc_cont = trim (n-1) k }
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a3ef7ffcc6418ab11ba039915f9951…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a3ef7ffcc6418ab11ba039915f9951…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26834] 2 commits: Delete unecessary GHC.Internal.Data.Ix
by Teo Camarasu (@teo) 26 Jan '26
by Teo Camarasu (@teo) 26 Jan '26
26 Jan '26
Teo Camarasu pushed to branch wip/T26834 at Glasgow Haskell Compiler / GHC
Commits:
ffdda2af by Teo Camarasu at 2026-01-26T22:06:19+00:00
Delete unecessary GHC.Internal.Data.Ix
- - - - -
2a1f0bdc by Teo Camarasu at 2026-01-26T22:22:43+00:00
ghc-internal: refine List imports
- - - - -
17 changed files:
- libraries/base/src/Data/Ix.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- − libraries/ghc-internal/src/GHC/Internal/Data/Ix.hs
- libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs
- libraries/ghc-internal/src/GHC/Internal/Data/String.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/ExecutionStack/Internal.hsc
- libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage.hs
- libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
- libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
- libraries/ghc-internal/src/GHC/Internal/Windows.hs
Changes:
=====================================
libraries/base/src/Data/Ix.hs
=====================================
@@ -1,4 +1,4 @@
-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Trustworthy #-}
-- |
--
@@ -42,4 +42,4 @@ module Data.Ix
-- <https://www.haskell.org/onlinereport/haskell2010/haskellch19.html>.
) where
-import GHC.Internal.Data.Ix
+import GHC.Internal.Ix
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -153,7 +153,6 @@ Library
GHC.Internal.Data.Functor.Identity
GHC.Internal.Data.Functor.Utils
GHC.Internal.Data.IORef
- GHC.Internal.Data.Ix
GHC.Internal.Data.List
GHC.Internal.Data.List.NonEmpty
GHC.Internal.Data.Maybe
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs
=====================================
@@ -28,7 +28,7 @@ import GHC.Internal.Data.Proxy
--import qualified Data.List.NonEmpty as NE
import GHC.Internal.Generics
import qualified GHC.Internal.Data.List.NonEmpty as NE
-import qualified GHC.Internal.Data.List as List
+import qualified GHC.Internal.List as List
import GHC.Internal.Data.Maybe
import GHC.Internal.Data.Tuple
--import Prelude
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
=====================================
@@ -117,7 +117,7 @@ import GHC.Internal.Data.Maybe
import GHC.Internal.Data.Monoid
import GHC.Internal.Data.NonEmpty ( NonEmpty(..) )
import GHC.Internal.Data.Ord
-import GHC.Internal.Data.List (findIndex)
+import GHC.Internal.Data.OldList (findIndex)
import GHC.Internal.Data.Typeable
import GHC.Internal.Data.Version( Version(..) )
import GHC.Internal.Base hiding (Any, IntRep, FloatRep, NonEmpty(..))
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Ix.hs deleted
=====================================
@@ -1,64 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-
------------------------------------------------------------------------------
--- |
--- Module : GHC.Internal.Data.Ix
--- Copyright : (c) The University of Glasgow 2001
--- License : BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer : libraries(a)haskell.org
--- Stability : stable
--- Portability : portable
---
--- The 'Ix' class is used to map a contiguous subrange of values in
--- type onto integers. It is used primarily for array indexing
--- (see the array package). 'Ix' uses row-major order.
---
------------------------------------------------------------------------------
-
-module GHC.Internal.Data.Ix
- (
- -- * The 'Ix' class
- Ix
- ( range
- , index
- , inRange
- , rangeSize
- )
- -- Ix instances:
- --
- -- Ix Char
- -- Ix Int
- -- Ix Integer
- -- Ix Bool
- -- Ix Ordering
- -- Ix ()
- -- (Ix a, Ix b) => Ix (a, b)
- -- ...
-
- -- * Deriving Instances of 'Ix'
- -- | Derived instance declarations for the class 'Ix' are only possible
- -- for enumerations (i.e. datatypes having only nullary constructors)
- -- and single-constructor datatypes, including arbitrarily large tuples,
- -- whose constituent types are instances of 'Ix'.
- --
- -- * For an enumeration, the nullary constructors are assumed to be
- -- numbered left-to-right with the indices being 0 to n-1 inclusive. This
- -- is the same numbering defined by the 'Enum' class. For example, given
- -- the datatype:
- --
- -- > data Colour = Red | Orange | Yellow | Green | Blue | Indigo | Violet
- --
- -- we would have:
- --
- -- > range (Yellow,Blue) == [Yellow,Green,Blue]
- -- > index (Yellow,Blue) Green == 1
- -- > inRange (Yellow,Blue) Red == False
- --
- -- * For single-constructor datatypes, the derived instance declarations
- -- are as shown for tuples in chapter 19, section 2 of the Haskell 2010 report:
- -- <https://www.haskell.org/onlinereport/haskell2010/haskellch19.html>.
-
- ) where
-
-import GHC.Internal.Ix
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs
=====================================
@@ -8,7 +8,7 @@ module GHC.Internal.Data.List.NonEmpty
) where
import GHC.Internal.Data.NonEmpty (NonEmpty (..), map)
-import qualified GHC.Internal.Data.List as List
+import qualified GHC.Internal.List as List
-- | The 'zip' function takes two streams and returns a stream of
-- corresponding pairs.
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/String.hs
=====================================
@@ -35,7 +35,7 @@ module GHC.Internal.Data.String (
import GHC.Internal.Base
import GHC.Internal.Data.Functor.Const (Const (Const))
import GHC.Internal.Data.Functor.Identity (Identity (Identity))
-import GHC.Internal.Data.List (lines, words, unlines, unwords)
+import GHC.Internal.Data.OldList (lines, words, unlines, unwords)
-- | `IsString` is used in combination with the @-XOverloadedStrings@
-- language extension to convert the literals to different string types.
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
=====================================
@@ -40,7 +40,7 @@ import GHC.Internal.Data.Functor ( Functor(..) )
import GHC.Internal.Data.Bool ( (&&) )
import GHC.Internal.Data.Eq
import GHC.Internal.Int ( Int )
-import GHC.Internal.Data.List ( map, sort, concat, concatMap, intersperse, (++) )
+import GHC.Internal.Data.OldList ( map, sort, concat, concatMap, intersperse, (++) )
import GHC.Internal.Data.Ord
import GHC.Internal.Data.String ( String )
import GHC.Internal.Base ( Applicative(..) )
=====================================
libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
=====================================
@@ -103,7 +103,7 @@ import GHC.Internal.IORef
import GHC.Internal.Maybe
import GHC.Internal.Ptr
import GHC.Internal.Word
-import GHC.Internal.Data.OldList (deleteBy)
+import GHC.Internal.List (deleteBy)
import qualified GHC.Internal.Event.Array as A
import GHC.Internal.Base
import GHC.Internal.Conc.Bound
=====================================
libraries/ghc-internal/src/GHC/Internal/ExecutionStack/Internal.hsc
=====================================
@@ -39,7 +39,7 @@ module GHC.Internal.ExecutionStack.Internal (
import GHC.Internal.Data.Functor
import GHC.Internal.Data.Maybe
-import GHC.Internal.Data.List (reverse, null)
+import GHC.Internal.List (reverse, null)
import GHC.Internal.Word
import GHC.Internal.Foreign.C.Types
import GHC.Internal.Foreign.C.String (peekCString, CString)
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/Encoding/CodePage.hs
=====================================
@@ -30,7 +30,7 @@ import GHC.Internal.IO.Encoding.Types
import GHC.Internal.IO.Buffer
import GHC.Internal.Data.Bits
import GHC.Internal.Data.Maybe
-import GHC.Internal.Data.OldList (lookup)
+import GHC.Internal.List (lookup)
import qualified GHC.Internal.IO.Encoding.CodePage.API as API
import GHC.Internal.IO.Encoding.CodePage.Table
=====================================
libraries/ghc-internal/src/GHC/Internal/ResponseFile.hs
=====================================
@@ -28,7 +28,7 @@ import GHC.Internal.Control.Exception
import GHC.Internal.Data.Foldable (Foldable(..))
import GHC.Internal.Base
import GHC.Internal.Unicode (isSpace)
-import GHC.Internal.Data.List (filter, unlines, concat, reverse)
+import GHC.Internal.Data.OldList (filter, unlines, concat, reverse)
import GHC.Internal.Text.Show (show)
import GHC.Internal.System.Environment (getArgs)
import GHC.Internal.System.Exit (exitFailure)
=====================================
libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
=====================================
@@ -36,7 +36,7 @@ import GHC.Internal.Num
import GHC.Internal.Data.Bits
import GHC.Internal.Data.Functor
import GHC.Internal.Data.Maybe (catMaybes)
-import GHC.Internal.Data.List
+import GHC.Internal.List
import GHC.Internal.Data.Tuple
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Foreign.Storable
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
=====================================
@@ -40,14 +40,14 @@ module GHC.Internal.System.Environment.Blank
) where
import GHC.Internal.Data.Functor
-import GHC.Internal.Data.List (elem, null, takeWhile)
+import GHC.Internal.List (elem, null, takeWhile)
import GHC.Internal.Foreign.C.String
import GHC.Internal.Base
#if defined(mingw32_HOST_OS)
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Windows
import GHC.Internal.Control.Monad
-import GHC.Internal.Data.List (lookup)
+import GHC.Internal.List (lookup)
#else
import GHC.Internal.Foreign.C.Error
import GHC.Internal.Foreign.C.Types
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Environment/ExecutablePath.hsc
=====================================
@@ -53,7 +53,7 @@ import GHC.Internal.System.IO.Error (isDoesNotExistError)
import GHC.Internal.System.Posix.Internals
#elif defined(linux_HOST_OS) || defined(gnu_HOST_OS)
import GHC.Internal.Data.Functor
-import GHC.Internal.Data.List (isSuffixOf)
+import GHC.Internal.Data.OldList (isSuffixOf)
import GHC.Internal.Foreign.C.Types
import GHC.Internal.Foreign.C.Error
import GHC.Internal.Foreign.C.String
@@ -85,7 +85,7 @@ import GHC.Internal.System.Posix.Internals
import GHC.Internal.Control.Exception
import GHC.Internal.Control.Monad.Fail
import GHC.Internal.Data.Functor
-import GHC.Internal.Data.List (isPrefixOf, drop)
+import GHC.Internal.OldList (isPrefixOf, drop)
import GHC.Internal.Word
import GHC.Internal.Foreign.C.String
import GHC.Internal.Foreign.Marshal.Array
=====================================
libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
=====================================
@@ -70,7 +70,7 @@ import GHC.Internal.Foreign.Storable
import qualified GHC.Internal.Foreign.C.String.Encoding as GHC
#else
import GHC.Internal.Int
-import GHC.Internal.Data.OldList (elem)
+import GHC.Internal.List (elem)
#endif
-- ---------------------------------------------------------------------------
=====================================
libraries/ghc-internal/src/GHC/Internal/Windows.hs
=====================================
@@ -80,7 +80,7 @@ module GHC.Internal.Windows (
import GHC.Internal.Data.Bits (finiteBitSize, shiftL, shiftR, (.|.), (.&.))
import GHC.Internal.Unicode (isSpace)
-import GHC.Internal.Data.OldList
+import GHC.Internal.List
import GHC.Internal.Data.Maybe
import GHC.Internal.Word
import GHC.Internal.Int
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/966bd642640e2ccd17bbe43f2f5145…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/966bd642640e2ccd17bbe43f2f5145…
You're receiving this email because of your account on gitlab.haskell.org.
1
0