[Git][ghc/ghc][master] exceptions: annotate onException continuation with WhileHandling
by Marge Bot (@marge-bot) 14 Mar '26
by Marge Bot (@marge-bot) 14 Mar '26
14 Mar '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
3774086e by Matthew Pickering at 2026-03-14T05:13:00-04:00
exceptions: annotate onException continuation with WhileHandling
Before this patch, an exception thrown in the `onException` handler
would loose track of where the original exception was thrown.
```
import Control.Exception
main :: IO ()
main = failingAction `onException` failingCleanup
where
failingAction = throwIO (ErrorCall "outer failure")
failingCleanup = throwIO (ErrorCall "cleanup failure")
```
would report
```
T28399: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
HasCallStack backtrace:
throwIO, called at T28399.hs:<line>:<column> in <package-id>:Main
```
notice that the "outer failure" exception is not present in the error
message.
With this patch, any exception thrown is in the handler is annotated
with WhileHandling. The resulting message looks like
```
T28399: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
While handling outer failure
HasCallStack backtrace:
throwIO, called at T28399.hs:7:22 in main:Main
```
CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/397
Fixes #26759
- - - - -
9 changed files:
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
- libraries/ghc-internal/src/GHC/Internal/IO.hs
- + testsuite/tests/exceptions/T26759.hs
- + testsuite/tests/exceptions/T26759.stderr
- + testsuite/tests/exceptions/T26759a.hs
- + testsuite/tests/exceptions/T26759a.stderr
- + testsuite/tests/exceptions/T26759a.stdout
- testsuite/tests/exceptions/all.T
Changes:
=====================================
libraries/base/changelog.md
=====================================
@@ -27,6 +27,7 @@
* Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
* Hide implementation details when throwing exceptions in throw and throwSTM. ([CLC proposal #387](https://github.com/haskell/core-libraries-committee/issues/387))
* Change `hIsReadable` and `hIsWritable` such that they always throw a respective exception when encountering a closed or semi-closed handle, not just in the case of a file handle. ([CLC proposal #371](github.com/haskell/core-libraries-committee/issues/371))
+ * Annotate `onException` continuation with `WhileHandling`. ([CLC Proposal #397](https://github.com/haskell/core-libraries-committee/issues/397))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
=====================================
@@ -203,7 +203,7 @@ tryJust p a = catchJust p (Right `fmap` a) (return . Left)
-- exception raised by the computation.
onException :: IO a -> IO b -> IO a
onException io what = io `catchNoPropagate` \e -> do
- _ <- what
+ _ <- annotateIO (whileHandling e) what
rethrowIO (e :: ExceptionWithContext SomeException)
-----------------------------------------------------------------------------
=====================================
libraries/ghc-internal/src/GHC/Internal/IO.hs
=====================================
@@ -52,7 +52,7 @@ module GHC.Internal.IO (
import GHC.Internal.Base
import GHC.Internal.ST
import GHC.Internal.Exception
-import GHC.Internal.Exception.Type (NoBacktrace(..), WhileHandling(..), HasExceptionContext, ExceptionWithContext(..))
+import GHC.Internal.Exception.Type (NoBacktrace(..), whileHandling, WhileHandling(..), HasExceptionContext, ExceptionWithContext(..))
import GHC.Internal.Show
import GHC.Internal.IO.Unsafe
import GHC.Internal.Unsafe.Coerce ( unsafeCoerce )
@@ -363,7 +363,7 @@ getMaskingState = IO $ \s ->
onException :: IO a -> IO b -> IO a
onException io what = io `catchExceptionNoPropagate` \e -> do
- _ <- what
+ _ <- annotateIO (whileHandling e) what
rethrowIO (e :: ExceptionWithContext SomeException)
-- | Executes an IO computation with asynchronous
=====================================
testsuite/tests/exceptions/T26759.hs
=====================================
@@ -0,0 +1,10 @@
+import Control.Exception
+
+run :: IO ()
+run = failingAction `onException` failingCleanup
+ where
+ failingAction = throwIO (ErrorCall "outer failure")
+ failingCleanup = throwIO (ErrorCall "cleanup failure")
+
+main :: IO ()
+main = run
=====================================
testsuite/tests/exceptions/T26759.stderr
=====================================
@@ -0,0 +1,9 @@
+T26759: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+
+cleanup failure
+
+While handling outer failure
+
+HasCallStack backtrace:
+ throwIO, called at T26759.hs:7:22 in main:Main
+
=====================================
testsuite/tests/exceptions/T26759a.hs
=====================================
@@ -0,0 +1,10 @@
+import Control.Exception
+
+run :: IO ()
+run = failingAction `onException` cleanup
+ where
+ failingAction = throwIO (ErrorCall "outer failure")
+ cleanup = putStrLn "cleanup"
+
+main :: IO ()
+main = run
=====================================
testsuite/tests/exceptions/T26759a.stderr
=====================================
@@ -0,0 +1,7 @@
+T26759a: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+
+outer failure
+
+HasCallStack backtrace:
+ throwIO, called at T26759a.hs:6:21 in main:Main
+
=====================================
testsuite/tests/exceptions/T26759a.stdout
=====================================
@@ -0,0 +1 @@
+cleanup
=====================================
testsuite/tests/exceptions/all.T
=====================================
@@ -1,2 +1,3 @@
test('T25052', normal, compile_and_run, [''])
-
+test('T26759', exit_code(1), compile_and_run, [''])
+test('T26759a', exit_code(1), compile_and_run, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3774086e666f08d9800ce22a1dfc3a1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3774086e666f08d9800ce22a1dfc3a1…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] configure: make $LLVMAS default to $CC when $CcLlvmBackend is YES
by Marge Bot (@marge-bot) 14 Mar '26
by Marge Bot (@marge-bot) 14 Mar '26
14 Mar '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
a18fa3c1 by Cheng Shao at 2026-03-14T05:12:14-04:00
configure: make $LLVMAS default to $CC when $CcLlvmBackend is YES
This patch changes the $LLVMAS detection logic in configure so that
when it's not manually specified by the user, it defaults to $CC if
$CcLlvmBackend is YES. It's a more sensible default than auto-detected
clang from the environment, especially when cross-compiling, $CC as
the cross target's LLVM assembler is more compatible with the use case
than the system-wide clang. Fixes #26769.
- - - - -
2 changed files:
- configure.ac
- distrib/configure.ac.in
Changes:
=====================================
configure.ac
=====================================
@@ -542,9 +542,17 @@ FIND_LLVM_PROG([OPT], [opt], [$LlvmMinVersion], [$LlvmMaxVersion])
OptCmd="$OPT"
AC_SUBST([OptCmd])
+dnl ** look to see if we have a C compiler using an llvm back end.
+dnl
+FP_CC_LLVM_BACKEND
+AC_SUBST(CcLlvmBackend)
+
dnl ** Which LLVM assembler to use?
dnl --------------------------------------------------------------
AC_ARG_VAR(LLVMAS,[Use as the path to LLVM's assembler (typically clang) [default=autodetect]])
+if test "x$CcLlvmBackend" = "xYES" && test -z "$LLVMAS"; then
+ LLVMAS="$CC"
+fi
FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion])
LlvmAsCmd="$LLVMAS"
AC_SUBST([LlvmAsCmd])
@@ -622,11 +630,6 @@ else
AC_SUBST([NeedLibatomic],[NO])
fi
-dnl ** look to see if we have a C compiler using an llvm back end.
-dnl
-FP_CC_LLVM_BACKEND
-AC_SUBST(CcLlvmBackend)
-
FPTOOLS_SET_C_LD_FLAGS([target],[CFLAGS],[LDFLAGS],[IGNORE_LINKER_LD_FLAGS],[CPPFLAGS])
FPTOOLS_SET_C_LD_FLAGS([build],[CONF_CC_OPTS_STAGE0],[CONF_GCC_LINKER_OPTS_STAGE0],[CONF_LD_LINKER_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAGE1],[CONF_LD_LINKER_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
=====================================
distrib/configure.ac.in
=====================================
@@ -203,9 +203,17 @@ FIND_LLVM_PROG([OPT], [opt], [$LlvmMinVersion], [$LlvmMaxVersion])
OptCmd="$OPT"
AC_SUBST([OptCmd])
+dnl ** look to see if we have a C compiler using an llvm back end.
+dnl
+FP_CC_LLVM_BACKEND
+AC_SUBST(CcLlvmBackend)
+
dnl ** Which LLVM assembler to use?
dnl --------------------------------------------------------------
AC_ARG_VAR(LLVMAS,[Use as the path to LLVM's assembler (typically clang) [default=autodetect]])
+if test "x$CcLlvmBackend" = "xYES" && test -z "$LLVMAS"; then
+ LLVMAS="$CC"
+fi
FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion])
LlvmAsCmd="$LLVMAS"
AC_SUBST([LlvmAsCmd])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a18fa3c142a194aa9725abb004730ad…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a18fa3c142a194aa9725abb004730ad…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
14 Mar '26
Cheng Shao pushed new branch wip/ci-make-install-j at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ci-make-install-j
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: configure: make $LLVMAS default to $CC when $CcLlvmBackend is YES
by Marge Bot (@marge-bot) 14 Mar '26
by Marge Bot (@marge-bot) 14 Mar '26
14 Mar '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
8833e7d9 by Cheng Shao at 2026-03-14T00:11:41-04:00
configure: make $LLVMAS default to $CC when $CcLlvmBackend is YES
This patch changes the $LLVMAS detection logic in configure so that
when it's not manually specified by the user, it defaults to $CC if
$CcLlvmBackend is YES. It's a more sensible default than auto-detected
clang from the environment, especially when cross-compiling, $CC as
the cross target's LLVM assembler is more compatible with the use case
than the system-wide clang. Fixes #26769.
- - - - -
53ae233d by Matthew Pickering at 2026-03-14T00:11:41-04:00
exceptions: annotate onException continuation with WhileHandling
Before this patch, an exception thrown in the `onException` handler
would loose track of where the original exception was thrown.
```
import Control.Exception
main :: IO ()
main = failingAction `onException` failingCleanup
where
failingAction = throwIO (ErrorCall "outer failure")
failingCleanup = throwIO (ErrorCall "cleanup failure")
```
would report
```
T28399: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
HasCallStack backtrace:
throwIO, called at T28399.hs:<line>:<column> in <package-id>:Main
```
notice that the "outer failure" exception is not present in the error
message.
With this patch, any exception thrown is in the handler is annotated
with WhileHandling. The resulting message looks like
```
T28399: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
While handling outer failure
HasCallStack backtrace:
throwIO, called at T28399.hs:7:22 in main:Main
```
CLC Proposal: https://github.com/haskell/core-libraries-committee/issues/397
Fixes #26759
- - - - -
a3ac9e2a by Andreas Klebinger at 2026-03-14T00:11:42-04:00
Fix missing profiling header for origin_thunk frame.
Fixes #27007
- - - - -
e1118b76 by Cheng Shao at 2026-03-14T00:11:43-04:00
ci: fix ci-images revision
The current ci-images revision was a commit on the WIP branch of
https://gitlab.haskell.org/ghc/ci-images/-/merge_requests/183, and
it's not on the current ci-images master branch. This patch fixes the
image revision to use the current tip of ci-images master.
- - - - -
6a4c0dcc by Andreas Klebinger at 2026-03-14T00:11:44-04:00
Revert "hadrian/build-cabal: Better respect and utilize -j"
This reverts commit eab3dbba79650e6046efca79133b4c0a5257613d.
While it's neat this currently isn't well supported on all platforms.
It's time will come, but for now I'm reverting this to avoid issues for
users on slightly unconvential platforms.
This will be tracked at #26977.
- - - - -
14 changed files:
- .gitlab-ci.yml
- configure.ac
- distrib/configure.ac.in
- hadrian/build-cabal
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
- libraries/ghc-internal/src/GHC/Internal/IO.hs
- rts/StgMiscClosures.cmm
- + testsuite/tests/exceptions/T26759.hs
- + testsuite/tests/exceptions/T26759.stderr
- + testsuite/tests/exceptions/T26759a.hs
- + testsuite/tests/exceptions/T26759a.stderr
- + testsuite/tests/exceptions/T26759a.stdout
- testsuite/tests/exceptions/all.T
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -11,7 +11,7 @@ variables:
GIT_SSL_NO_VERIFY: "1"
# Commit of ghc/ci-images repository from which to pull Docker images
- DOCKER_REV: 4c3454a524436623df71b5faabd24e30b0f816d5
+ DOCKER_REV: 5df428b97c501f61f57587048d4bd15eba53e364
# Sequential version number of all cached things.
# Bump to invalidate GitLab CI cache.
=====================================
configure.ac
=====================================
@@ -542,9 +542,17 @@ FIND_LLVM_PROG([OPT], [opt], [$LlvmMinVersion], [$LlvmMaxVersion])
OptCmd="$OPT"
AC_SUBST([OptCmd])
+dnl ** look to see if we have a C compiler using an llvm back end.
+dnl
+FP_CC_LLVM_BACKEND
+AC_SUBST(CcLlvmBackend)
+
dnl ** Which LLVM assembler to use?
dnl --------------------------------------------------------------
AC_ARG_VAR(LLVMAS,[Use as the path to LLVM's assembler (typically clang) [default=autodetect]])
+if test "x$CcLlvmBackend" = "xYES" && test -z "$LLVMAS"; then
+ LLVMAS="$CC"
+fi
FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion])
LlvmAsCmd="$LLVMAS"
AC_SUBST([LlvmAsCmd])
@@ -622,11 +630,6 @@ else
AC_SUBST([NeedLibatomic],[NO])
fi
-dnl ** look to see if we have a C compiler using an llvm back end.
-dnl
-FP_CC_LLVM_BACKEND
-AC_SUBST(CcLlvmBackend)
-
FPTOOLS_SET_C_LD_FLAGS([target],[CFLAGS],[LDFLAGS],[IGNORE_LINKER_LD_FLAGS],[CPPFLAGS])
FPTOOLS_SET_C_LD_FLAGS([build],[CONF_CC_OPTS_STAGE0],[CONF_GCC_LINKER_OPTS_STAGE0],[CONF_LD_LINKER_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAGE1],[CONF_LD_LINKER_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
=====================================
distrib/configure.ac.in
=====================================
@@ -203,9 +203,17 @@ FIND_LLVM_PROG([OPT], [opt], [$LlvmMinVersion], [$LlvmMaxVersion])
OptCmd="$OPT"
AC_SUBST([OptCmd])
+dnl ** look to see if we have a C compiler using an llvm back end.
+dnl
+FP_CC_LLVM_BACKEND
+AC_SUBST(CcLlvmBackend)
+
dnl ** Which LLVM assembler to use?
dnl --------------------------------------------------------------
AC_ARG_VAR(LLVMAS,[Use as the path to LLVM's assembler (typically clang) [default=autodetect]])
+if test "x$CcLlvmBackend" = "xYES" && test -z "$LLVMAS"; then
+ LLVMAS="$CC"
+fi
FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion])
LlvmAsCmd="$LLVMAS"
AC_SUBST([LlvmAsCmd])
=====================================
hadrian/build-cabal
=====================================
@@ -23,52 +23,9 @@ fi
CABVERSTR=$("$CABAL" --numeric-version)
CABVER=( ${CABVERSTR//./ } )
-THREADS="-j1"
-GC_THREADS=""
-SEMAPHORE=""
-
-echo "$@"
-
-# Try building hadrian in parallel. We check for -j<n>.
-# If threads > 1 we pass --semaphore to allow ghc to build more than one module in parallel
-# If threads > 4 we pass -qn as higher parallel gc thread counts can lead to slow downs
-# We only do any of thise for cabal >= 3.14, because I don't trust older versions to handle --semaphore right
-if [ "${CABVER[0]}" -gt 3 ] || [ "${CABVER[0]}" -eq 3 -a "${CABVER[1]}" -ge 14 ];
-then
-
- for arg in "$@"; do
- case "$arg" in
- -j)
- GC_THREADS="-qn4"
- SEMAPHORE="--semaphore"
- THREADS="-j"
- ;;
- -j[0-9]*)
- threads="${arg#-j}"
- if [[ "$threads" =~ ^[0-9]+$ ]] && [ "$threads" -ne 0 ]; then
- THREADS="-j${threads}"
- if [ $threads -ge 4 ]; then
- GC_THREADS="-qn4"
- fi
- if [ $threads -gt 1 ]; then
- SEMAPHORE="--semaphore"
- fi
- fi
- ;;
- esac
-
- done
-
-fi
-
-if [ "$(uname -s)" = "FreeBSD" ]; then
- # Can't rely on posix semaphore support in free bsd.
- SEMAPHORE=""
-fi
-
if [ "${CABVER[0]}" -gt 2 -o "${CABVER[0]}" -eq 2 -a "${CABVER[1]}" -ge 2 ];
then
- "$CABAL" --project-file="$PROJ" new-build "${CABFLAGS[@]}" ${THREADS} ${SEMAPHORE} --ghc-options="+RTS ${GC_THREADS} -RTS" exe:hadrian
+ "$CABAL" --project-file="$PROJ" new-build "${CABFLAGS[@]}" -j exe:hadrian
# use new-exec instead of new-run to make sure that the build-tools (alex & happy) are in PATH
"$CABAL" --project-file="$PROJ" new-exec "${CABFLAGS[@]}" hadrian -- \
--directory "$PWD" \
=====================================
libraries/base/changelog.md
=====================================
@@ -27,6 +27,7 @@
* Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
* Hide implementation details when throwing exceptions in throw and throwSTM. ([CLC proposal #387](https://github.com/haskell/core-libraries-committee/issues/387))
* Change `hIsReadable` and `hIsWritable` such that they always throw a respective exception when encountering a closed or semi-closed handle, not just in the case of a file handle. ([CLC proposal #371](github.com/haskell/core-libraries-committee/issues/371))
+ * Annotate `onException` continuation with `WhileHandling`. ([CLC Proposal #397](https://github.com/haskell/core-libraries-committee/issues/397))
## 4.22.0.0 *TBA*
* Shipped with GHC 9.14.1
=====================================
libraries/ghc-internal/src/GHC/Internal/Control/Exception/Base.hs
=====================================
@@ -203,7 +203,7 @@ tryJust p a = catchJust p (Right `fmap` a) (return . Left)
-- exception raised by the computation.
onException :: IO a -> IO b -> IO a
onException io what = io `catchNoPropagate` \e -> do
- _ <- what
+ _ <- annotateIO (whileHandling e) what
rethrowIO (e :: ExceptionWithContext SomeException)
-----------------------------------------------------------------------------
=====================================
libraries/ghc-internal/src/GHC/Internal/IO.hs
=====================================
@@ -52,7 +52,7 @@ module GHC.Internal.IO (
import GHC.Internal.Base
import GHC.Internal.ST
import GHC.Internal.Exception
-import GHC.Internal.Exception.Type (NoBacktrace(..), WhileHandling(..), HasExceptionContext, ExceptionWithContext(..))
+import GHC.Internal.Exception.Type (NoBacktrace(..), whileHandling, WhileHandling(..), HasExceptionContext, ExceptionWithContext(..))
import GHC.Internal.Show
import GHC.Internal.IO.Unsafe
import GHC.Internal.Unsafe.Coerce ( unsafeCoerce )
@@ -363,7 +363,7 @@ getMaskingState = IO $ \s ->
onException :: IO a -> IO b -> IO a
onException io what = io `catchExceptionNoPropagate` \e -> do
- _ <- what
+ _ <- annotateIO (whileHandling e) what
rethrowIO (e :: ExceptionWithContext SomeException)
-- | Executes an IO computation with asynchronous
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -47,6 +47,7 @@ import CLOSURE stg_ret_v_info;
/* See Note [Original thunk info table frames] in GHC.StgToCmm.Bind. */
INFO_TABLE_RET (stg_orig_thunk_info_frame, RET_SMALL,
W_ info_ptr,
+ PROF_HDR_FIELDS(W_, p1, p2)
W_ thunk_info_ptr)
/* no args => explicit stack */
{
=====================================
testsuite/tests/exceptions/T26759.hs
=====================================
@@ -0,0 +1,10 @@
+import Control.Exception
+
+run :: IO ()
+run = failingAction `onException` failingCleanup
+ where
+ failingAction = throwIO (ErrorCall "outer failure")
+ failingCleanup = throwIO (ErrorCall "cleanup failure")
+
+main :: IO ()
+main = run
=====================================
testsuite/tests/exceptions/T26759.stderr
=====================================
@@ -0,0 +1,9 @@
+T26759: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+
+cleanup failure
+
+While handling outer failure
+
+HasCallStack backtrace:
+ throwIO, called at T26759.hs:7:22 in main:Main
+
=====================================
testsuite/tests/exceptions/T26759a.hs
=====================================
@@ -0,0 +1,10 @@
+import Control.Exception
+
+run :: IO ()
+run = failingAction `onException` cleanup
+ where
+ failingAction = throwIO (ErrorCall "outer failure")
+ cleanup = putStrLn "cleanup"
+
+main :: IO ()
+main = run
=====================================
testsuite/tests/exceptions/T26759a.stderr
=====================================
@@ -0,0 +1,7 @@
+T26759a: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+
+outer failure
+
+HasCallStack backtrace:
+ throwIO, called at T26759a.hs:6:21 in main:Main
+
=====================================
testsuite/tests/exceptions/T26759a.stdout
=====================================
@@ -0,0 +1 @@
+cleanup
=====================================
testsuite/tests/exceptions/all.T
=====================================
@@ -1,2 +1,3 @@
test('T25052', normal, compile_and_run, [''])
-
+test('T26759', exit_code(1), compile_and_run, [''])
+test('T26759a', exit_code(1), compile_and_run, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dedb4fec9b374c4f422f04d10b9395…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dedb4fec9b374c4f422f04d10b9395…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
14 Mar '26
Teo Camarasu pushed to branch wip/abstract-q at Glasgow Haskell Compiler / GHC
Commits:
81baed9d by Teo Camarasu at 2026-03-14T01:09:55+00:00
wip: Abstract Q
- - - - -
3fd2d50d by Teo Camarasu at 2026-03-14T01:09:55+00:00
wip
- - - - -
4 changed files:
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Tc/Gen/Splice.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghci/GHCi/TH.hs
Changes:
=====================================
compiler/GHC/Data/IOEnv.hs
=====================================
@@ -29,7 +29,7 @@ module GHC.Data.IOEnv (
-- I/O operations
IORef, newMutVar, readMutVar, writeMutVar, updMutVar,
- atomicUpdMutVar, atomicUpdMutVar'
+ atomicUpdMutVar, atomicUpdMutVar', unliftIOEnv
) where
import GHC.Prelude
@@ -258,3 +258,10 @@ updEnv upd (IOEnv m) = IOEnv (\ env -> m (upd env))
updEnvIO :: (env -> IO env') -> IOEnv env' a -> IOEnv env a
{-# INLINE updEnvIO #-}
updEnvIO upd (IOEnv m) = IOEnv (\ env -> m =<< upd env)
+
+unliftIOEnv :: forall env b. ((forall a. IOEnv env a -> IO a) -> IO b) -> IOEnv env b
+unliftIOEnv k = IOEnv $ \env ->
+ let
+ unlift :: forall a. IOEnv env a -> IO a
+ unlift (IOEnv m) = m env
+ in k unlift
=====================================
compiler/GHC/Tc/Gen/Splice.hs
=====================================
@@ -138,6 +138,7 @@ import qualified GHC.LanguageExtensions as LangExt
-- THSyntax gives access to internal functions and data types
import qualified GHC.Boot.TH.Syntax as TH
import qualified GHC.Boot.TH.Monad as TH
+import GHC.Boot.TH.Monad (MetaHandlers(..))
import qualified GHC.Boot.TH.Ppr as TH
#if defined(HAVE_INTERNAL_INTERPRETER)
@@ -1139,7 +1140,7 @@ convertAnnotationWrapper fhv = do
-}
runQuasi :: TH.Q a -> TcM a
-runQuasi act = TH.runQ act
+runQuasi (TH.Q act) = unliftIOEnv $ \runInIO -> liftIO $ act runInIO metaHandlersTcM
runRemoteModFinalizers :: ThModFinalizers -> TcM ()
runRemoteModFinalizers (ThModFinalizers finRefs) = do
@@ -1466,68 +1467,12 @@ when showing an error message.
To call runQ in the Tc monad, we need to make TcM an instance of Quasi:
-}
-instance TH.Quasi TcM where
- qNewName s = do { u <- newUnique
- ; let i = toInteger (getKey u)
- ; return (TH.mkNameU s i) }
-
- -- 'msg' is forced to ensure exceptions don't escape,
- -- see Note [Exceptions in TH]
- qReport True msg = seqList msg $ addErr $ TcRnTHError $ ReportCustomQuasiError True msg
- qReport False msg = seqList msg $ addDiagnostic $ TcRnTHError $ ReportCustomQuasiError False msg
-
- qLocation :: TcM TH.Loc
- qLocation = do { m <- getModule
- ; l <- getSrcSpanM
- ; r <- case l of
- UnhelpfulSpan _ -> pprPanic "qLocation: Unhelpful location"
- (ppr l)
- RealSrcSpan s _ -> return s
- ; return (TH.Loc { TH.loc_filename = unpackFS (srcSpanFile r)
- , TH.loc_module = moduleNameString (moduleName m)
- , TH.loc_package = unitString (moduleUnit m)
- , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
- , TH.loc_end = (srcSpanEndLine r, srcSpanEndCol r) }) }
-
- qLookupName = lookupName
- qReify = reify
- qReifyFixity nm = lookupThName nm >>= reifyFixity
- qReifyType = reifyTypeOfThing
- qReifyInstances = reifyInstances
- qReifyRoles = reifyRoles
- qReifyAnnotations = reifyAnnotations
- qReifyModule = reifyModule
- qReifyConStrictness nm = do { nm' <- lookupThName nm
- ; dc <- tcLookupDataCon nm'
- ; let bangs = dataConImplBangs dc
- ; return (map reifyDecidedStrictness bangs) }
-
- -- For qRecover, discard error messages if
- -- the recovery action is chosen. Otherwise
- -- we'll only fail higher up.
- qRecover recover main = tryTcDiscardingErrs recover main
-
- qGetPackageRoot = do
- dflags <- getDynFlags
- return $ fromMaybe "." (workingDirectory dflags)
-
- qAddDependentFile fp = do
- ref <- fmap tcg_dependent_files getGblEnv
- dep_files <- readTcRef ref
- writeTcRef ref (fp:dep_files)
-
- qAddDependentDirectory dp = do
- ref <- fmap tcg_dependent_dirs getGblEnv
- dep_dirs <- readTcRef ref
- writeTcRef ref (dp:dep_dirs)
-
- qAddTempFile suffix = do
- dflags <- getDynFlags
- logger <- getLogger
- tmpfs <- hsc_tmpfs <$> getTopEnv
- liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
-
- qAddTopDecls thds = do
+report :: Bool -> [Char] -> TcM ()
+report True msg = seqList msg $ addErr $ TcRnTHError $ ReportCustomQuasiError True msg
+report False msg = seqList msg $ addDiagnostic $ TcRnTHError $ ReportCustomQuasiError False msg
+
+addTopDecls :: [TH.Dec] -> TcM ()
+addTopDecls thds = do
exts <- fmap extensionFlags getDynFlags
l <- getSrcSpanM
th_origin <- getThSpliceOrigin
@@ -1555,52 +1500,13 @@ instance TH.Quasi TcM where
bindName :: RdrName -> TcM ()
bindName (Exact n)
= do { th_topnames_var <- fmap tcg_th_topnames getGblEnv
- ; updTcRef th_topnames_var (\ns -> extendNameSet ns n)
- }
+ ; updTcRef th_topnames_var (\ns -> extendNameSet ns n)
+ }
bindName name = addErr $ TcRnTHError $ THNameError $ NonExactName name
- qAddForeignFilePath lang fp = do
- var <- fmap tcg_th_foreign_files getGblEnv
- updTcRef var ((lang, fp) :)
-
- qAddModFinalizer fin = do
- r <- liftIO $ mkRemoteRef fin
- fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
- addModFinalizerRef fref
-
- qAddCorePlugin plugin = do
- hsc_env <- getTopEnv
- let fc = hsc_FC hsc_env
- let home_unit = hsc_home_unit hsc_env
- let dflags = hsc_dflags hsc_env
- let fopts = initFinderOpts dflags
- r <- liftIO $ findHomeModule fc fopts home_unit (mkModuleName plugin)
- let err = TcRnTHError $ AddInvalidCorePlugin plugin
- case r of
- Found {} -> addErr err
- FoundMultiple {} -> addErr err
- _ -> return ()
- th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
- updTcRef th_coreplugins_var (plugin:)
-
- qGetQ :: forall a. Typeable a => TcM (Maybe a)
- qGetQ = do
- th_state_var <- fmap tcg_th_state getGblEnv
- th_state <- readTcRef th_state_var
- -- See #10596 for why we use a scoped type variable here.
- return (Map.lookup (typeRep (Proxy :: Proxy a)) th_state >>= fromDynamic)
-
- qPutQ x = do
- th_state_var <- fmap tcg_th_state getGblEnv
- updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
-
- qIsExtEnabled = xoptM
-
- qExtsEnabled =
- EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
-
- qPutDoc doc_loc s = do
+putDoc :: TH.DocLoc -> String -> TcM ()
+putDoc doc_loc s = do
th_doc_var <- tcg_th_docs <$> getGblEnv
resolved_doc_loc <- resolve_loc doc_loc
is_local <- checkLocalName resolved_doc_loc
@@ -1622,15 +1528,129 @@ instance TH.Quasi TcM where
checkLocalName (InstDoc n) = nameIsLocalOrFrom <$> getModule <*> pure n
checkLocalName ModuleDoc = pure True
-
- qGetDoc (TH.DeclDoc n) = lookupThName n >>= lookupDeclDoc
- qGetDoc (TH.InstDoc t) = lookupThInstName t >>= lookupDeclDoc
- qGetDoc (TH.ArgDoc n i) = lookupThName n >>= lookupArgDoc i
- qGetDoc TH.ModuleDoc = do
+getDoc :: TH.DocLoc -> TcM (Maybe String)
+getDoc (TH.DeclDoc n) = lookupThName n >>= lookupDeclDoc
+getDoc (TH.InstDoc t) = lookupThInstName t >>= lookupDeclDoc
+getDoc (TH.ArgDoc n i) = lookupThName n >>= lookupArgDoc i
+getDoc TH.ModuleDoc = do
df <- getDynFlags
docs <- getGblEnv >>= extractDocs df
return (renderHsDocString . hsDocString <$> (docs_mod_hdr =<< docs))
+getQ :: forall a. Typeable a => TcM (Maybe a)
+getQ = do
+ th_state_var <- fmap tcg_th_state getGblEnv
+ th_state <- readTcRef th_state_var
+ -- See #10596 for why we use a scoped type variable here.
+ return (Map.lookup (typeRep (Proxy :: Proxy a)) th_state >>= fromDynamic)
+
+location :: TcM TH.Loc
+location = do { m <- getModule
+ ; l <- getSrcSpanM
+ ; r <- case l of
+ UnhelpfulSpan _ -> pprPanic "qLocation: Unhelpful location"
+ (ppr l)
+ RealSrcSpan s _ -> return s
+ ; return (TH.Loc { TH.loc_filename = unpackFS (srcSpanFile r)
+ , TH.loc_module = moduleNameString (moduleName m)
+ , TH.loc_package = unitString (moduleUnit m)
+ , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
+ , TH.loc_end = (srcSpanEndLine r, srcSpanEndCol r) }) }
+
+metaHandlersTcM :: TH.MetaHandlers TcM
+metaHandlersTcM = TH.MetaHandlers {
+ mNewName = \s -> do { u <- newUnique
+ ; let i = toInteger (getKey u)
+ ; return (TH.mkNameU s i) }
+
+ -- 'msg' is forced to ensure exceptions don't escape,
+ -- see Note [Exceptions in TH]
+ , mReport = report
+
+ , mLocation = location
+
+ , mLookupName = lookupName
+ , mReify = reify
+ , mReifyFixity = \nm -> lookupThName nm >>= reifyFixity
+ , mReifyType = reifyTypeOfThing
+ , mReifyInstances = reifyInstances
+ , mReifyRoles = reifyRoles
+ , mReifyAnnotations = reifyAnnotations
+ , mReifyModule = reifyModule
+ , mReifyConStrictness = \nm -> do { nm' <- lookupThName nm
+ ; dc <- tcLookupDataCon nm'
+ ; let bangs = dataConImplBangs dc
+ ; return (map reifyDecidedStrictness bangs) }
+
+ -- For qRecover, discard error messages if
+ -- the recovery action is chosen. Otherwise
+ -- we'll only fail higher up.
+ -- NB: extremely subtle!!! TODO: write up note
+ -- tryTcDiscardingErrs manipulates the reader env so we need to be careful we don't sneak in the outside env
+ , mRecover = \recover main -> tryTcDiscardingErrs (runQuasi recover) (runQuasi main)
+
+ , mGetPackageRoot = do
+ dflags <- getDynFlags
+ return $ fromMaybe "." (workingDirectory dflags)
+
+ , mAddDependentFile = \fp -> do
+ ref <- fmap tcg_dependent_files getGblEnv
+ dep_files <- readTcRef ref
+ writeTcRef ref (fp:dep_files)
+
+ , mAddDependentDirectory = \dp -> do
+ ref <- fmap tcg_dependent_dirs getGblEnv
+ dep_dirs <- readTcRef ref
+ writeTcRef ref (dp:dep_dirs)
+
+ , mAddTempFile = \suffix -> do
+ dflags <- getDynFlags
+ logger <- getLogger
+ tmpfs <- hsc_tmpfs <$> getTopEnv
+ liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
+
+ , mAddTopDecls = addTopDecls
+
+ , mAddForeignFilePath = \lang fp -> do
+ var <- fmap tcg_th_foreign_files getGblEnv
+ updTcRef var ((lang, fp) :)
+
+ , mAddModFinalizer = \fin -> do
+ r <- liftIO $ mkRemoteRef fin
+ fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
+ addModFinalizerRef fref
+
+ , mAddCorePlugin = \plugin -> do
+ hsc_env <- getTopEnv
+ let fc = hsc_FC hsc_env
+ let home_unit = hsc_home_unit hsc_env
+ let dflags = hsc_dflags hsc_env
+ let fopts = initFinderOpts dflags
+ r <- liftIO $ findHomeModule fc fopts home_unit (mkModuleName plugin)
+ let err = TcRnTHError $ AddInvalidCorePlugin plugin
+ case r of
+ Found {} -> addErr err
+ FoundMultiple {} -> addErr err
+ _ -> return ()
+ th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
+ updTcRef th_coreplugins_var (plugin:)
+
+ , mGetQ = getQ
+
+ , mPutQ = \x -> do
+ th_state_var <- fmap tcg_th_state getGblEnv
+ updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
+
+ , mIsExtEnabled = xoptM
+
+ , mExtsEnabled =
+ EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
+
+ , mPutDoc = putDoc
+
+ , mGetDoc = getDoc
+ }
+
-- | Looks up documentation for a declaration in first the current module,
-- otherwise tries to find it in another module via 'hscGetModuleInterface'.
lookupDeclDoc :: Name -> TcM (Maybe String)
@@ -1795,7 +1815,7 @@ runTH ty fhv = do
-- Remote GHCi, see Note [Remote Template Haskell] in
-- libraries/ghci/GHCi/TH.hs.
rstate <- getTHState inst
- loc <- TH.qLocation
+ loc <- location
-- run a remote TH request
r <- liftIO $
withForeignRef rstate $ \state_hv ->
@@ -1911,32 +1931,32 @@ wrapTHResult tcm = do
handleTHMessage :: THMessage a -> TcM a
handleTHMessage msg = case msg of
- NewName a -> wrapTHResult $ TH.qNewName a
- Report b str -> wrapTHResult $ TH.qReport b str
- LookupName b str -> wrapTHResult $ TH.qLookupName b str
- Reify n -> wrapTHResult $ TH.qReify n
- ReifyFixity n -> wrapTHResult $ TH.qReifyFixity n
- ReifyType n -> wrapTHResult $ TH.qReifyType n
- ReifyInstances n ts -> wrapTHResult $ TH.qReifyInstances n ts
- ReifyRoles n -> wrapTHResult $ TH.qReifyRoles n
+ NewName a -> wrapTHResult $ runQuasi $ TH.newName a
+ Report b str -> wrapTHResult $ runQuasi $ TH.report b str
+ LookupName b str -> wrapTHResult $ runQuasi $ TH.lookupName b str
+ Reify n -> wrapTHResult $ runQuasi $ TH.reify n
+ ReifyFixity n -> wrapTHResult $ runQuasi $ TH.reifyFixity n
+ ReifyType n -> wrapTHResult $ runQuasi $ TH.reifyType n
+ ReifyInstances n ts -> wrapTHResult $ runQuasi $ TH.reifyInstances n ts
+ ReifyRoles n -> wrapTHResult $ runQuasi $ TH.reifyRoles n
ReifyAnnotations lookup tyrep ->
wrapTHResult $ (map B.pack <$> getAnnotationsByTypeRep lookup tyrep)
- ReifyModule m -> wrapTHResult $ TH.qReifyModule m
- ReifyConStrictness nm -> wrapTHResult $ TH.qReifyConStrictness nm
- GetPackageRoot -> wrapTHResult $ TH.qGetPackageRoot
- AddDependentFile f -> wrapTHResult $ TH.qAddDependentFile f
- AddDependentDirectory d -> wrapTHResult $ TH.qAddDependentDirectory d
- AddTempFile s -> wrapTHResult $ TH.qAddTempFile s
+ ReifyModule m -> wrapTHResult $ runQuasi $ TH.reifyModule m
+ ReifyConStrictness nm -> wrapTHResult $ runQuasi $ TH.reifyConStrictness nm
+ GetPackageRoot -> wrapTHResult $ runQuasi $ TH.getPackageRoot
+ AddDependentFile f -> wrapTHResult $ runQuasi $ TH.addDependentFile f
+ AddDependentDirectory d -> wrapTHResult $ runQuasi $ TH.addDependentDirectory d
+ AddTempFile s -> wrapTHResult $ runQuasi $ TH.addTempFile s
AddModFinalizer r -> do
interp <- hscInterp <$> getTopEnv
wrapTHResult $ liftIO (mkFinalizedHValue interp r) >>= addModFinalizerRef
- AddCorePlugin str -> wrapTHResult $ TH.qAddCorePlugin str
- AddTopDecls decs -> wrapTHResult $ TH.qAddTopDecls decs
- AddForeignFilePath lang str -> wrapTHResult $ TH.qAddForeignFilePath lang str
- IsExtEnabled ext -> wrapTHResult $ TH.qIsExtEnabled ext
- ExtsEnabled -> wrapTHResult $ TH.qExtsEnabled
- PutDoc l s -> wrapTHResult $ TH.qPutDoc l s
- GetDoc l -> wrapTHResult $ TH.qGetDoc l
+ AddCorePlugin str -> wrapTHResult $ runQuasi $ TH.addCorePlugin str
+ AddTopDecls decs -> wrapTHResult $ runQuasi $ TH.addTopDecls decs
+ AddForeignFilePath lang str -> wrapTHResult $ runQuasi $ TH.addForeignFilePath lang str
+ IsExtEnabled ext -> wrapTHResult $ runQuasi $ TH.isExtEnabled ext
+ ExtsEnabled -> wrapTHResult $ runQuasi $ TH.extsEnabled
+ PutDoc l s -> wrapTHResult $ runQuasi $ TH.putDoc l s
+ GetDoc l -> wrapTHResult $ runQuasi $ TH.getDoc l
FailIfErrs -> wrapTHResult failIfErrsM
_ -> panic ("handleTHMessage: unexpected message " ++ show msg)
=====================================
libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
=====================================
@@ -59,6 +59,7 @@ import GHC.Internal.TH.Syntax
-----------------------------------------------------
class (MonadIO m, MonadFail m) => Quasi m where
+ qRunQ :: Q a -> m a
-- | Fresh names. See 'newName'.
qNewName :: String -> m Name
@@ -149,6 +150,7 @@ class (MonadIO m, MonadFail m) => Quasi m where
-- type environment, so reification isn't going to
-- work.
instance Quasi IO where
+ qRunQ (Q m) = m id metaHandlersIO
qNewName = newNameIO
qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
@@ -180,9 +182,124 @@ instance Quasi IO where
qGetDoc _ = badIO "getDoc"
qAddDependentDirectory _ = badIO "AddDependentDirectory"
+metaHandlersIO :: MetaHandlers IO
+metaHandlersIO = MetaHandlers {
+ mNewName = newNameIO
+ , mReport = \b msg ->
+ if b then
+ hPutStrLn stderr ("Template Haskell error: " ++ msg)
+ else
+ hPutStrLn stderr ("Template Haskell error: " ++ msg) -- TODO: should this be different from above?
+ , mLookupName = \ _ _ -> badIO "lookupName"
+ , mReify = \_ -> badIO "reify"
+ , mReifyFixity = \_ -> badIO "reifyFixity"
+ , mReifyType = \_ -> badIO "reifyFixity"
+ , mReifyInstances = \_ _ -> badIO "reifyInstances"
+ , mReifyRoles = \_ -> badIO "reifyRoles"
+ , mReifyAnnotations = \_ -> badIO "reifyAnnotations"
+ , mReifyModule = \_ -> badIO "reifyModule"
+ , mReifyConStrictness = \_ -> badIO "reifyConStrictness"
+ , mLocation = badIO "currentLocation"
+ , mRecover = \_ _ -> badIO "recover" -- Maybe we could fix this?
+ , mGetPackageRoot = badIO "getProjectRoot"
+ , mAddDependentFile = \_ -> badIO "addDependentFile"
+ , mAddTempFile = \_ -> badIO "addTempFile"
+ , mAddTopDecls = \_ -> badIO "addTopDecls"
+ , mAddForeignFilePath = \_ _ -> badIO "addForeignFilePath"
+ , mAddModFinalizer = \_ -> badIO "addModFinalizer"
+ , mAddCorePlugin = \_ -> badIO "addCorePlugin"
+ , mGetQ = badIO "getQ"
+ , mPutQ = \_ -> badIO "putQ"
+ , mIsExtEnabled = \_ -> badIO "isExtEnabled"
+ , mExtsEnabled = badIO "extsEnabled"
+ , mPutDoc = \_ _ -> badIO "putDoc"
+ , mGetDoc = \_ -> badIO "getDoc"
+ , mAddDependentDirectory = \_ -> badIO "AddDependentDirectory"
+ }
+
instance Quote IO where
newName = newNameIO
+data MetaHandlers m = MetaHandlers {
+ -- | Fresh names. See 'newName'.
+ mNewName :: String -> m Name
+
+ ------- Error reporting and recovery -------
+ -- | Report an error (True) or warning (False)
+ -- ...but carry on; use 'fail' to stop. See 'report'.
+ , mReport :: Bool -> String -> m ()
+
+ -- | See 'recover'.
+ , mRecover :: forall a. Q a -- ^ the error handler
+ -> Q a -- ^ action which may fail
+ -> m a -- ^ Recover from the monadic 'fail'
+
+ ------- Inspect the type-checker's environment -------
+ -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
+ , mLookupName :: Bool -> String -> m (Maybe Name)
+ -- | See 'reify'.
+ , mReify :: Name -> m Info
+ -- | See 'reifyFixity'.
+ , mReifyFixity :: Name -> m (Maybe Fixity)
+ -- | See 'reifyType'.
+ , mReifyType :: Name -> m Type
+ -- | Is (n tys) an instance? Returns list of matching instance Decs (with
+ -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
+ , mReifyInstances :: Name -> [Type] -> m [Dec]
+ -- | See 'reifyRoles'.
+ , mReifyRoles :: Name -> m [Role]
+ -- | See 'reifyAnnotations'.
+ , mReifyAnnotations :: forall a. Data a => AnnLookup -> m [a]
+ -- | See 'reifyModule'.
+ , mReifyModule :: Module -> m ModuleInfo
+ -- | See 'reifyConStrictness'.
+ , mReifyConStrictness :: Name -> m [DecidedStrictness]
+
+ -- | See 'location'.
+ , mLocation :: m Loc
+
+ -- | See 'getPackageRoot'.
+ , mGetPackageRoot :: m FilePath
+
+ -- | See 'addDependentFile'.
+ , mAddDependentFile :: FilePath -> m ()
+
+ -- | See 'addDependentDirectory'.
+ , mAddDependentDirectory :: FilePath -> m ()
+
+ -- | See 'addTempFile'.
+ , mAddTempFile :: String -> m FilePath
+
+ -- | See 'addTopDecls'.
+ , mAddTopDecls :: [Dec] -> m ()
+
+ -- | See 'addForeignFilePath'.
+ , mAddForeignFilePath :: ForeignSrcLang -> String -> m ()
+
+ -- | See 'addModFinalizer'.
+ , mAddModFinalizer :: Q () -> m ()
+
+ -- | See 'addCorePlugin'.
+ , mAddCorePlugin :: String -> m ()
+
+ -- | See 'getQ'.
+ , mGetQ :: forall a. Typeable a => m (Maybe a)
+
+ -- | See 'putQ'.
+ , mPutQ :: forall a. Typeable a => a -> m ()
+
+ -- | See 'isExtEnabled'.
+ , mIsExtEnabled :: Extension -> m Bool
+ -- | See 'extsEnabled'.
+ , mExtsEnabled :: m [Extension]
+
+ -- | See 'putDoc'.
+ , mPutDoc :: DocLoc -> String -> m ()
+ -- | See 'getDoc'.
+ , mGetDoc :: DocLoc -> m (Maybe String)
+ }
+
+
newNameIO :: String -> IO Name
newNameIO s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x))
; pure (mkNameU s n) }
@@ -213,7 +330,7 @@ counter = unsafePerformIO (newIORef 0)
-- inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle),
-- providing an abstract interface for the user which is later concretely
-- fufilled by an concrete 'Quasi' instance, internal to GHC.
-newtype Q a = Q { unQ :: forall m. Quasi m => m a }
+newtype Q a = Q { unQ :: forall m. (forall x. m x -> IO x) -> MetaHandlers m -> IO a }
-- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
-- should not need this function, as the splice brackets @$( ... )@
@@ -227,22 +344,22 @@ newtype Q a = Q { unQ :: forall m. Quasi m => m a }
-- simply fail at runtime. Indeed, the only operations guaranteed to succeed
-- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
runQ :: Quasi m => Q a -> m a
-runQ (Q m) = m
+runQ = qRunQ
instance Monad Q where
- Q m >>= k = Q (m >>= \x -> unQ (k x))
+ Q m >>= k = Q $ \r h -> (m r h >>= \x -> unQ (k x) r h)
(>>) = (*>)
instance MonadFail Q where
- fail s = report True s >> Q (fail "Q monad failure")
+ fail s = report True s >> Q (\_ _ -> fail "Q monad failure")
instance Functor Q where
- fmap f (Q x) = Q (fmap f x)
+ fmap f (Q x) = Q $ \r h -> fmap f (x r h)
instance Applicative Q where
- pure x = Q (pure x)
- Q f <*> Q x = Q (f <*> x)
- Q m *> Q n = Q (m *> n)
+ pure x = Q $ \_ _ -> pure x
+ Q f <*> Q x = Q $ \r h -> (f r h <*> x r h)
+ Q m *> Q n = Q $ \r h -> (m r h *> n r h)
-- | @since 2.17.0.0
instance Semigroup a => Semigroup (Q a) where
@@ -311,8 +428,17 @@ class Monad m => Quote m where
-}
newName :: String -> m Name
+runHandler :: (forall m. MetaHandlers m -> m a) -> Q a
+runHandler op = Q $ \r h -> r (op h)
+
+runHandler1 :: (forall m. MetaHandlers m -> a -> m b) -> a -> Q b
+runHandler1 op = \x -> Q $ \r h -> r (op h x)
+
+runHandler2 :: (forall m. MetaHandlers m -> a -> b -> m c) -> a -> b -> Q c
+runHandler2 op = \x y -> Q $ \r h -> r (op h x y)
+
instance Quote Q where
- newName s = Q (qNewName s)
+ newName = runHandler1 mNewName
-----------------------------------------------------
--
@@ -510,7 +636,7 @@ joinCode = flip bindCode id
-- | Report an error (True) or warning (False),
-- but carry on; use 'fail' to stop.
report :: Bool -> String -> Q ()
-report b s = Q (qReport b s)
+report b s = runHandler2 mReport b s
{-# DEPRECATED report "Use reportError or reportWarning instead" #-} -- deprecated in 7.6
-- | Report an error to the user, but allow the current splice's computation to carry on. To abort the computation, use 'fail'.
@@ -525,20 +651,20 @@ reportWarning = report False
recover :: Q a -- ^ handler to invoke on failure
-> Q a -- ^ computation to run
-> Q a
-recover (Q r) (Q m) = Q (qRecover r m)
+recover rec main = Q $ \r h -> r $ mRecover h rec main
-- We don't export lookupName; the Bool isn't a great API
-- Instead we export lookupTypeName, lookupValueName
lookupName :: Bool -> String -> Q (Maybe Name)
-lookupName ns s = Q (qLookupName ns s)
+lookupName ns s = runHandler2 mLookupName ns s
-- | Look up the given name in the (type namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
lookupTypeName :: String -> Q (Maybe Name)
-lookupTypeName s = Q (qLookupName True s)
+lookupTypeName s = runHandler2 mLookupName True s
-- | Look up the given name in the (value namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
lookupValueName :: String -> Q (Maybe Name)
-lookupValueName s = Q (qLookupName False s)
+lookupValueName s = runHandler2 mLookupName False s
{-
Note [Name lookup]
@@ -613,7 +739,7 @@ To ensure we get information about @D@-the-value, use 'lookupValueName':
and to get information about @D@-the-type, use 'lookupTypeName'.
-}
reify :: Name -> Q Info
-reify v = Q (qReify v)
+reify v = runHandler1 mReify v
{- | @reifyFixity nm@ attempts to find a fixity declaration for @nm@. For
example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then
@@ -622,7 +748,7 @@ example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then
'Nothing', so you may assume @bar@ has 'defaultFixity'.
-}
reifyFixity :: Name -> Q (Maybe Fixity)
-reifyFixity nm = Q (qReifyFixity nm)
+reifyFixity nm = runHandler1 mReifyFixity nm
{- | @reifyType nm@ attempts to find the type or kind of @nm@. For example,
@reifyType 'not@ returns @Bool -> Bool@, and
@@ -630,7 +756,7 @@ reifyFixity nm = Q (qReifyFixity nm)
This works even if there's no explicit signature and the type or kind is inferred.
-}
reifyType :: Name -> Q Type
-reifyType nm = Q (qReifyType nm)
+reifyType nm = runHandler1 mReifyType nm
{- | Template Haskell is capable of reifying information about types and
terms defined in previous declaration groups. Top-level declaration splices break up
@@ -722,7 +848,7 @@ has some discussion around this.
-}
reifyInstances :: Name -> [Type] -> Q [InstanceDec]
-reifyInstances cls tys = Q (qReifyInstances cls tys)
+reifyInstances cls tys = runHandler2 mReifyInstances cls tys
{- | @reifyRoles nm@ returns the list of roles associated with the parameters
(both visible and invisible) of
@@ -741,20 +867,20 @@ and @reifyRoles Proxy@, we will get @['NominalR', 'PhantomR']@. The 'NominalR' i
the role of the invisible @k@ parameter. Kind parameters are always nominal.
-}
reifyRoles :: Name -> Q [Role]
-reifyRoles nm = Q (qReifyRoles nm)
+reifyRoles nm = runHandler1 mReifyRoles nm
-- | @reifyAnnotations target@ returns the list of annotations
-- associated with @target@. Only the annotations that are
-- appropriately typed is returned. So if you have @Int@ and @String@
-- annotations for the same target, you have to call this function twice.
reifyAnnotations :: Data a => AnnLookup -> Q [a]
-reifyAnnotations an = Q (qReifyAnnotations an)
+reifyAnnotations an = runHandler1 mReifyAnnotations an
-- | @reifyModule mod@ looks up information about module @mod@. To
-- look up the current module, call this function with the return
-- value of 'Language.Haskell.TH.Lib.thisModule'.
reifyModule :: Module -> Q ModuleInfo
-reifyModule m = Q (qReifyModule m)
+reifyModule m = runHandler1 mReifyModule m
-- | @reifyConStrictness nm@ looks up the strictness information for the fields
-- of the constructor with the name @nm@. Note that the strictness information
@@ -769,7 +895,7 @@ reifyModule m = Q (qReifyModule m)
-- circumstances, but it would return @['DecidedStrict', DecidedStrict]@ if the
-- @-XStrictData@ language extension was enabled.
reifyConStrictness :: Name -> Q [DecidedStrictness]
-reifyConStrictness n = Q (qReifyConStrictness n)
+reifyConStrictness n = runHandler1 mReifyConStrictness n
-- | Is the list of instances returned by 'reifyInstances' nonempty?
--
@@ -782,7 +908,7 @@ isInstance nm tys = do { decs <- reifyInstances nm tys
-- | The location at which this computation is spliced.
location :: Q Loc
-location = Q qLocation
+location = runHandler mLocation
-- |The 'runIO' function lets you run an I\/O computation in the 'Q' monad.
-- Take care: you are guaranteed the ordering of calls to 'runIO' within
@@ -792,7 +918,7 @@ location = Q qLocation
-- necessarily flushed when the compiler finishes running, so you should
-- flush them yourself.
runIO :: IO a -> Q a
-runIO m = Q (qRunIO m)
+runIO m = Q $ \_ _ -> m
-- | Get the package root for the current package which is being compiled.
-- This can be set explicitly with the -package-root flag but is normally
@@ -804,7 +930,7 @@ runIO m = Q (qRunIO m)
-- change directory when compiling files but instead set the -package-root flag
-- appropriately.
getPackageRoot :: Q FilePath
-getPackageRoot = Q qGetPackageRoot
+getPackageRoot = runHandler mGetPackageRoot
-- | Record external directories that runIO is using (dependent upon).
-- The compiler can then recognize that it should re-compile the Haskell file
@@ -823,7 +949,7 @@ getPackageRoot = Q qGetPackageRoot
-- * The state of the directory is read at the interface generation time,
-- not at the time of the function call.
addDependentDirectory :: FilePath -> Q ()
-addDependentDirectory dp = Q (qAddDependentDirectory dp)
+addDependentDirectory dp = runHandler1 mAddDependentDirectory dp
-- | Record external files that runIO is using (dependent upon).
-- The compiler can then recognize that it should re-compile the Haskell file
@@ -837,17 +963,17 @@ addDependentDirectory dp = Q (qAddDependentDirectory dp)
--
-- * The dependency is based on file content, not a modification time
addDependentFile :: FilePath -> Q ()
-addDependentFile fp = Q (qAddDependentFile fp)
+addDependentFile fp = runHandler1 mAddDependentFile fp
-- | Obtain a temporary file path with the given suffix. The compiler will
-- delete this file after compilation.
addTempFile :: String -> Q FilePath
-addTempFile suffix = Q (qAddTempFile suffix)
+addTempFile suffix = runHandler1 mAddTempFile suffix
-- | Add additional top-level declarations. The added declarations will be type
-- checked along with the current declaration group.
addTopDecls :: [Dec] -> Q ()
-addTopDecls ds = Q (qAddTopDecls ds)
+addTopDecls ds = runHandler1 mAddTopDecls ds
-- | Same as 'addForeignSource', but expects to receive a path pointing to the
-- foreign file instead of a 'String' of its contents. Consider using this in
@@ -856,7 +982,7 @@ addTopDecls ds = Q (qAddTopDecls ds)
-- This is a good alternative to 'addForeignSource' when you are trying to
-- directly link in an object file.
addForeignFilePath :: ForeignSrcLang -> FilePath -> Q ()
-addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp)
+addForeignFilePath lang fp = runHandler2 mAddForeignFilePath lang fp
-- | Add a finalizer that will run in the Q monad after the current module has
-- been type checked. This only makes sense when run within a top-level splice.
@@ -865,7 +991,7 @@ addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp)
-- 'reify' is able to find the local definitions when executed inside the
-- finalizer.
addModFinalizer :: Q () -> Q ()
-addModFinalizer act = Q (qAddModFinalizer (unQ act))
+addModFinalizer act = runHandler1 mAddModFinalizer act
-- | Adds a core plugin to the compilation pipeline.
--
@@ -875,7 +1001,7 @@ addModFinalizer act = Q (qAddModFinalizer (unQ act))
-- to tell the compiler that we needed to compile first a plugin module in the
-- current package.
addCorePlugin :: String -> Q ()
-addCorePlugin plugin = Q (qAddCorePlugin plugin)
+addCorePlugin plugin = runHandler1 mAddCorePlugin plugin
-- | Get state from the 'Q' monad. The state maintained by 'Q' is isomorphic to
-- a type-indexed finite map. That is,
@@ -889,20 +1015,20 @@ addCorePlugin plugin = Q (qAddCorePlugin plugin)
-- Note that the state is local to the Haskell module in which the Template
-- Haskell expression is executed.
getQ :: Typeable a => Q (Maybe a)
-getQ = Q qGetQ
+getQ = runHandler mGetQ
-- | Replace the state in the 'Q' monad. Note that the state is local to the
-- Haskell module in which the Template Haskell expression is executed.
putQ :: Typeable a => a -> Q ()
-putQ x = Q (qPutQ x)
+putQ x = runHandler1 mPutQ x
-- | Determine whether the given language extension is enabled in the 'Q' monad.
isExtEnabled :: Extension -> Q Bool
-isExtEnabled ext = Q (qIsExtEnabled ext)
+isExtEnabled ext = runHandler1 mIsExtEnabled ext
-- | List all enabled language extensions.
extsEnabled :: Q [Extension]
-extsEnabled = Q qExtsEnabled
+extsEnabled = runHandler mExtsEnabled
-- | Add Haddock documentation to the specified location. This will overwrite
-- any documentation at the location if it already exists. This will reify the
@@ -921,19 +1047,20 @@ extsEnabled = Q qExtsEnabled
-- Adding documentation to anything outside of the current module will cause an
-- error.
putDoc :: DocLoc -> String -> Q ()
-putDoc t s = Q (qPutDoc t s)
+putDoc t s = runHandler2 mPutDoc t s
-- | Retrieves the Haddock documentation at the specified location, if one
-- exists.
-- It can be used to read documentation on things defined outside of the current
-- module, provided that those modules were compiled with the @-haddock@ flag.
getDoc :: DocLoc -> Q (Maybe String)
-getDoc n = Q (qGetDoc n)
+getDoc n = runHandler1 mGetDoc n
instance MonadIO Q where
liftIO = runIO
instance Quasi Q where
+ qRunQ = id
qNewName = newName
qReport = report
qRecover = recover
=====================================
libraries/ghci/GHCi/TH.hs
=====================================
@@ -163,56 +163,67 @@ ghcCmd m = GHCiQ $ \s -> do
instance MonadIO GHCiQ where
liftIO m = GHCiQ $ \s -> fmap (,s) m
-instance TH.Quasi GHCiQ where
- qNewName str = ghcCmd (NewName str)
- qReport isError msg = ghcCmd (Report isError msg)
-
- -- See Note [TH recover with -fexternal-interpreter] in GHC.Tc.Gen.Splice
- qRecover (GHCiQ h) a = GHCiQ $ \s -> mask $ \unmask -> do
- remoteTHCall (qsPipe s) StartRecover
- e <- try $ unmask $ runGHCiQ (a <* ghcCmd FailIfErrs) s
- remoteTHCall (qsPipe s) (EndRecover (isLeft e))
- case e of
- Left GHCiQException{} -> h s
- Right r -> return r
- qLookupName isType occ = ghcCmd (LookupName isType occ)
- qReify name = ghcCmd (Reify name)
- qReifyFixity name = ghcCmd (ReifyFixity name)
- qReifyType name = ghcCmd (ReifyType name)
- qReifyInstances name tys = ghcCmd (ReifyInstances name tys)
- qReifyRoles name = ghcCmd (ReifyRoles name)
-
-- To reify annotations, we send GHC the AnnLookup and also the
-- TypeRep of the thing we're looking for, to avoid needing to
-- serialize irrelevant annotations.
- qReifyAnnotations :: forall a . Data a => TH.AnnLookup -> GHCiQ [a]
- qReifyAnnotations lookup =
+reifyAnnotations :: forall a . Data a => TH.AnnLookup -> GHCiQ [a]
+reifyAnnotations lookup =
map (deserializeWithData . B.unpack) <$>
ghcCmd (ReifyAnnotations lookup typerep)
where typerep = typeOf (undefined :: a)
- qReifyModule m = ghcCmd (ReifyModule m)
- qReifyConStrictness name = ghcCmd (ReifyConStrictness name)
- qLocation = fromMaybe noLoc . qsLocation <$> getState
- qGetPackageRoot = ghcCmd GetPackageRoot
- qAddDependentFile file = ghcCmd (AddDependentFile file)
- qAddDependentDirectory dir = ghcCmd (AddDependentDirectory dir)
- qAddTempFile suffix = ghcCmd (AddTempFile suffix)
- qAddTopDecls decls = ghcCmd (AddTopDecls decls)
- qAddForeignFilePath lang fp = ghcCmd (AddForeignFilePath lang fp)
- qAddModFinalizer fin = GHCiQ (\s -> mkRemoteRef fin >>= return . (, s)) >>=
+-- TODO: !!!
+-- This is wrong because it will discard any updates to the state.
+-- What I should do instead is refactor GHCiQ first (!) to use an IORef for state, and then save/restore that.
+runQinGHCiQ :: TH.Q a -> GHCiQ a
+runQinGHCiQ (TH.Q m) = GHCiQ $ \s -> (,s) <$> m (runInIO s) metaHandlersGHCiQ
+ where
+ runInIO :: QState -> GHCiQ a -> IO a
+ runInIO s (GHCiQ m) = fst <$> m s
+
+metaHandlersGHCiQ = TH.MetaHandlers {
+ mNewName = \str -> ghcCmd (NewName str)
+ , mReport = \isError msg -> ghcCmd (Report isError msg)
+
+ -- See Note [TH recover with -fexternal-interpreter] in GHC.Tc.Gen.Splice
+ , mRecover = \h a -> GHCiQ $ \s -> mask $ \unmask -> do
+ remoteTHCall (qsPipe s) StartRecover
+ e <- try $ unmask $ runGHCiQ (runQinGHCiQ a <* ghcCmd FailIfErrs) s -- TODO: simplify
+ remoteTHCall (qsPipe s) (EndRecover (isLeft e))
+ case e of
+ Left GHCiQException{} -> runGHCiQ (runQinGHCiQ h) s -- TODO: simplify
+ Right r -> return r
+ , mLookupName = \isType occ -> ghcCmd (LookupName isType occ)
+ , mReify = \name -> ghcCmd (Reify name)
+ , mReifyFixity = \name -> ghcCmd (ReifyFixity name)
+ , mReifyType = \name -> ghcCmd (ReifyType name)
+ , mReifyInstances = \name tys -> ghcCmd (ReifyInstances name tys)
+ , mReifyRoles = \name -> ghcCmd (ReifyRoles name)
+
+ , mReifyAnnotations = reifyAnnotations
+ , mReifyModule = \m -> ghcCmd (ReifyModule m)
+ , mReifyConStrictness = \name -> ghcCmd (ReifyConStrictness name)
+ , mLocation = fromMaybe noLoc . qsLocation <$> getState
+ , mGetPackageRoot = ghcCmd GetPackageRoot
+ , mAddDependentFile = \file -> ghcCmd (AddDependentFile file)
+ , mAddDependentDirectory = \dir -> ghcCmd (AddDependentDirectory dir)
+ , mAddTempFile = \suffix -> ghcCmd (AddTempFile suffix)
+ , mAddTopDecls = \decls -> ghcCmd (AddTopDecls decls)
+ , mAddForeignFilePath = \lang fp -> ghcCmd (AddForeignFilePath lang fp)
+ , mAddModFinalizer = \fin -> GHCiQ (\s -> mkRemoteRef fin >>= return . (, s)) >>=
ghcCmd . AddModFinalizer
- qAddCorePlugin str = ghcCmd (AddCorePlugin str)
- qGetQ = GHCiQ $ \s ->
+ , mAddCorePlugin = \str -> ghcCmd (AddCorePlugin str)
+ , mGetQ = GHCiQ $ \s ->
let lookup :: forall a. Typeable a => Map TypeRep Dynamic -> Maybe a
lookup m = fromDynamic =<< M.lookup (typeOf (undefined::a)) m
in return (lookup (qsMap s), s)
- qPutQ k = GHCiQ $ \s ->
+ , mPutQ = \k -> GHCiQ $ \s ->
return ((), s { qsMap = M.insert (typeOf k) (toDyn k) (qsMap s) })
- qIsExtEnabled x = ghcCmd (IsExtEnabled x)
- qExtsEnabled = ghcCmd ExtsEnabled
- qPutDoc l s = ghcCmd (PutDoc l s)
- qGetDoc l = ghcCmd (GetDoc l)
+ , mIsExtEnabled = \x -> ghcCmd (IsExtEnabled x)
+ , mExtsEnabled = ghcCmd ExtsEnabled
+ , mPutDoc = \l s -> ghcCmd (PutDoc l s)
+ , mGetDoc = \l -> ghcCmd (GetDoc l)
+}
-- | The implementation of the 'StartTH' message: create
-- a new IORef QState, and return a RemoteRef to it.
@@ -231,7 +242,7 @@ runModFinalizerRefs pipe rstate qrefs = do
qs <- mapM localRef qrefs
qstateref <- localRef rstate
qstate <- readIORef qstateref
- _ <- runGHCiQ (TH.runQ $ sequence_ qs) qstate { qsPipe = pipe }
+ _ <- runGHCiQ (runQinGHCiQ $ sequence_ qs) qstate { qsPipe = pipe }
return ()
-- | The implementation of the 'RunTH' message
@@ -269,6 +280,6 @@ runTHQ pipe rstate mb_loc ghciq = do
qstateref <- localRef rstate
qstate <- readIORef qstateref
let st = qstate { qsLocation = mb_loc, qsPipe = pipe }
- (r,new_state) <- runGHCiQ (TH.runQ ghciq) st
+ (r,new_state) <- runGHCiQ (runQinGHCiQ ghciq) st
writeIORef qstateref new_state
return $! LB.toStrict (runPut (put r))
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/857149f67c75bf2a4fd2b59f377526…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/857149f67c75bf2a4fd2b59f377526…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Apoorv Ingle pushed to branch wip/ani/tc-expand at Glasgow Haskell Compiler / GHC
Commits:
3b036900 by Apoorv Ingle at 2026-03-13T18:34:40-05:00
wibbles
- - - - -
3 changed files:
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
Changes:
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -14,7 +14,7 @@ module GHC.Tc.Gen.App
, tcExprSigma
, tcExprPrag ) where
-import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcPolyExpr )
+import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcPolyLExprNC )
import GHC.Hs
@@ -570,7 +570,7 @@ tcValArg do_ql _ _ (EWrap (EHsWrap w)) = do { whenQL do_ql $ qlMonoHsWrapper w
tcValArg _ _ _ (EWrap ew) = return (EWrap ew)
tcValArg do_ql pos (fun, fun_lspan) (EValArg { ea_loc_span = lspan
- , ea_arg = larg@(L arg_loc arg)
+ , ea_arg = larg@(L arg_loc _)
, ea_arg_ty = sc_arg_ty })
= addArgCtxt pos (fun, fun_lspan) larg $
do { -- Crucial step: expose QL results before checking exp_arg_ty
@@ -596,11 +596,11 @@ tcValArg do_ql pos (fun, fun_lspan) (EValArg { ea_loc_span = lspan
-- Now check the argument
; arg' <- tcScalingUsage mult $
- tcPolyExpr arg (mkCheckExpType exp_arg_ty)
+ tcPolyLExprNC larg (mkCheckExpType exp_arg_ty)
; traceTc "tcValArg" $ vcat [ ppr arg'
, text "}" ]
; return (EValArg { ea_loc_span = lspan
- , ea_arg = L arg_loc arg'
+ , ea_arg = arg'
, ea_arg_ty = noExtField }) }
tcValArg _ pos (fun, fun_lspan) (EValArgQL {
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -123,30 +123,11 @@ tcPolyLExpr, tcPolyLExprNC :: LHsExpr GhcRn -> ExpSigmaType
tcPolyLExpr (L loc expr) res_ty
= addLExprCtxt (locA loc) expr $ -- Note [Error contexts in generated code]
- do { (L loc' expanded_expr, mb_ret_ty, ctxt, did_expand) <- tcExpandLExpr loc expr res_ty
- ; e <-
- mb_add_xexpr_wrap (ExprCtxt expr) did_expand $ mb_add_ctxt ctxt (locA loc') expanded_expr $
- case mb_ret_ty of
- Nothing -> tcPolyExpr expanded_expr res_ty
- Just ds_res_ty -> do expr' <- tcPolyExpr expanded_expr (Check ds_res_ty)
- tcWrapResult expr expr' ds_res_ty res_ty
- ; return (L loc' e)
- }
- where
- mb_add_ctxt :: Maybe HsCtxt -> SrcSpan -> HsExpr GhcRn -> TcM a -> TcM a
- mb_add_ctxt Nothing _ _ thing_inside
- = thing_inside
- mb_add_ctxt (Just ctxt) loc expanded_expr thing_inside
- = addExpansionErrCtxt ctxt $
- addLExprCtxt loc expanded_expr $
- thing_inside
-
- mb_add_xexpr_wrap :: HsCtxt -> Bool -> TcM (HsExpr GhcTc) -> TcM (HsExpr GhcTc)
- mb_add_xexpr_wrap hs_ctxt True thing_inside = mkExpandedTc hs_ctxt <$> setInGeneratedCode thing_inside
- mb_add_xexpr_wrap _ False thing_inside = thing_inside
+ tcPolyLExprNC (L loc expr) res_ty
tcPolyLExprNC (L loc expr) res_ty
- = do { (L loc' expanded_expr, mb_ret_ty, ctxt, did_expand) <- tcExpandLExpr loc expr res_ty
+ = setSrcSpanA loc $
+ do { (L loc' expanded_expr, mb_ret_ty, ctxt, did_expand) <- tcExpandLExpr loc expr res_ty
; e <-
mb_add_xexpr_wrap (ExprCtxt expr) did_expand $ mb_add_ctxt ctxt (locA loc') expanded_expr $
case mb_ret_ty of
@@ -313,30 +294,11 @@ tcMonoLExpr, tcMonoLExprNC
tcMonoLExpr (L loc expr) res_ty
= addLExprCtxt (locA loc) expr $ -- Note [Error contexts in generated code]
- do { (L loc' expanded_expr, mb_ret_ty, ctxt, did_expand) <- tcExpandLExpr loc expr res_ty
- ; e <-
- mb_add_xexpr_wrap (ExprCtxt expr) did_expand $ mb_add_ctxt ctxt (locA loc') expanded_expr $
- case mb_ret_ty of
- Nothing -> tcExpr expanded_expr res_ty
- Just ds_res_ty -> do expr' <- tcExpr expanded_expr (Check ds_res_ty)
- tcWrapResultMono expr expr' ds_res_ty res_ty
- ; return (L loc' e)
- }
- where
- mb_add_ctxt :: Maybe HsCtxt -> SrcSpan -> HsExpr GhcRn -> TcM a -> TcM a
- mb_add_ctxt Nothing _ _ thing_inside
- = thing_inside
- mb_add_ctxt (Just ctxt) loc expanded_expr thing_inside
- = addExpansionErrCtxt ctxt $
- addLExprCtxt loc expanded_expr $
- thing_inside
-
- mb_add_xexpr_wrap :: HsCtxt -> Bool -> TcM (HsExpr GhcTc) -> TcM (HsExpr GhcTc)
- mb_add_xexpr_wrap hs_ctxt True thing_inside = mkExpandedTc hs_ctxt <$> setInGeneratedCode thing_inside
- mb_add_xexpr_wrap _ False thing_inside = thing_inside
+ tcMonoLExprNC (L loc expr) res_ty
tcMonoLExprNC (L loc expr) res_ty
- = do { (L loc' expanded_expr, mb_ret_ty, ctxt, did_expand) <- tcExpandLExpr loc expr res_ty
+ = setSrcSpanA loc $
+ do { (L loc' expanded_expr, mb_ret_ty, ctxt, did_expand) <- tcExpandLExpr loc expr res_ty
; e <-
mb_add_xexpr_wrap (ExprCtxt expr) did_expand $ mb_add_ctxt ctxt (locA loc') expanded_expr $
case mb_ret_ty of
=====================================
compiler/GHC/Tc/Gen/Expr.hs-boot
=====================================
@@ -24,7 +24,7 @@ tcCheckMonoExpr, tcCheckMonoExprNC ::
-> TcRhoType
-> TcM (LHsExpr GhcTc)
-tcPolyLExpr :: LHsExpr GhcRn -> ExpSigmaType -> TcM (LHsExpr GhcTc)
+tcPolyLExpr, tcPolyLExprNC :: LHsExpr GhcRn -> ExpSigmaType -> TcM (LHsExpr GhcTc)
tcPolyLExprSig :: LHsExpr GhcRn -> TcCompleteSig -> TcM (LHsExpr GhcTc)
tcPolyExpr :: HsExpr GhcRn -> ExpSigmaType -> TcM (HsExpr GhcTc)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b036900b32dfa9aab96a2da22ac7ee…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b036900b32dfa9aab96a2da22ac7ee…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Apoorv Ingle pushed new branch wip/ani/tc-expand at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ani/tc-expand
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T23246] 52 commits: wasm: add /assets endpoint to serve user-specified assets
by Peter Trommler (@trommler) 13 Mar '26
by Peter Trommler (@trommler) 13 Mar '26
13 Mar '26
Peter Trommler pushed to branch wip/T23246 at Glasgow Haskell Compiler / GHC
Commits:
c951fef1 by Cheng Shao at 2026-02-25T20:58:28+00:00
wasm: add /assets endpoint to serve user-specified assets
This patch adds an `/assets` endpoint to the wasm dyld http server, so
that users can also fetch assets from the same host with sensible
default MIME types, without needing a separate http server for assets
that also introduces CORS headaches:
- A `-fghci-browser-assets-dir` driver flag is added to specify the
assets root directory (defaults to `$PWD`)
- The dyld http server fetches `mime-db` on demand and uses it as
source of truth for mime types.
Closes #26951.
- - - - -
dde22f97 by Sylvain Henry at 2026-02-26T13:14:03-05:00
Fix -fcheck-prim-bounds for non constant args (#26958)
Previously we were only checking bounds for constant (literal)
arguments!
I've refactored the code to simplify the generation of out-of-line Cmm
code for the primop composed of some inline code + some call to an
external Cmm function.
- - - - -
bd3eba86 by Vladislav Zavialov at 2026-02-27T05:48:01-05:00
Check for negative type literals in the type checker (#26861)
GHC disallows negative type literals (e.g., -1), as tested by T8306 and
T8412. This check is currently performed in the renamer:
rnHsTyLit tyLit@(HsNumTy x i) = do
when (i < 0) $
addErr $ TcRnNegativeNumTypeLiteral tyLit
However, this check can be bypassed using RequiredTypeArguments
(see the new test case T26861). Prior to this patch, such programs
caused the compiler to hang instead of reporting a proper error.
This patch addresses the issue by adding an equivalent check in
the type checker, namely in tcHsType.
The diff is deliberately minimal to facilitate backporting. A more
comprehensive rework of HsTyLit is planned for a separate commit.
- - - - -
faf14e0c by Vladislav Zavialov at 2026-02-27T05:48:45-05:00
Consistent pretty-printing of HsString, HsIsString, HsStrTy
Factor out a helper to pretty-print string literals, thus fixing newline
handling for overloaded string literals and type literals.
Test cases: T26860ppr T26860ppr_overloaded T26860ppr_tylit
Follow up to ddf1434ff9bb08cfef3c93f23de6b83ec698aa27
- - - - -
f108a972 by Arnaud Spiwack at 2026-02-27T12:53:01-05:00
Make list comprehension completely non-linear
Fixes #25081
From the note:
The usefulness of list comprehension in conjunction with linear types is dubious.
After all, statements are made to be run many times, for instance in
```haskell
[u | y <- [0,1], stmts]
```
both `u` and `stmts` are going to be run several times.
In principle, though, there are some position in a monad comprehension
expression which could be considered linear. We could try and make it so that
these positions are considered linear by the typechecker, but in practice the
desugarer doesn't take enough care to ensure that these are indeed desugared to
linear sites. We tried in the past, and it turned out that we'd miss a
desugaring corner case (#25772).
Until there's a demand for this very specific improvement, let's instead be
conservative, and consider list comprehension to be completely non-linear.
- - - - -
ae799cab by Simon Jakobi at 2026-02-27T12:53:54-05:00
PmAltConSet: Use Data.Set instead of Data.Map
...to store `PmLit`s.
The Map was only used to map keys to themselves.
Changing the Map to a Set saves a Word of memory per entry.
Resolves #26756.
- - - - -
dcd7819c by Vladislav Zavialov at 2026-02-27T18:46:03-05:00
Drop HsTyLit in favor of HsLit (#26862, #25121)
This patch is a small step towards unification of HsExpr and HsType,
taking care of literals (HsLit) and type literals (HsTyLit).
Additionally, it improves error messages for unsupported type literals,
such as unboxed or fractional literals (test cases: T26862, T26862_th).
Changes to the AST:
* Use HsLit where HsTyLit was previously used
* Use HsChar where HsCharTy was previously used
* Use HsString where HsStrTy was previously used
* Use HsNatural (NEW) where HsNumTy was previously used
* Use HsDouble (NEW) to represent unsupported fractional type literals
Changes to logic:
* Parse unboxed and fractional type literals (to be rejected later)
* Drop the check for negative literals in the renamer (rnHsTyLit)
in favor of checking in the type checker (tc_hs_lit_ty)
* Check for invalid type literals in TH (repTyLit) and report
unrepresentable literals with ThUnsupportedTyLit
* Allow negative type literals in TH (numTyLit). This is fine as
these will be taken care of at splice time (test case: T8306_th)
- - - - -
c927954f by Vladislav Zavialov at 2026-02-27T18:46:50-05:00
Increase test coverage of diagnostics
Add test cases for the previously untested diagnostics:
[GHC-01239] PsErrIfInFunAppExpr
[GHC-04807] PsErrProcInFunAppExpr
[GHC-08195] PsErrInvalidRecordCon
[GHC-16863] PsErrUnsupportedBoxedSumPat
[GHC-18910] PsErrSemiColonsInCondCmd
[GHC-24737] PsErrInvalidWhereBindInPatSynDecl
[GHC-25037] PsErrCaseInFunAppExpr
[GHC-25078] PsErrPrecedenceOutOfRange
[GHC-28021] PsErrRecordSyntaxInPatSynDecl
[GHC-35827] TcRnNonOverloadedSpecialisePragma
[GHC-40845] PsErrUnpackDataCon
[GHC-45106] PsErrInvalidInfixHole
[GHC-50396] PsErrInvalidRuleActivationMarker
[GHC-63930] MultiWayIfWithoutAlts
[GHC-65536] PsErrNoSingleWhereBindInPatSynDecl
[GHC-67630] PsErrMDoInFunAppExpr
[GHC-70526] PsErrLetCmdInFunAppCmd
[GHC-77808] PsErrDoCmdInFunAppCmd
[GHC-86934] ClassPE
[GHC-90355] PsErrLetInFunAppExpr
[GHC-91745] CasesExprWithoutAlts
[GHC-92971] PsErrCaseCmdInFunAppCmd
[GHC-95644] PsErrBangPatWithoutSpace
[GHC-97005] PsErrIfCmdInFunAppCmd
Remove unused error constructors:
[GHC-44524] PsErrExpectedHyphen
[GHC-91382] TcRnIllegalKindSignature
- - - - -
3a9470fd by Torsten Schmits at 2026-02-27T18:47:34-05:00
Avoid expensive computation for debug logging in `mergeDatabases` when log level is low
This computed and traversed a set intersection for every single
dependency unconditionally.
- - - - -
ea4c2cbd by Brandon Chinn at 2026-02-27T16:22:38-08:00
Implement QualifiedStrings (#26503)
See Note [Implementation of QualifiedStrings]
- - - - -
08bc245b by sheaf at 2026-03-01T11:11:54-05:00
Clean up join points, casts & ticks
This commit shores up the logic dealing with casts and ticks occurring
in between a join point binding and a jump.
Fixes #26642 #26929 #26693
Makes progress on #14610 #26157 #26422
Changes:
- Remove 'GHC.Types.Tickish.TickishScoping' in favour of simpler
predicates 'tickishHasNoScope'/'tickishHasSoftScope', as things were
before commit 993975d3. This makes the code easier to read and
document (fewer indirections).
- Introduce 'canCollectArgsThroughTick' for consistent handling of
ticks around PrimOps and other 'Id's that cannot be eta-reduced.
See overhauled Note [Ticks and mandatory eta expansion].
- New Note [JoinId vs TailCallInfo] in GHC.Core.SimpleOpt that explains
robustness of JoinId vs fragility of TailCallInfo.
- Allow casts/non-soft-scoped ticks to occur in between a join point
binder and a jump, but only in Core Prep.
See Note [Join points, casts, and ticks] and
Note [Join points, casts, and ticks... in Core Prep]
in GHC.Core.Opt.Simplify.Iteration.
Also update Core Lint to account for this.
See Note [Linting join points with casts or ticks] in GHC.Core.Lint.
- Update 'GHC.Core.Utils.mergeCaseAlts' to avoid pushing a cast in
between a join point binding and its jumps. This fixes #26642.
See the new (MC5) and (MC6) in Note [Merge Nested Cases].
- Update float out to properly handle source note ticks. They are now
properly floated out instead of being discarded.
This increases the number of ticks in certain tests with -g.
Test cases: T26642 and TrickyJoins.
Metric increase due to more source note ticks with -g:
-------------------------
Metric Increase:
libdir
size_hello_artifact
size_hello_unicode
-------------------------
- - - - -
476c4cdf by Sean D. Gillespie at 2026-03-02T10:14:37-05:00
Add SIMD absolute value on x86 and LLVM
On x86, absolute value of 32 bits or less is implemented with
PABSB/PABSW/PABSD if SSSE3 is available. Otherwise, there is a fallback
for SSE2. For 64 bit integers it uses VPABSQ, required by AVX-512VL,
with fallbacks for SSE4.2 and SSE2.
There is no dedicated instruction for floating point absolute value on
x86, so it is simulated using bitwise AND.
Absolute value for signed integers and floats are implemented by the
"llvm.abs/llvm.fabs" standard library intrinsics. This implementation
uses MachOps constructors, unlike non-vector floating point absolute
value, which uses CallishMachOps.
- - - - -
709448c0 by Sean D. Gillespie at 2026-03-02T10:14:46-05:00
Add SIMD floating point square root
On x86, this is implemented with the SQRTPS and SQRTPD instructions. On
LLVM, it uses the sqrt library intrinstic.
- - - - -
0deadf66 by Sean D. Gillespie at 2026-03-02T10:14:47-05:00
Improve error message for SIMD on aarch64
When encountering vector literals on aarch64, previously it would
throw:
<no location info>: error:
panic! (the 'impossible' happened)
GHC version 9.15.20251219:
getRegister' (CmmLit:CmmVec):
Now it is more consistent with the other vector operations:
<no location info>: error:
sorry! (unimplemented feature or known bug)
GHC version 9.15.20251219:
SIMD operations on AArch64 currently require the LLVM backend
- - - - -
7d64031b by Vladislav Zavialov at 2026-03-03T11:09:28-05:00
Replace maybeAddSpace with spaceIfSingleQuote
Simplify pretty-printing of HsTypes by using spaceIfSingleQuote.
This allows us to drop the unwieldy lhsTypeHasLeadingPromotionQuote
helper function.
Follow-up to 178c1fd830c78377ef5d338406a41e1d8eb5f0da
- - - - -
598db847 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Correct `hIsReadable` and `hIsWritable` for duplex handles
This contribution implements CLC proposal #371. It changes `hIsReadable`
and `hIsWritable` such that they always throw a respective exception
when encountering a closed or semi-closed handle, not just in the case
of a file handle.
- - - - -
b90201e5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Document `SemiClosedHandle`
- - - - -
c9df72b5 by Wolfgang Jeltsch at 2026-03-06T06:25:25-05:00
Tell users what “semi-closed” means for duplex handles
- - - - -
a8aa1868 by Ilias Tsitsimpis at 2026-03-06T06:26:29-05:00
Fix determinism of linker arguments
The switch from Data.Map to UniqMap in 3b5be05ac29 introduced
non-determinism in the order of packages passed to the linker.
This resulted in non-reproducible builds where the DT_NEEDED entries in
dynamic libraries were ordered differently across builds.
Fix the regression by explicitly sorting the package list derived from
UniqMap.
Fixes #26838
- - - - -
9b64ad3a by Matthew Pickering at 2026-03-06T06:27:16-05:00
determinism: Use a deterministic renaming when writing bytecode files
Now when writing the bytecode file, a counter and substitution are used
to provide deterministic keys to local variables (rather than relying on
uniques). This change ensures that `.gbc` are produced
deterministically.
Fixes #26499
- - - - -
d29800e0 by Teo Camarasu at 2026-03-06T06:28:46-05:00
ghc-internal: delete Version hs-boot loop
Version has a Read instance which needs Unicode but part of the Unicode interface is the unicode version. This is easy to resolve. We simply don't re-export the version from the Unicode module.
Resolves #26940
- - - - -
ad25af90 by Sylvain Henry at 2026-03-06T06:30:33-05:00
Linker: implement support for COMMON symbols (#6107)
Add some support for COMMON symbols. We don't support common symbols
having different sizes where the larger one is allocated after the
smaller one. The linker will fail with an appropriate error message if
it happens.
- - - - -
3b59f158 by Cheng Shao at 2026-03-06T06:31:16-05:00
compiler: fix redundant import of GHC.Hs.Lit
This patch removes a redundant import of `GHC.Hs.Lit` which causes a
ghc build failure with validate flavours when bootstrapping from 9.14.
Fixes #26972.
- - - - -
148d36f3 by Cheng Shao at 2026-03-06T06:32:01-05:00
compiler: avoid unneeded traversals in GHC.Unit.State
Following !15591, this patch avoids unneeded traversals in
`reportCycles`/`reportUnusable` when log verbosity is below given
threshold. Also applies `logVerbAtLeast` when appropriate.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
7e31367c by Cheng Shao at 2026-03-06T06:32:46-05:00
ghc-internal: fix redundant import in GHC.Internal.Event.Windows.ManagedThreadPool
This patch fixes redundant import in
`GHC.Internal.Event.Windows.ManagedThreadPool` that causes a
compilation error when building windows target with validate flavours
and bootstrapping from 9.14. Fixes #26976.
- - - - -
fc8b8e27 by sheaf at 2026-03-06T06:33:28-05:00
System.Info.fullCompilerVersion: add 'since' annot
Fixes #26973
- - - - -
c8238375 by Sylvain Henry at 2026-03-06T06:34:23-05:00
Hadrian: deprecate --bignum and automatically enable +native_bignum for JS
Deprecate --bignum=... to select the bignum backend. It's only used to
select the native backend, and this can be done with the +native_bignum
flavour transformer.
Additionally, we automatically enable +native_bignum for the JS target
because the GMP backend isn't supported.
- - - - -
a3ac7074 by Sylvain Henry at 2026-03-06T06:35:17-05:00
JS: fix putEnum/fromEnum (#24593)
Don't go through Word16 when serializing Enums.
- - - - -
0b36e96c by Andreas Klebinger at 2026-03-06T06:35:58-05:00
Docs: Document -fworker-wrapper-cbv default setting.
Fixes #26841
- - - - -
eca445e7 by mangoiv at 2026-03-07T05:02:36-05:00
drop deb9/10 from CI, add deb13
debian 9 and 10 are end of life, hence we drop them
from our CI, but we do add debian 13. Jobs that were
previously run on 9 and 10 run on 13, too, jobs that
were run on 10, are run on 11 now. Jobs that were
previously run on debian 12 are run on debian 13 now.
This MR also updates hadrian's bootstrap plans for that
reason.
Metric Decrease:
T9872d
- - - - -
12f8b829 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Fix GHC.Internal.Prim haddock
Haddock used to parse Haskell source to generate documentation,
but switched to using interface files instead. This broke documentation
of the GHC.Internal.Prim module, since it's a wired-in interface that
didn't provide a document structure.
This patch adds the missing document structure and updates genprimopcode
to make the section headers and descriptions available.
fixes #26954
- - - - -
f87e5e57 by Luite Stegeman at 2026-03-07T05:03:33-05:00
Remove obsolete --make-haskell-source from genprimopcode
Now that haddock uses the wired-in interface for GHC.Internal.Prim,
the generated Haskell source file is no longer needed. Remove the
--make-haskell-source code generator from genprimopcode and replace
the generated GHC/Internal/Prim.hs with a minimal static source file.
- - - - -
4a7ddc7b by Sylvain Henry at 2026-03-07T05:04:59-05:00
JS: fix linking of exposed but non-preload units (#24886)
Units exposed in the unit database but not explicitly passed on the
command-line were not considered by the JS linker. This isn't an issue
for cabal which passes every unit explicitly but it is an issue when
using GHC directly (cf T24886 test).
- - - - -
689aafcd by mangoiv at 2026-03-07T05:05:52-05:00
testsuite: double foundation timeout multiplier
The runtime timeout in the foundation test was regularly hit by code
generated by the wasm backend - we increase the timout since the high
runtime is expected on the wasm backend for this rather complex test.
Resolves #26938
- - - - -
d1a3686b by Peter Trommler at 2026-03-08T17:05:36+01:00
Fix conditional branch in atomicRMW ops
- - - - -
496e2945 by Peter Trommler at 2026-03-08T17:05:36+01:00
Add ORC instruction
- - - - -
0ebe8e2f by Peter Trommler at 2026-03-08T17:05:36+01:00
Draft of atomic RMW at smaller sizes
- - - - -
60fd1585 by Peter Trommler at 2026-03-08T17:05:36+01:00
Fix W32 and W64 case, move to dst register
- - - - -
39556ad0 by Peter Trommler at 2026-03-08T17:05:36+01:00
Fix masked_other
- - - - -
3d1599f2 by Peter Trommler at 2026-03-08T17:05:36+01:00
Fix build_result
- - - - -
4f647863 by Peter Trommler at 2026-03-08T17:05:36+01:00
testsuite: mark T9015 `req_interp`
The test does not require the RTS linker (req_rts_linker), support
for GHCi (req_interp) is sufficient.
- - - - -
5e88e151 by Peter Trommler at 2026-03-08T17:05:36+01:00
Fix shift amount on big endian (sic!)
- - - - -
f184ef98 by Peter Trommler at 2026-03-08T17:05:36+01:00
Fix build result
- - - - -
6c16604d by Peter Trommler at 2026-03-08T17:05:36+01:00
PPC NCG: print tab after clr(l|r)i instr
- - - - -
285f04e4 by Peter Trommler at 2026-03-08T17:05:36+01:00
Refactor and implement small constants for W32/W64
- - - - -
b29b790c by Peter Trommler at 2026-03-08T17:05:36+01:00
Optimize AMO_And
- - - - -
683b9ae8 by Peter Trommler at 2026-03-08T17:05:36+01:00
Refactor mask inversion
- - - - -
f3aa8d10 by Peter Trommler at 2026-03-08T17:05:36+01:00
Optimize OR and XOR and more refactoring
- - - - -
2ffc6e84 by Peter Trommler at 2026-03-08T17:05:36+01:00
Some more refactoring
- - - - -
5f25f2d5 by Peter Trommler at 2026-03-08T17:05:36+01:00
Untangle atomic MOs
- - - - -
d02e9b4d by Peter Trommler at 2026-03-08T17:05:36+01:00
And yet more refactoring
- - - - -
982ca8a0 by Peter Trommler at 2026-03-13T20:59:50+01:00
Refactor small sizes
- - - - -
297 changed files:
- .gitlab-ci.yml
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/Instr.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- + compiler/GHC/Rename/Lit.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Interpreter/Wasm.hs
- compiler/GHC/StgToCmm/Expr.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Error.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- + docs/users_guide/exts/qualified_strings.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/wasm.rst
- hadrian/README.md
- hadrian/bootstrap/generate_bootstrap_plans
- hadrian/bootstrap/plan-9_10_1.json
- hadrian/bootstrap/plan-9_10_2.json
- + hadrian/bootstrap/plan-9_10_3.json
- hadrian/bootstrap/plan-bootstrap-9_10_1.json
- hadrian/bootstrap/plan-bootstrap-9_10_2.json
- + hadrian/bootstrap/plan-bootstrap-9_10_3.json
- hadrian/src/CommandLine.hs
- hadrian/src/Main.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/GenPrimopCode.hs
- libraries/base/changelog.md
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/System/Info.hs
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Version.hs-boot
- libraries/ghc-internal/src/GHC/Internal/Event/Windows/ManagedThreadPool.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs
- + libraries/ghc-internal/src/GHC/Internal/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode.hs
- libraries/ghc-internal/src/GHC/Internal/Unicode/Version.hs
- libraries/ghc-internal/tools/ucd2haskell/exe/UCD2Haskell/ModuleGenerators.hs
- rts/Linker.c
- rts/LinkerInternals.h
- rts/linker/Elf.c
- rts/linker/MachO.c
- rts/linker/PEi386.c
- testsuite/driver/perf_notes.py
- testsuite/tests/codeGen/should_compile/debug.stdout
- + testsuite/tests/codeGen/should_fail/T26958.hs
- testsuite/tests/codeGen/should_fail/all.T
- + testsuite/tests/dependent/should_fail/SelfDepCls.hs
- + testsuite/tests/dependent/should_fail/SelfDepCls.stderr
- testsuite/tests/dependent/should_fail/all.T
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/T4437.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/ghc-api/annotations-literals/literals.stdout
- testsuite/tests/ghc-api/annotations-literals/parsed.hs
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- + testsuite/tests/javascript/T24886.hs
- + testsuite/tests/javascript/T24886.stderr
- + testsuite/tests/javascript/T24886.stdout
- testsuite/tests/javascript/all.T
- − testsuite/tests/linear/should_compile/LinearListComprehension.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/T25081.hs
- testsuite/tests/linear/should_fail/T25081.stderr
- testsuite/tests/module/all.T
- + testsuite/tests/module/mod70b.hs
- + testsuite/tests/module/mod70b.stderr
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/overloadedrecflds/should_compile/all.T
- testsuite/tests/overloadedrecflds/should_run/all.T
- + testsuite/tests/parser/should_fail/NoBlockArgumentsFail4.hs
- + testsuite/tests/parser/should_fail/NoBlockArgumentsFail4.stderr
- testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.hs
- testsuite/tests/parser/should_fail/NoBlockArgumentsFailArrowCmds.stderr
- + testsuite/tests/parser/should_fail/NoDoAndIfThenElseArrowCmds.hs
- + testsuite/tests/parser/should_fail/NoDoAndIfThenElseArrowCmds.stderr
- + testsuite/tests/parser/should_fail/T26860ppr_overloaded.hs
- + testsuite/tests/parser/should_fail/T26860ppr_overloaded.stderr
- + testsuite/tests/parser/should_fail/T26860ppr_tylit.hs
- + testsuite/tests/parser/should_fail/T26860ppr_tylit.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/parser/should_fail/badRuleMarker.hs
- + testsuite/tests/parser/should_fail/badRuleMarker.stderr
- + testsuite/tests/parser/should_fail/patFail010.hs
- + testsuite/tests/parser/should_fail/patFail010.stderr
- + testsuite/tests/parser/should_fail/patFail011.hs
- + testsuite/tests/parser/should_fail/patFail011.stderr
- + testsuite/tests/parser/should_fail/precOutOfRange.hs
- + testsuite/tests/parser/should_fail/precOutOfRange.stderr
- + testsuite/tests/parser/should_fail/unpack_data_con.hs
- + testsuite/tests/parser/should_fail/unpack_data_con.stderr
- testsuite/tests/patsyn/should_fail/T10426.stderr
- testsuite/tests/patsyn/should_fail/all.T
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail1.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail1.stderr
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail2.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail2.stderr
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail3.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail3.stderr
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail4.hs
- + testsuite/tests/patsyn/should_fail/patsyn_where_fail4.stderr
- testsuite/tests/pmcheck/should_compile/T11303.hs
- + testsuite/tests/qualified-strings/Makefile
- + testsuite/tests/qualified-strings/should_compile/Example/Length.hs
- + testsuite/tests/qualified-strings/should_compile/all.T
- + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.hs
- + testsuite/tests/qualified-strings/should_compile/qstrings_redundant_pattern.stderr
- + testsuite/tests/qualified-strings/should_fail/Example/Length.hs
- + testsuite/tests/qualified-strings/should_fail/Makefile
- + testsuite/tests/qualified-strings/should_fail/all.T
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_expr.stderr
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_bad_pat.stderr
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.stderr
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringAscii.hs
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringUtf8.hs
- + testsuite/tests/qualified-strings/should_run/Example/Text.hs
- + testsuite/tests/qualified-strings/should_run/Makefile
- + testsuite/tests/qualified-strings/should_run/all.T
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_th.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_th.stdout
- testsuite/tests/quasiquotation/qq005/test.T
- testsuite/tests/quasiquotation/qq006/test.T
- testsuite/tests/rts/linker/Makefile
- + testsuite/tests/rts/linker/T6107.hs
- + testsuite/tests/rts/linker/T6107.stdout
- + testsuite/tests/rts/linker/T6107_sym1.s
- + testsuite/tests/rts/linker/T6107_sym2.s
- testsuite/tests/rts/linker/all.T
- testsuite/tests/saks/should_compile/all.T
- testsuite/tests/showIface/all.T
- testsuite/tests/simd/should_run/doublex2_arith.hs
- testsuite/tests/simd/should_run/doublex2_arith.stdout
- testsuite/tests/simd/should_run/doublex2_arith_baseline.hs
- testsuite/tests/simd/should_run/doublex2_arith_baseline.stdout
- testsuite/tests/simd/should_run/floatx4_arith.hs
- testsuite/tests/simd/should_run/floatx4_arith.stdout
- testsuite/tests/simd/should_run/floatx4_arith_baseline.hs
- testsuite/tests/simd/should_run/floatx4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int16x8_arith.hs
- testsuite/tests/simd/should_run/int16x8_arith.stdout
- testsuite/tests/simd/should_run/int16x8_arith_baseline.hs
- testsuite/tests/simd/should_run/int16x8_arith_baseline.stdout
- testsuite/tests/simd/should_run/int32x4_arith.hs
- testsuite/tests/simd/should_run/int32x4_arith.stdout
- testsuite/tests/simd/should_run/int32x4_arith_baseline.hs
- testsuite/tests/simd/should_run/int32x4_arith_baseline.stdout
- testsuite/tests/simd/should_run/int64x2_arith.hs
- testsuite/tests/simd/should_run/int64x2_arith.stdout
- testsuite/tests/simd/should_run/int64x2_arith_baseline.hs
- testsuite/tests/simd/should_run/int64x2_arith_baseline.stdout
- testsuite/tests/simd/should_run/int8x16_arith.hs
- testsuite/tests/simd/should_run/int8x16_arith.stdout
- testsuite/tests/simd/should_run/int8x16_arith_baseline.hs
- testsuite/tests/simd/should_run/int8x16_arith_baseline.stdout
- + testsuite/tests/simplCore/should_compile/T26642.hs
- + testsuite/tests/simplCore/should_compile/TrickyJoins.hs
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/th/T26862_th.script
- + testsuite/tests/th/T26862_th.stderr
- + testsuite/tests/th/T8306_th.script
- + testsuite/tests/th/T8306_th.stderr
- + testsuite/tests/th/T8306_th.stdout
- testsuite/tests/th/T8412.stderr
- + testsuite/tests/th/TH_EmptyLamCases.hs
- + testsuite/tests/th/TH_EmptyLamCases.stderr
- + testsuite/tests/th/TH_EmptyMultiIf.hs
- + testsuite/tests/th/TH_EmptyMultiIf.stderr
- testsuite/tests/th/all.T
- + testsuite/tests/typecheck/should_fail/T26861.hs
- + testsuite/tests/typecheck/should_fail/T26861.stderr
- + testsuite/tests/typecheck/should_fail/T26862.hs
- + testsuite/tests/typecheck/should_fail/T26862.stderr
- testsuite/tests/typecheck/should_fail/T8306.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/all.T
- + testsuite/tests/unboxedsums/unboxedsums4p.hs
- + testsuite/tests/unboxedsums/unboxedsums4p.stderr
- testsuite/tests/vdq-rta/should_compile/all.T
- + testsuite/tests/warnings/should_compile/SpecMultipleTysMono.hs
- + testsuite/tests/warnings/should_compile/SpecMultipleTysMono.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/genprimopcode/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5cca0826144f3a3b0dfc226610fc81…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5cca0826144f3a3b0dfc226610fc81…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/text-read-uncovering] 6 commits: Move the `System.IO` implementation into `base`
by Wolfgang Jeltsch (@jeltsch) 13 Mar '26
by Wolfgang Jeltsch (@jeltsch) 13 Mar '26
13 Mar '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/text-read-uncovering at Glasgow Haskell Compiler / GHC
Commits:
a662500a by Wolfgang Jeltsch at 2026-03-13T21:54:17+02:00
Move the `System.IO` implementation into `base`
- - - - -
aef95363 by Wolfgang Jeltsch at 2026-03-13T21:54:59+02:00
Move I/O-related `Read` instances into `base`
- - - - -
9c4f1965 by Wolfgang Jeltsch at 2026-03-13T21:54:59+02:00
Move most of the `Numeric` implementation into `base`
The `showHex` operation and the `showIntAtBase` operation, which
underlies it, are kept in `GHC.Internal.Numeric`, because `showHex` is
used in a few places in `ghc-internal`; everything else is moved.
- - - - -
da270ba5 by Wolfgang Jeltsch at 2026-03-13T21:54:59+02:00
Move the instance `Read ByteOrder` into `base`
- - - - -
9d648f5a by Wolfgang Jeltsch at 2026-03-13T21:54:59+02:00
Move the implementation of version parsing into `base`
- - - - -
c72dc2f4 by Wolfgang Jeltsch at 2026-03-13T21:54:59+02:00
Move the implementation of `readConstr` into `base`
- - - - -
32 changed files:
- libraries/base/src/Data/Data.hs
- libraries/base/src/Data/Version.hs
- libraries/base/src/GHC/ByteOrder.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/Numeric.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/Text/Printf.hs
- libraries/ghc-internal/src/GHC/Internal/ByteOrder.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Device.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/IOMode.hs
- libraries/ghc-internal/src/GHC/Internal/Numeric.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.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/plugins/plugins09.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/plugins/plugins11.stdout
- testsuite/tests/plugins/static-plugins.stdout
- testsuite/tests/typecheck/should_compile/T9497a.stderr
- testsuite/tests/typecheck/should_compile/holes.stderr
- testsuite/tests/typecheck/should_compile/holes3.stderr
- testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/T9497d.stderr
- testsuite/tests/typecheck/should_run/T9497a-run.stderr
- testsuite/tests/typecheck/should_run/T9497b-run.stderr
- testsuite/tests/typecheck/should_run/T9497c-run.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96892ac7d618ed6dc2ecf0631b3f22…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96892ac7d618ed6dc2ecf0631b3f22…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/fix-base-redundant-imports
by Cheng Shao (@TerrorJack) 13 Mar '26
by Cheng Shao (@TerrorJack) 13 Mar '26
13 Mar '26
Cheng Shao pushed new branch wip/fix-base-redundant-imports at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix-base-redundant-imports
You're receiving this email because of your account on gitlab.haskell.org.
1
0