ghc-internal 9.1001.0 → 9.1002.0
raw patch · 41 files changed
+385/−131 lines, 41 filesdep ~ghc-primnew-uploaderPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: ghc-prim
API changes (from Hackage documentation)
+ GHC.Internal.System.Posix.Internals: statGetType_maybe :: Ptr CStat -> IO (Maybe IODeviceType)
- GHC.Internal.Control.Exception: throw :: forall a e. (?callStack :: CallStack, Exception e) => e -> a
+ GHC.Internal.Control.Exception: throw :: forall a e. (HasCallStack, Exception e) => e -> a
- GHC.Internal.Control.Exception.Base: throw :: forall a e. (?callStack :: CallStack, Exception e) => e -> a
+ GHC.Internal.Control.Exception.Base: throw :: forall a e. (HasCallStack, Exception e) => e -> a
- GHC.Internal.Exception: throw :: forall a e. (?callStack :: CallStack, Exception e) => e -> a
+ GHC.Internal.Exception: throw :: forall a e. (HasCallStack, Exception e) => e -> a
Files
- CHANGELOG.md +2/−2
- ghc-internal.cabal +6/−5
- jsbits/base.js +10/−1
- jsbits/platform.js +29/−11
- src/GHC/Internal/Base.hs +115/−33
- src/GHC/Internal/ByteOrder.hs-boot +1/−0
- src/GHC/Internal/Conc/Sync.hs +3/−3
- src/GHC/Internal/ConsoleHandler.hsc +2/−1
- src/GHC/Internal/Constants.hs +0/−10
- src/GHC/Internal/Data/Coerce.hs +0/−4
- src/GHC/Internal/Data/Tuple.hs +0/−1
- src/GHC/Internal/Data/Version.hs-boot +9/−1
- src/GHC/Internal/Enum.hs-boot +3/−2
- src/GHC/Internal/Event/KQueue.hsc +12/−5
- src/GHC/Internal/Exception.hs +85/−8
- src/GHC/Internal/Exception/Backtrace.hs +1/−1
- src/GHC/Internal/Exception/Context.hs-boot +3/−0
- src/GHC/Internal/Exception/Type.hs-boot +2/−1
- src/GHC/Internal/Exts.hs +34/−2
- src/GHC/Internal/Float/RealFracMethods.hs +2/−1
- src/GHC/Internal/Foreign/C/Types.hs +1/−1
- src/GHC/Internal/IO.hs +1/−1
- src/GHC/Internal/IO/Encoding/CodePage.hs +4/−1
- src/GHC/Internal/IO/Encoding/Iconv.hs +4/−1
- src/GHC/Internal/IO/FD.hs +10/−4
- src/GHC/Internal/IO/Handle/Lock/Flock.hsc +2/−1
- src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc +2/−1
- src/GHC/Internal/IO/Handle/Lock/Windows.hsc +2/−1
- src/GHC/Internal/IO/Handle/Types.hs-boot +1/−1
- src/GHC/Internal/InfoProv/Types.hsc +8/−6
- src/GHC/Internal/JS/Prim/Internal/Build.hs +2/−1
- src/GHC/Internal/Maybe.hs +2/−2
- src/GHC/Internal/Num.hs-boot +0/−1
- src/GHC/Internal/Read.hs +1/−1
- src/GHC/Internal/Real.hs +3/−3
- src/GHC/Internal/Real.hs-boot +0/−1
- src/GHC/Internal/Records.hs +2/−3
- src/GHC/Internal/Stack/Types.hs +1/−3
- src/GHC/Internal/System/Posix/Internals.hs +18/−5
- src/GHC/Internal/TypeError.hs +0/−1
- src/GHC/Internal/Wasm/Prim/Conc/Internal.hs +2/−0
CHANGELOG.md view
@@ -1,5 +1,5 @@ # Revision history for `ghc-internal` -## 0.1.0.0 -- YYYY-mm-dd+## 9.1001.0 -- 2024-05-01 -* First version. Released on an unsuspecting world.+* Package created containing implementation moved from `base`.
ghc-internal.cabal view
@@ -1,8 +1,10 @@ cabal-version: 3.0+-- WARNING: ghc-internal.cabal is automatically generated from ghc-internal.cabal.in by+-- the top-level ./configure script. Make sure you are editing ghc-internal.cabal.in, not ghc-internal.cabal. name: ghc-internal-version: 9.1001.0--- NOTE: Don't forget to update ./changelog.md-+-- The project is ghc's version plus ghc-internal's version suffix.+-- For example, for ghc=9.10.1, ghc-internal's version will be 9.1001.0.+version: 9.1002.0 license: BSD-3-Clause license-file: LICENSE maintainer: Core Libraries Committee <core-libraries-committee@haskell.org>@@ -87,7 +89,7 @@ build-depends: rts == 1.0.*,- ghc-prim >= 0.11 && < 0.12,+ ghc-prim >= 0.11 && < 0.13, ghc-bignum >= 1.0 && < 2.0 exposed-modules:@@ -172,7 +174,6 @@ GHC.Internal.Conc.Signal GHC.Internal.Conc.Sync GHC.Internal.ConsoleHandler- GHC.Internal.Constants GHC.Internal.Desugar GHC.Internal.Encoding.UTF8 GHC.Internal.Enum
jsbits/base.js view
@@ -912,7 +912,7 @@ } } else if(h$isJsCore()) { h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) {- c(0);+ c(0); } var h$base_stdoutLeftover = { f: print, val: null }; var h$base_stderrLeftover = { f: debug, val: null };@@ -1077,3 +1077,12 @@ } return 0; }++// It is required by Google Closure Compiler to be at least defined if+// somewhere it is used+var h$stg_cloneMyStackzh, h$stg_decodeStackzh+h$stg_cloneMyStackzh+ = h$stg_decodeStackzh+ = function () {+ throw new Error('Stack Cloning Decoding: Not Implemented Yet')+ }
jsbits/platform.js view
@@ -46,18 +46,36 @@ } // load all required node.js modules-if(typeof process !== 'undefined' && (typeof h$TH !== 'undefined' || (typeof require !== 'undefined' && typeof module !== 'undefined' && module.exports))) {+if(typeof global !== 'undefined' && typeof process !== 'undefined' && (typeof h$TH !== 'undefined' || (typeof require !== 'undefined' && typeof module !== 'undefined' && module.exports))) { h$isNode_ = true;- // we have to use these names for the closure compiler externs to work- var fs = require('fs');- var path = require('path');- var os = require('os');- var child_process = require('child_process');- var h$fs = fs;- var h$path = path;- var h$os = os;- var h$child = child_process;+ // we have to put fs var into closure to prevent name clashes with emscripten compiler code injections+ // we use additional suffix to have more guarantees over possible clashes+ // we should use amd/commonjs module wrappers to avoid such ugly things+ global.h$nodeOS_modules_qvsKGchAmE = (function() {+ var fs = require('fs');+ var path = require('path');+ var os = require('os');+ var child_process = require('child_process');+ return {+ 'fs' : fs,+ 'path': path,+ 'os': os,+ 'child_process': child_process+ };+ })();+ // we dictionary-like access strictly prevents+ // google closure compiler names mangling+ var h$fs = global.h$nodeOS_modules_qvsKGchAmE['fs'];+ var h$path = global.h$nodeOS_modules_qvsKGchAmE['path'];+ var h$os = global.h$nodeOS_modules_qvsKGchAmE['os'];+ var h$child = global.h$nodeOS_modules_qvsKGchAmE['child_process'];++ // we forcibly delete temporary lexical environment variable+ // to prevent any clashes+ delete global.h$nodeOS_modules_qvsKGchAmE;+ var h$process = process;+ function h$getProcessConstants() { // this is a non-public API, but we need these values for things like file access modes var cs = process['binding']('constants');@@ -76,7 +94,7 @@ } } var h$processConstants = h$getProcessConstants();-} else if(typeof Java !== 'undefined') {+} else if(typeof Java !== 'undefined' && typeof java !== 'undefined') { h$isJvm_ = true; this.console = { log: function(s) {
src/GHC/Internal/Base.hs view
@@ -326,8 +326,7 @@ import GHC.Internal.Maybe import {-# SOURCE #-} GHC.Internal.IO (mkUserError, mplusIO) -import GHC.Tuple (Solo (MkSolo)) -- Note [Depend on GHC.Tuple]-import GHC.Num.Integer () -- Note [Depend on GHC.Num.Integer]+import GHC.Tuple (Solo (MkSolo)) -- See Note [Semigroup stimes cycle] import {-# SOURCE #-} GHC.Internal.Num (Num (..))@@ -348,38 +347,120 @@ default () -- Double isn't available yet {--Note [Depend on GHC.Num.Integer]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-The Integer type is special because GHC.CoreToStg.Prep.mkConvertNumLiteral-lookups names in ghc-bignum interfaces to construct Integer literal values.-Currently it reads the interface file whether or not the current module *has*-any Integer literals, so it's important that GHC.Num.Integer is compiled before-any other module.+Note [Tracking dependencies on primitives]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+When desugaring certain program constructs, GHC will insert references+to the primitives used to implement those constructs even if those+primitives have not actually been imported. For example, the function+``fst (x,_) = x`` will be desugared using references to the 2-tuple+data constructor, which lives in GHC.Tuple. -The danger is that if the build system doesn't know about the implicit-dependency on Integer, it'll compile some base module before GHC.Num.Integer,-resulting in:- Failed to load interface for ‘GHC.Num.Integer’- There are files missing in the ‘ghc-bignum’ package,+When bootstrapping GHC, it is important that we do not attempt to+compile any such reference to GHC.Tuple before GHC.Tuple itself has+been built, otherwise compilation will fail with an error like this one:+ Failed to load interface for ‘GHC.Tuple’.+ There are files missing in the ‘ghc-prim-0.10.0’ package,+ try running 'ghc-pkg check'.+ Use -v to see a list of the files searched for. -To ensure that GHC.Num.Integer is there, we must ensure that there is a visible-dependency on GHC.Num.Integer from every module in base. We make GHC.Internal.Base-depend on GHC.Num.Integer; and everything else either depends on GHC.Base,-directly on GHC.Num.Integer, or does not have NoImplicitPrelude (and hence-depends on Prelude).+To prevent such errors, we insist that if any boot library module X+implicitly depends on primitives in module Y, then the transitive+imports of X must include Y. -The lookup is only disabled for packages ghc-prim and ghc-bignum, which aren't-allowed to contain any Integer literal.+Such implicit dependencies can be introduced in at least the following ways: +W1:+ Common awkward dependencies:+ * TypeRep metadata introduces references to GHC.Types in EVERY module.+ * A String literal introduces a reference to GHC.CString, for either+ unpackCString# or unpackCStringUtf8# depending on its contents.+ * Tuple-notation introduces references to GHC.Tuple.+ * Constraint tuples introduce references to GHC.Classes.+ * Short lists like [3,8,2] produce references to GHC.Internal.Base.build -Note [Depend on GHC.Tuple]-~~~~~~~~~~~~~~~~~~~~~~~~~~-Similarly, tuple syntax (or ()) creates an implicit dependency on-GHC.Tuple, so we use the same rule as for Integer --- see Note [Depend on-GHC.Num.Integer] --- to explain this to the build system. We make GHC.Internal.Base-depend on GHC.Tuple, and everything else depends on GHC.Internal.Base or Prelude.+ A module can transitively depend on all of these by importing any of+ GHC.Internal.Base, GHC.Base, or Prelude. The latter in particular+ means that an explicit import for this reason is only necessary when+ ImplicitPrelude is disabled, so this primarily comes up in the+ dependencies of base and in the compiler itself. + * Most modules in ghc-internal import GHC.Internal.Base.+ * Most modules in compiler/ import GHC.Prelude, which imports Prelude.+ * Most hs-boot files that would otherwise have no imports can get+ away with just importing GHC.Types. + Unfortunately, the requirement to transitively import these modules+ when they are implicitly used is obscure and causes only /intermittent/+ build failures, so enforcement of that requirement has historically+ been pretty spotty, causing issues like #23942.++ Improving this situation is discussed at #24520.++W2:+ Non-exhaustive pattern matches, incomplete record selectors,+ missing record fields, and missing class instance methods all+ introduce references to GHC.Internal.Control.Exception.Base.++ These constructs are therefore not allowed in ghc-prim or ghc-bignum.+ But since they generally have bad code smell and are avoided by+ developers anyway, this restriction has not been very burdensome.++W3:+ Various "overloaded" bits of syntax:+ * Overloaded integer literals introduce references to GHC.Internal.Num.+ * Likewise overloaded fractional literals to GHC.Internal.Real+ * Likewise overloaded string literals to GHC.Internal.Data.String+ * Likewise overloaded list literals to GHC.Internal.IsList+ * Overloaded labels introduce references to GHC.Internal.OverloadedLabels+ * Uses of OverloadedRecordDot introduce references to GHC.Internal.Records.+ * Do-notation introduces references to GHC.Internal.Base for Monad stuff.+ * Likewise arrow-notation to GHC.Internal.Control.Arrow+ * Likewise RecursiveDo stuff to GHC.Internal.Control.Monad.Fix+ * (Does TemplateHaskellQuotes fall into this category as well?)++ These are not problematic in practice. For example, a program+ that uses arrow-notation but does not otherwise import the Arrow+ type class will almost certainly fail to type-check anyway.+ (The "Arrow m" constraint will be very hard to solve!)++W4:+ Stock derived instances introduce references to various things.+ Derived Eq instances can reference GHC.Magic.dataToTag#, for example.+ But since any module containing a derived Eq instance must import Eq,+ as long as the module which defines Eq imports GHC.Magic this cannot+ cause trouble.++ Embarrassingly, we do not follow this plan for the Lift class.+ Derived Lift instances refer to machinery in Language.Haskell.TH.Lib,+ which is not imported by the module Language.Haskell.TH.Syntax that+ defines the Lift class. This is still causing annoyance for boot+ library maintainers as of March 2024: See #22229.++W5:+ If no explicit "default" declaration is present, the assumed+ "default (Integer, Double)" creates a dependency on GHC.Num.Integer+ for the Integer type if defaulting is ever attempted during+ type-checking. (This doesn't apply to hs-boot files, which can't+ be given "default" declarations anyway.)++W6:+ In the wasm backend, JSFFI imports and exports pull in a bunch of stuff;+ see Note [Desugaring JSFFI static export] and Note [Desugaring JSFFI import]+ in GHC.HsToCore.Foreign.Wasm.++A complete list could probably be made by going through the known-key+names in GHC.Builtin.Names and GHC.Builtin.Names.TH. To test whether+the transitive imports are sufficient for any single module, instruct+the build system to build /only/ that module in stage 2. For example,+a command to check whether the transitive imports for GHC.Internal.Maybe+are sufficient is:++ hadrian/build -o_checkDeps _checkDeps/stage1/libraries/ghc-internal/build/GHC/Internal/Maybe.o++Use the ".o-boot" suffix instead of ".o" to check an hs-boot file's+transitive imports.++ Note [Semigroup stimes cycle] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Semigroup is defined in this module, GHC.Base, with the method@@ -388,12 +469,13 @@ This presents a problem. * We use Integral methods (quot, rem) and Num methods (-) in stimes definitions in this module. Num is a superclass of Integral.-* Num is defined in GHC.Num, which imports GHC.Base.-* Enum is defined in GHC.Enum, which imports GHC.Internal.Base and GHC.Num. Enum is a- superclass of Integral. We don't use any Enum methods here, but it is relevant+* Num is defined in GHC.Internal.Num, which imports GHC.Internal.Base.+* Enum is defined in GHC.Internal.Enum, which imports+ GHC.Internal.Base and GHC.Internal.Num. Enum is a superclass of+ Integral. We don't use any Enum methods here, but it is relevant (read on).-* Integral is defined in GHC.Real, which imports GHC.Base, GHC.Num, and- GHC.Enum.+* Integral is defined in GHC.Internal.Real, which imports+ GHC.Internal.Base, GHC.Internal.Num, and GHC.Internal.Enum. We resolve this web of dependencies with hs-boot files. The rules https://ghc.gitlab.haskell.org/ghc/doc/users_guide/separate_compilation.html#how-to-compile-mutually-recursive-modules@@ -2268,7 +2350,7 @@ getTag = dataToTag# ------------------------------------------------- GHC.Internal.Numeric primops+-- Numeric primops ---------------------------------------------- -- Definitions of the boxed PrimOps; these will be
src/GHC/Internal/ByteOrder.hs-boot view
@@ -19,6 +19,7 @@ module GHC.Internal.ByteOrder where +-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base import GHC.Types () data ByteOrder
src/GHC/Internal/Conc/Sync.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RankNTypes #-}@@ -394,13 +393,14 @@ getNumProcessors = fmap fromIntegral c_getNumberOfProcessors foreign import ccall unsafe "getNumberOfProcessors"- c_getNumberOfProcessors :: IO CUInt+ c_getNumberOfProcessors :: IO Word32 -- | Returns the number of sparks currently in the local spark pool numSparks :: IO Int numSparks = IO $ \s -> case numSparks# s of (# s', n #) -> (# s', I# n #) -foreign import ccall "&enabled_capabilities" enabled_capabilities :: Ptr CInt+foreign import ccall "&enabled_capabilities"+ enabled_capabilities :: Ptr Word32 childHandler :: SomeException -> IO () childHandler err = catch (real_handler err) childHandler
src/GHC/Internal/ConsoleHandler.hsc view
@@ -22,7 +22,8 @@ #if !defined(mingw32_HOST_OS) where -import GHC.Internal.Base () -- dummy dependency+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () #else /* whole file */ ( Handler(..) , installHandler
− src/GHC/Internal/Constants.hs
@@ -1,10 +0,0 @@-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE NoImplicitPrelude #-}--module GHC.Internal.Constants where---- TODO: This used to include HaskellConstants.hs, but that has now gone.--- We probably want to include the constants in platformConstants somehow--- instead.--import GHC.Internal.Base () -- dummy dependency
src/GHC/Internal/Data/Coerce.hs view
@@ -26,7 +26,3 @@ ) where import GHC.Prim (coerce) import GHC.Types (Coercible)---- The import of GHC.Internal.Base is for build ordering; see Notes in GHC.Internal.Base for--- more info.-import GHC.Internal.Base ()
src/GHC/Internal/Data/Tuple.hs view
@@ -25,7 +25,6 @@ , swap ) where -import GHC.Internal.Base () -- Note [Depend on GHC.Tuple] import GHC.Tuple (Solo (..), getSolo) default () -- Double isn't available yet
src/GHC/Internal/Data/Version.hs-boot view
@@ -5,7 +5,15 @@ , makeVersion ) where -import GHC.Internal.Base+import GHC.Types+++-- The generated module GHC.Internal.Unicode.Version depends on+-- GHC.Internal.Base.build via built-in list syntax, and its only+-- import is this hs-boot file, so until someone fixes the generator,+-- this import has to stay here to ensure sound build ordering. See also+-- W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base.+import GHC.Internal.Base () data Version
src/GHC/Internal/Enum.hs-boot view
@@ -1,10 +1,11 @@ {-# LANGUAGE NoImplicitPrelude #-} -module GHC.Internal.Enum (Enum) where- -- For why this file exists -- See Note [Semigroup stimes cycle] in GHC.Internal.Base +module GHC.Internal.Enum (Enum) where++-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base import GHC.Types () class Enum a
src/GHC/Internal/Event/KQueue.hsc view
@@ -44,8 +44,8 @@ import GHC.Internal.Real (quotRem, fromIntegral) import GHC.Internal.Show (Show(show)) import GHC.Internal.Event.Internal (Timeout(..))-import GHC.Internal.System.Posix.Internals (c_close)-import GHC.Internal.System.Posix.Types (Fd(..))+import GHC.Internal.System.Posix.Internals (c_close,c_getpid)+import GHC.Internal.System.Posix.Types (Fd(..), CPid) import qualified GHC.Internal.Event.Array as A #if defined(netbsd_HOST_OS)@@ -73,19 +73,26 @@ data KQueue = KQueue { kqueueFd :: {-# UNPACK #-} !KQueueFd , kqueueEvents :: {-# UNPACK #-} !(A.Array Event)+ , kqueuePid :: {-# UNPACK #-} !CPid -- ^ pid, used to detect forks } new :: IO E.Backend new = do kqfd <- kqueue events <- A.new 64- let !be = E.backend poll modifyFd modifyFdOnce delete (KQueue kqfd events)+ pid <- c_getpid+ let !be = E.backend poll modifyFd modifyFdOnce delete (KQueue kqfd events pid) return be delete :: KQueue -> IO () delete kq = do- _ <- c_close . fromKQueueFd . kqueueFd $ kq- return ()+ -- detect forks: the queue isn't inherited by a child process created with+ -- fork. Hence we mustn't try to close the old fd or we might close a random+ -- one (e.g. the one used by timerfd, cf #24672).+ pid <- c_getpid+ when (pid == kqueuePid kq) $ do+ _ <- c_close . fromKQueueFd . kqueueFd $ kq+ return () modifyFd :: KQueue -> Fd -> E.Event -> E.Event -> IO Bool modifyFd kq fd oevt nevt = do
src/GHC/Internal/Exception.hs view
@@ -79,11 +79,88 @@ -- WARNING: You may want to use 'throwIO' instead so that your pure code -- stays exception-free. throw :: forall (r :: RuntimeRep). forall (a :: TYPE r). forall e.- (?callStack :: CallStack, Exception e) => e -> a+ (HasCallStack, Exception e) => e -> a throw e =- let !se = unsafePerformIO (toExceptionWithBacktrace e)+ -- Note the absolutely crucial bang "!" on this binding!+ -- See Note [Capturing the backtrace in throw]+ -- Note also the absolutely crucial `noinine` in the RHS!+ -- See Note [Hiding precise exception signature in throw]+ let se :: SomeException+ !se = noinline (unsafePerformIO (toExceptionWithBacktrace e)) in raise# se +-- Note [Capturing the backtrace in throw]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- When `throw` captures a backtrace, it must be the backtrace *at the moment+-- that `throw` is called*. That is why the binding of `se` is marked strict,+-- via the `!`:+--+-- !se = <rhs>+--+-- GHC can capture /four/ different sorts of backtraces (See Note [Backtrace+-- mechanisms] in "Control.Exception.Backtrace" for details). One of them+-- (`CallStack` constraints) does not need this strict-binding treatment,+-- because the `CallStack` constraint is captured in the thunk. However, the+-- other two (DWARF stack unwinding, and native Haskell stack unwinding) are+-- much more fragile, and can only be captured right at the call of `throw`.+--+-- However, making `se` strict has downsides: see+-- Note [Hiding precise exception signature in throw] below.+--+--+-- Note [Hiding precise exception signature in throw]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+-- In 'throw' we use `unsafePerformIO . toExceptionWithBacktrace' to collect+-- the backtraces which will be attached as the exception's 'ExceptionContext'.+-- We must ensure that this is evaluated immediately in `throw` since+-- `toExceptionWithBacktrace` must capture the execution state at the moment+-- that the exception is thrown (see Note [Capturing the backtrace in throw]).+-- Unfortunately, unless we take particular care this can lead to a+-- catastrophic regression in 'throw's demand signature which will infect+-- all callers (#25066)+--+-- Specifically, GHC's demand analysis has an approximate heuristic for tracking+-- whether divergent functions diverge with precise or imprecise exceptions (namely+-- the 'ExnOrDiv' and 'Diverges' constructors of 'GHC.Types.Demand.Divergence',+-- respectively). This is because we can take considerably more liberties in+-- optimising around functions which are known not to diverge via precise+-- exception (see Note [Precise exceptions and strictness analysis]).+-- For this reason, it is important that 'throw' have a 'Diverges' divergence+-- type.+--+-- Unfortunately, this is broken if we allow `unsafePerformIO` to inline. Specifically,+-- if we allow this inlining we will end up with Core of the form:+--+-- throw = \e ->+-- case runRW# (\s -> ... toExceptionWithBacktrace e s ...) of+-- se -> raise# se+--+-- so far this is fine; the demand analyzer's divergence heuristic+-- will give 'throw' the expected 'Diverges' divergence.+--+-- However, the simplifier will subsequently notice that `raise#` can be fruitfully+-- floated into the body of the `runRW#`:+--+-- throw = \e ->+-- runRW# (\s -> case toExceptionWithBacktrace e s of+-- (# s', se #) -> raise# se)+--+-- This is problematic as one of the demand analyser's heuristics examines+-- `case` scrutinees, looking for those that result in a `RealWorld#` token+-- (see Note [Which scrutinees may throw precise exceptions], test (1)). The+-- `case toExceptionWithBacktrace e of ...` here fails this check, causing the+-- heuristic to conclude that `throw` may indeed diverge with a precise+-- exception. This resulted in the significant performance regression noted in+-- #25066.+--+-- To avoid this, we use `noinline` to ensure that `unsafePerformIO` does not unfold,+-- meaning that the `raise#` cannot be floated under the `toExceptionWithBacktrace`+-- case analysis.+--+-- Ultimately this is a bit of a horrible hack; the right solution would be to have+-- primops which allow more precise guidance of the demand analyser's heuristic+-- (e.g. #23847).+ -- | @since base-4.20.0.0 toExceptionWithBacktrace :: (HasCallStack, Exception e) => e -> IO SomeException@@ -120,12 +197,12 @@ errorCallWithCallStackException :: String -> CallStack -> SomeException errorCallWithCallStackException s stk = unsafeDupablePerformIO $ do- ccsStack <- currentCallStack- let- implicitParamCallStack = prettyCallStackLines stk- ccsCallStack = showCCSStack ccsStack- stack = intercalate "\n" $ implicitParamCallStack ++ ccsCallStack- toExceptionWithBacktrace (ErrorCallWithLocation s stack)+ ccsStack <- currentCallStack+ let implicitParamCallStack = prettyCallStackLines stk+ ccsCallStack = showCCSStack ccsStack+ stack = intercalate "\n" $ implicitParamCallStack ++ ccsCallStack+ toExceptionWithBacktrace (ErrorCallWithLocation s stack)+ where ?callStack = stk showCCSStack :: [String] -> [String] showCCSStack [] = []
src/GHC/Internal/Exception/Backtrace.hs view
@@ -33,7 +33,7 @@ = CostCentreBacktrace -- | collect 'HasCallStack' backtraces | HasCallStackBacktrace- -- | collect backtraces from native execution stack unwinding+ -- | collect backtraces via native execution stack unwinding (e.g. using DWARF debug information) | ExecutionBacktrace -- | collect backtraces from Info Table Provenance Entries | IPEBacktrace
src/GHC/Internal/Exception/Context.hs-boot view
@@ -2,5 +2,8 @@ module GHC.Internal.Exception.Context where +-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types ()+ data ExceptionContext
src/GHC/Internal/Exception/Type.hs-boot view
@@ -9,7 +9,8 @@ , underflowException ) where -import GHC.Num.Integer () -- See Note [Depend on GHC.Num.Integer] in GHC.Internal.Base+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () data SomeException divZeroException, overflowException,
src/GHC/Internal/Exts.hs view
@@ -18,10 +18,42 @@ -- Stability : internal -- Portability : non-portable (GHC Extensions) ----- GHC Extensions: this is the Approved Way to get at GHC-specific extensions.+-- GHC Extensions: This is a unstable way to get at GHC-specific extensions.+-- If possible prefer using GHC.PrimOps from ghc-experimental+-- or GHC.Exts from base. ----- Note: no other base module should import this module.+-- Note: no other ghc-internal module should import this module. -----------------------------------------------------------------------------++{- Note [Where do we export PrimOps]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Built in primops are automatically exported via the magical module+GHC.Prim (See Note [GHC.Prim]).+However we don't want users to use GHC.Prim directly. Among other reasons that+would prevent us from giving those primops a regular haskell or cmm+implementation in the future.++So instead we provide a hirarchy of Modules through which we expose PrimOps.+* ghc-internal:GHC.Exts.Internal re-exports GHC.Prim along with some other+ builtin functionality. It gives zero stability guarantee and is mostly inteded+ for ghc internal use.+* ghc-experimental:GHC.PrimOps contains a more stable subset of GHC.Exts.Internal.+ This module does not offer any more stability *guarantees* than ghc-internal,+ but we try to keep things slightly more stable there and be backwards compatible+ if it's easy to do. For example an export from ghc-experimental is likely to get+ deprecated before being removed. While exports from ghc-internal could be removed+ without advanced notice between ghc versions!+* base:GHC.Exts: Contains all kinds of re-exports from ghc-internal:GHC.Exts.Internal+ which have been grandfathered into this module from pre ghc-9.10.+ Starting with 9.10.1 only definitions with a fairly high level of expected+ stability should be exposed through GHC.Exts and changing the API provided by+ this module now follows the CLC process.++If there is a desire to create a module for a specific group of primitives they+should still be exported by the catch-all modules GHC.Exts.Internal and GHC.PrimOps,+with their specific module being placed under ghc-experimental:GHC.PrimOps+in the module structure.+-} module GHC.Internal.Exts (
src/GHC/Internal/Float/RealFracMethods.hs view
@@ -62,7 +62,8 @@ import GHC.Num.Integer import GHC.Internal.Base hiding (uncheckedIShiftRA64#, uncheckedIShiftL64#)-import GHC.Internal.Num ()+import GHC.Internal.Num () -- instance Num Integer+ -- (We could remove uses with a little effort) #if WORD_SIZE_IN_BITS < 64
src/GHC/Internal/Foreign/C/Types.hs view
@@ -47,7 +47,7 @@ , CLLong(..), CULLong(..), CBool(..) , CIntPtr(..), CUIntPtr(..), CIntMax(..), CUIntMax(..) - -- ** GHC.Internal.Numeric types+ -- ** Numeric types -- | These types are represented as @newtype@s of basic -- foreign types, and are instances of -- 'Prelude.Eq', 'Prelude.Ord', 'Prelude.Num', 'Prelude.Read',
src/GHC/Internal/IO.hs view
@@ -210,7 +210,7 @@ -- | Execute an 'IO' action, adding the given 'ExceptionContext' -- to any thrown synchronous exceptions. ----- @since base-2.20.0.0+-- @since base-4.20.0.0 annotateIO :: forall e a. ExceptionAnnotation e => e -> IO a -> IO a annotateIO ann (IO io) = IO (catch# io handler) where
src/GHC/Internal/IO/Encoding/CodePage.hs view
@@ -14,7 +14,10 @@ ) where #if !defined(mingw32_HOST_OS)-import GHC.Internal.Base () -- Build ordering++-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types ()+ #else import GHC.Internal.Base import GHC.Internal.Show
src/GHC/Internal/IO/Encoding/Iconv.hs view
@@ -32,7 +32,10 @@ #include "HsBaseConfig.h" #if defined(mingw32_HOST_OS)-import GHC.Internal.Base () -- For build ordering++-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types ()+ #else import GHC.Internal.Foreign.C.Types
src/GHC/Internal/IO/FD.hs view
@@ -57,6 +57,7 @@ import GHC.Internal.Foreign.C.Types import GHC.Internal.Foreign.C.Error import GHC.Internal.Foreign.Marshal.Utils+import GHC.Internal.Foreign.Marshal.Alloc (allocaBytes) import qualified GHC.Internal.System.Posix.Internals import GHC.Internal.System.Posix.Internals hiding (FD, setEcho, getEcho)@@ -476,10 +477,15 @@ -- O_NONBLOCK has no effect on regular files and block devices; -- utilities inspecting fdIsNonBlocking (such as readRawBufferPtr) -- should not be tricked to think otherwise.- is_nonblock <- if set then do- (fd_type, _, _) <- fdStat (fdFD fd)- pure $ fd_type /= RegularFile && fd_type /= RawDevice- else pure False+ is_nonblock <-+ if set+ then do+ allocaBytes sizeof_stat $ \ p_stat -> do+ throwErrnoIfMinus1Retry_ "fileSize" $+ c_fstat (fdFD fd) p_stat+ fd_type <- statGetType_maybe p_stat+ pure $ fd_type /= Just RegularFile && fd_type /= Just RawDevice+ else pure False setNonBlockingFD (fdFD fd) is_nonblock #if defined(mingw32_HOST_OS) return fd
src/GHC/Internal/IO/Handle/Lock/Flock.hsc view
@@ -10,7 +10,8 @@ #include "HsBaseConfig.h" #if !HAVE_FLOCK-import GHC.Internal.Base () -- Make implicit dependency known to build system+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () #else #include <sys/file.h>
src/GHC/Internal/IO/Handle/Lock/LinuxOFD.hsc view
@@ -10,7 +10,8 @@ #include "HsBaseConfig.h" #if !HAVE_OFD_LOCKING-import GHC.Internal.Base () -- Make implicit dependency known to build system+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () #else -- Not only is this a good idea but it also works around #17950.
src/GHC/Internal/IO/Handle/Lock/Windows.hsc view
@@ -10,7 +10,8 @@ #include "HsBaseConfig.h" #if !defined(mingw32_HOST_OS)-import GHC.Internal.Base () -- Make implicit dependency known to build system+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () #else ##include <windows_cconv.h>
src/GHC/Internal/IO/Handle/Types.hs-boot view
@@ -2,7 +2,7 @@ module GHC.Internal.IO.Handle.Types ( Handle ) where --- See Note [Depend on GHC.Num.Integer] in GHC.Internal.Base+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base import GHC.Types () data Handle
src/GHC/Internal/InfoProv/Types.hsc view
@@ -18,8 +18,9 @@ ) where import GHC.Internal.Base-import GHC.Internal.Data.Maybe import GHC.Internal.Enum+import GHC.Internal.Real (fromIntegral)+import GHC.Internal.Word (Word32) import GHC.Internal.Show (Show) import GHC.Internal.Ptr (Ptr(..), plusPtr) import GHC.Internal.Foreign.C.String.Encoding (CString, peekCString)@@ -28,7 +29,6 @@ import GHC.Internal.IO.Encoding (utf8) import GHC.Internal.Foreign.Storable (peekByteOff) import GHC.Internal.ClosureTypes-import GHC.Internal.Text.Read import GHC.Prim (whereFrom##) data InfoProv = InfoProv {@@ -70,9 +70,11 @@ ipeProv :: Ptr InfoProvEnt -> Ptr InfoProv ipeProv p = (#ptr InfoProvEnt, prov) p -peekIpName, peekIpDesc, peekIpLabel, peekIpUnitId, peekIpModule, peekIpSrcFile, peekIpSrcSpan, peekIpTyDesc :: Ptr InfoProv -> IO CString-peekIpName p = (# peek InfoProv, table_name) p+peekIpDesc :: Ptr InfoProv -> IO Word32 peekIpDesc p = (# peek InfoProv, closure_desc) p++peekIpName, peekIpLabel, peekIpUnitId, peekIpModule, peekIpSrcFile, peekIpSrcSpan, peekIpTyDesc :: Ptr InfoProv -> IO CString+peekIpName p = (# peek InfoProv, table_name) p peekIpLabel p = (# peek InfoProv, label) p peekIpUnitId p = (# peek InfoProv, unit_id) p peekIpModule p = (# peek InfoProv, module) p@@ -83,7 +85,7 @@ peekInfoProv :: Ptr InfoProv -> IO InfoProv peekInfoProv infop = do name <- peekCString utf8 =<< peekIpName infop- desc <- peekCString utf8 =<< peekIpDesc infop+ desc <- peekIpDesc infop tyDesc <- peekCString utf8 =<< peekIpTyDesc infop label <- peekCString utf8 =<< peekIpLabel infop unit_id <- peekCString utf8 =<< peekIpUnitId infop@@ -94,7 +96,7 @@ ipName = name, -- The INVALID_OBJECT case should be impossible as we -- control the C code generating these values.- ipDesc = maybe INVALID_OBJECT toEnum . readMaybe @Int $ desc,+ ipDesc = toEnum $ fromIntegral desc, ipTyDesc = tyDesc, ipLabel = label, ipUnitId = unit_id,
src/GHC/Internal/JS/Prim/Internal/Build.hs view
@@ -4,7 +4,8 @@ #if !defined(javascript_HOST_ARCH) module GHC.Internal.JS.Prim.Internal.Build () where -import GHC.Internal.Base () -- for build ordering+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () #else {-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI, GHCForeignImportPrim #-}
src/GHC/Internal/Maybe.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE NoImplicitPrelude, StandaloneDeriving #-} {-# OPTIONS_HADDOCK not-home #-} -- | Maybe type@@ -7,7 +7,7 @@ ) where -import GHC.Num.Integer () -- See Note [Depend on GHC.Num.Integer] in GHC.Internal.Base+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base import GHC.Classes default ()
src/GHC/Internal/Num.hs-boot view
@@ -6,7 +6,6 @@ -- See Note [Semigroup stimes cycle] in GHC.Internal.Base import GHC.Num.Integer (Integer)-import GHC.Types () infixl 7 * infixl 6 +, -
src/GHC/Internal/Read.hs view
@@ -551,7 +551,7 @@ readList = readListDefault ----------------------------------------------------------------- GHC.Internal.Numeric instances of Read+-- Numeric instances of Read -------------------------------------------------------------- readNumber :: Num a => (L.Lexeme -> ReadPrec a) -> ReadPrec a
src/GHC/Internal/Real.hs view
@@ -360,7 +360,7 @@ {-# INLINE numericEnumFrom #-} -- See Note [Inline Enum method helpers] in GHC.Internal.Enum numericEnumFrom n = go 0 where- -- See Note [GHC.Internal.Numeric Stability of Enumerating Floating Numbers]+ -- See Note [Numeric Stability of Enumerating Floating Numbers] go !k = let !n' = n + k in n' : go (k + 1) @@ -369,7 +369,7 @@ numericEnumFromThen n m = go 0 where step = m - n- -- See Note [GHC.Internal.Numeric Stability of Enumerating Floating Numbers]+ -- See Note [Numeric Stability of Enumerating Floating Numbers] go !k = let !n' = n + k * step in n' : go (k + 1) @@ -386,7 +386,7 @@ !predicate | e2 >= e1 = (<= e3 + mid) | otherwise = (>= e3 + mid) -{- Note [GHC.Internal.Numeric Stability of Enumerating Floating Numbers]+{- Note [Numeric Stability of Enumerating Floating Numbers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When enumerate floating numbers, we could add the increment to the last number at every run (as what we did previously):
src/GHC/Internal/Real.hs-boot view
@@ -7,7 +7,6 @@ import GHC.Classes (Ord) import GHC.Num.Integer (Integer)-import GHC.Types () import {-# SOURCE #-} GHC.Internal.Num (Num) import {-# SOURCE #-} GHC.Internal.Enum (Enum)
src/GHC/Internal/Records.hs view
@@ -25,9 +25,8 @@ ( HasField(..) ) where --- The import of GHC.Internal.Base is for build ordering; see Notes in GHC.Internal.Base for--- more info.-import GHC.Internal.Base ()+-- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base+import GHC.Types () -- | Constraint representing the fact that the field @x@ belongs to -- the record type @r@ and has field type @a@. This will be solved
src/GHC/Internal/Stack/Types.hs view
@@ -54,9 +54,7 @@ import GHC.Classes (Eq) import GHC.Types (Char, Int) --- Make implicit dependency known to build system-import GHC.Tuple () -- See Note [Depend on GHC.Tuple] in GHC.Internal.Base-import GHC.Num.Integer () -- See Note [Depend on GHC.Num.Integer] in GHC.Internal.Base+default () -- $setup -- >>> import Prelude
src/GHC/Internal/System/Posix/Internals.hs view
@@ -140,17 +140,30 @@ fdType :: FD -> IO IODeviceType fdType fd = do (ty,_,_) <- fdStat fd; return ty +-- | Return a known device type or throw an exception if the device+-- type is unknown. statGetType :: Ptr CStat -> IO IODeviceType statGetType p_stat = do+ dev_ty_m <- statGetType_maybe p_stat+ case dev_ty_m of+ Nothing -> ioError ioe_unknownfiletype+ Just dev_ty -> pure dev_ty++-- | Unlike @statGetType@, @statGetType_maybe@ will not throw an exception+-- if the CStat refers to a unknown device type.+--+-- @since base-4.20.1.0+statGetType_maybe :: Ptr CStat -> IO (Maybe IODeviceType)+statGetType_maybe p_stat = do c_mode <- st_mode p_stat :: IO CMode case () of- _ | s_isdir c_mode -> return Directory+ _ | s_isdir c_mode -> return $ Just Directory | s_isfifo c_mode || s_issock c_mode || s_ischr c_mode- -> return Stream- | s_isreg c_mode -> return RegularFile+ -> return $ Just Stream+ | s_isreg c_mode -> return $ Just RegularFile -- Q: map char devices to RawDevice too?- | s_isblk c_mode -> return RawDevice- | otherwise -> ioError ioe_unknownfiletype+ | s_isblk c_mode -> return $ Just RawDevice+ | otherwise -> return Nothing ioe_unknownfiletype :: IOException ioe_unknownfiletype = IOError Nothing UnsupportedOperation "fdType"
src/GHC/Internal/TypeError.hs view
@@ -32,7 +32,6 @@ ) where import GHC.Internal.Data.Bool-import GHC.Num.Integer () -- See Note [Depend on GHC.Num.Integer] in GHC.Internal.Base import GHC.Types (TYPE, Constraint, Symbol) {- Note [Custom type errors]
src/GHC/Internal/Wasm/Prim/Conc/Internal.hs view
@@ -6,6 +6,8 @@ import GHC.Internal.Base import GHC.Internal.IO++-- See W6 of Note [Tracking dependencies on primitives] in GHC.Internal.Base import GHC.Internal.Wasm.Prim.Imports () foreign import javascript safe "new Promise(res => setTimeout(res, $1 / 1000))"