Duncan Coutts pushed to branch wip/dcoutts/io-manager-io-primop-exceptions at Glasgow Haskell Compiler / GHC Commits: eaa95a6f by Andrei Borzenkov at 2026-09-04T08:08:40-04:00 Parentheses in prefix GADT constructors (#27423) Updated `splitLHsGadtTy` to allow looking through the parentheses for inner binders. General example of a code pattern that's allowed now: data S a where MkS :: (forall a. S a) That should work now with any combination of nested foralls and parentheses. We don't perform parenthesis unwrapping for record GADT constructors in accordance with GHC Proposal #402. To this end `con_inner_bndrs` no longer stores plain forall telescopes: `[HsForAllTelescope pass]` is replaced with `[LHsGadtTelescope pass]`, a new `HsArg`-style type whose `HsGadtForAll` holds an inner telescope and whose `HsGadtPar` holds a pair of parentheses. The parentheses carry no meaning for renaming or type checking; the only reason to record them is exact-printing. Updated `pprConDecl` to improve the `parse == parse . ppr . parse` property of GADT pretty-printing. The pretty printer can now output code that's similar to this: data T a where MkT1 :: (forall a. T a) MkT2 :: forall . forall a. T a These are special cases of inner forall binders for prefix GADT constructors, when we have either implicit or zero explicit outer binders. - - - - - 639456a8 by Evgeny Malyshev at 2026-09-04T08:09:25-04:00 HsPat: Add spacing to unary tuple patterns Use hsep when printing unary boxed TuplePat applications so that the MkSolo constructor is separated from its argument. The old hcat rendered wildcard and parenthesized arguments as MkSolo_ and MkSolo(). Add T27034 to exercise the HsPat splice-dump path with wildcard and variable arguments, and update existing affected golden output. Fixes #27034 Assisted-By: OpenAI Codex - - - - - 2908ab36 by Simon Jakobi at 2026-09-05T07:22:17-04:00 X86 NCG: use btr/bts/btc for single-bit operations Previously the Cmm patterns x & ~(1 << i) x | (1 << i) x ^ (1 << i) compiled to mov/shl/not/and-style sequences of 3-4 instructions. Now they compile to a single btr, bts or btc, matching what C compilers produce. When the bit index is a literal, constant folding has already collapsed these patterns into ones with a literal mask, such as x & 0xfffffeffffffffff for x & ~(1 << 40). Such masks are now also compiled to a bit-test instruction when they don't fit in an imm32 and would otherwise have to be loaded into a register first. For a variable bit index, this applies only when the shift is unchecked (uncheckedShiftL#, Data.Bits.unsafeShiftL): the bounds-checked shiftL used by e.g. the default clearBit/setBit/complementBit implementations wraps the shift in a bounds mask that this optimisation does not see through. With a literal index, the bounds mask is constant-folded away, so the checked operations benefit too. See Note [Bit-test instructions] in GHC.CmmToAsm.X86.CodeGen. Fixes #25233. Assisted-by: Claude Fable 5 - - - - - c673ecf0 by Simon Peyton Jones at 2026-09-05T07:22:59-04:00 Move HsStatic free-var test to typechecker A `static` form should have no free *term* variables, but it can have free *type* variables. Alas, the renamer does not really know what is a term variable and what is a type variable, because of required type arguments. This patch moves the test to the typechecker, which does know. Addresses #27664 - - - - - 5939ceaf by sheaf at 2026-09-05T22:06:18-04:00 Windows: enforce path convention in ./configure As detailed in Note [MSYS paths] in Hadrian.Utilities, the standing convention (using Windows-style paths with forward slashes) is now enforced in ./configure instead of within Hadrian, removing the need for 'cygpath' calls within Hadrian. Fixes #26683 - - - - - a6061455 by sheaf at 2026-09-05T22:06:18-04:00 Hadrian: introduce ExeSpawnPath Specific details about the filepath used to specify the executable to spawn with CreateProcess matters on Windows: whether we use forward or backward slashes, a leading ./, or an absolute path changes how the executable is found. This commit introduces 'ExeSpawnPath' which is a path that is guaranteed to be found when spawning a process. All command invocations now go through this type to ensure the path has been properly sanitised. See Note [NeedCurrentDirectoryForExePath] in Hadrian.Utilities. The same treatment is applied to hsc2hs. Updates hsc2hs submodule. - - - - - e28313e3 by sheaf at 2026-09-05T22:07:06-04:00 Preserve tick ordering in 'tickTickedExpr' 'GHC.Core.Utils.tickTickedExpr' tries to combine a tick 't1' into an existing stack of ticks 't2s'. There are two situations: 1. 't1' is subsumed by a tick in 't2s': drop it. 2. A tick in 't2s' is subsumed by 't1', say 't2'. This commit ensures that in case (2) we keep 't1' on the outside instead of replacing 't2' at its position in the stack. This avoids re-ordering source notes (which was the cause of #27749). This fixes a regression introduced in 2dadf3b0d05. Fixes #27749 - - - - - 3172f557 by sheaf at 2026-09-05T22:07:06-04:00 Consistently prefer local source note ticks GHC.Cmm.DebugBlock.cmmDebugGen (DWARF annotations) and GHC.Stg.Debug.quickSourcePos (-finfo-table-map) both contained logic to prioritise source note ticks from the current module. This commit commons up this logic and propagates it to a third consumer: IPE stack frames, in GHC.Driver.GenerateCgIPEStub. See the new function GHC.Types.Tickish.bestSourceNote. - - - - - 192be0b6 by Luite Stegeman at 2026-09-07T19:43:36-04:00 rts: fix ctoi_tuple_spill_words getting out of sync Fix a few places that were not updating ctoi_tuple_spill_words correctly, leading to corruption/crashes when dealing with large unboxed tuples in bytecode: - captureContinuationAndAbort - findRetryFrameHelper/findAtomicallyFrameHelper - interpretBCO bci_BRK_FUN fixes #27633 - - - - - 604eb43c by Simon Jakobi at 2026-09-07T19:44:15-04:00 Hadrian: don't capture the testsuite driver's output (#27780) a6061455d54 switched the Testsuite RunTest case from Shake's cmd to the cmd' wrapper. cmd' always captures stdout and stderr, and since the caller asks for Exit, it returns without dumping what it captured. As a result the testsuite output no longer appears in CI job logs: failures, performance metrics and the summary were lost with the job. Use cmdExe, the uncaptured cmd, as the other plain-cmd sites in that commit do. Fixes #27780. Assisted-by: Claude Fable 5.1 - - - - - a20ccd7d by Duncan Coutts at 2026-09-08T10:15:44+01:00 Reorder cmm decls in HeapStackCheck for a better logical grouping And put more section headers in to deliniate the groups. We're about to add more here, so better to organise it first. - - - - - 4ac2f5dd by Duncan Coutts at 2026-09-08T10:15:44+01:00 Add raisePrimIOException and add it to RTS<->ghc-internal API The raisePrimIOException is a new helper function that I/O primops will use to help them report I/O errors. This is implemented in Haskell (since that's a lot easier), but has a calling convention that is easy(ish) to use from Cmm in the I/O primops. So we add it to the RTS API struct, and since we'll use it from Cmm we also need a field accessor macro for cmm (in deriveConstants). See the Note about how we cannot have nice things due to async exceptions and thunks preventing us from using catch. - - - - - cdd85f43 by Duncan Coutts at 2026-09-08T10:15:44+01:00 Add new blocking functions for I/O primops See the long Note. The point is, it will allow us to report synchronous exceptions from I/O primops, and do so much more flexibly. Previously the I/O managers could only report async exceptions and only nullary exceptions. This was OK historically, but no good as we add more I/O managers and expand the range of I/O operations we support. - - - - - be73402b by Duncan Coutts at 2026-09-08T10:15:44+01:00 Change the encoding of results from the I/O manager to I/O primops Previously we just had async continue or heap overflow. We now extend what we can report with synchronous success, and synchronous failure with an errno. See Note [Encoding of result of I/O manager operations] We don't use these two new cases yet, but we will. In particular an epoll I/O manager needs to be able to report synchronous success or failure for waitRead#/waitWrite#. - - - - - ac7ab60c by Duncan Coutts at 2026-09-08T10:15:44+01:00 Switch waitRead/Write# to use new blocking return frames and update the I/O managers to set the result before resuming the blocked threads. This makes it possible for I/O managers to report synchronous exceptions from the I/O primops, but that will be done in a subsequent commit. - - - - - 37c33024 by Duncan Coutts at 2026-09-08T10:15:44+01:00 Switch Poll and Select I/O managers to report sync exceptions rather than using raiseAsync with blockedOnBadFD_closure. This uses the new mechanism in the blocking frame return code to report synchronous exceptions. - - - - - 60a70959 by Duncan Coutts at 2026-09-08T10:15:44+01:00 Remove now-unused blockedOnBadFD It was previously thrown by the select and poll I/O managers, but now they use raisePrimIOException (with an EBADF errno). - - - - - 7b201feb by Duncan Coutts at 2026-09-08T10:15:44+01:00 Improve the docs for delay# waitRead# and waitWrite# Document that the waitRead/Write# can throw exceptions (this was true before too), and that all of them are async exception cancellation points. - - - - - 119 changed files: - + changelog.d/T27749 - + changelog.d/T27764 - + changelog.d/allow-gadt-prefix-con-parens - + changelog.d/ncg-x86-bit-test-instructions - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/GenerateCgIPEStub.hs - compiler/GHC/Driver/Main/Compile.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Tickish.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - configure.ac - docs/users_guide/exts/gadt_syntax.rst - hadrian/src/Base.hs - hadrian/src/Builder.hs - hadrian/src/Hadrian/Builder.hs - hadrian/src/Hadrian/Builder/Ar.hs - hadrian/src/Hadrian/Oracles/Path.hs - hadrian/src/Hadrian/Utilities.hs - hadrian/src/Oracles/Setting.hs - hadrian/src/Oracles/TestSettings.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Changelog.hs - hadrian/src/Rules/Codes.hs - hadrian/src/Rules/Lint.hs - hadrian/src/Rules/Nofib.hs - hadrian/src/Rules/Test.hs - libraries/ghc-internal/include/RtsIfaceSymbols.h - libraries/ghc-internal/src/GHC/Internal/Conc/IO.hs - libraries/ghc-internal/src/GHC/Internal/Event/Thread.hs - m4/find_python.m4 - + m4/fp_canonicalise_win_path.m4 - m4/fp_find_nm.m4 - m4/fp_find_root.m4 - m4/fp_prog_ar.m4 - m4/fp_prog_ar_args.m4 - m4/fp_prog_sh.m4 - m4/fptools_alex.m4 - m4/fptools_happy.m4 - rts/Continuation.c - rts/HeapStackCheck.cmm - rts/IOManager.c - rts/IOManager.h - rts/IOManagerInternals.h - rts/Interpreter.c - rts/Prelude.h - rts/PrimOps.cmm - rts/Schedule.c - rts/include/rts/RtsToHsIface.h - rts/include/stg/MiscClosures.h - rts/posix/Poll.c - rts/posix/Poll.h - rts/posix/Select.c - + testsuite/tests/bytecode/T27633/Obj.hs - + testsuite/tests/bytecode/T27633/T27633a.hs - + testsuite/tests/bytecode/T27633/T27633a.stdout - + testsuite/tests/bytecode/T27633/T27633b.hs - + testsuite/tests/bytecode/T27633/T27633b.stdout - + testsuite/tests/bytecode/T27633/all.T - + testsuite/tests/codeGen/should_gen_asm/T25233.asm - + testsuite/tests/codeGen/should_gen_asm/T25233.hs - + testsuite/tests/codeGen/should_gen_asm/T25233b.asm - + testsuite/tests/codeGen/should_gen_asm/T25233b.cmm - testsuite/tests/codeGen/should_gen_asm/all.T - − testsuite/tests/gadt/T14320.stderr - testsuite/tests/gadt/T18191.hs - testsuite/tests/gadt/T18191.stderr - + testsuite/tests/gadt/T27423a.hs - + testsuite/tests/gadt/T27423b.hs - + testsuite/tests/gadt/T27423b.stderr - testsuite/tests/gadt/all.T - + testsuite/tests/ghci.debugger/scripts/T27633c.hs - + testsuite/tests/ghci.debugger/scripts/T27633c.script - + testsuite/tests/ghci.debugger/scripts/T27633c.stdout - + testsuite/tests/ghci.debugger/scripts/T27633c_obj.hs - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/printer/Makefile - + testsuite/tests/printer/T27423c.hs - testsuite/tests/printer/all.T - testsuite/tests/rename/should_fail/RnStaticPointersFail01.stderr - testsuite/tests/rename/should_fail/RnStaticPointersFail03.stderr - testsuite/tests/rename/should_fail/T26545.stderr - + testsuite/tests/simplCore/should_compile/T27749.hs - + testsuite/tests/simplCore/should_compile/T27749.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/th/T17380.stderr - testsuite/tests/th/T18612.stderr - + testsuite/tests/th/T27034.hs - + testsuite/tests/th/T27034.stderr - testsuite/tests/th/T8761.stderr - testsuite/tests/th/all.T - + testsuite/tests/typecheck/should_compile/T27664.hs - testsuite/tests/typecheck/should_compile/all.T - utils/check-exact/ExactPrint.hs - utils/deriveConstants/Main.hs - utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs - utils/haddock/haddock-api/src/Haddock/Convert.hs - utils/haddock/haddock-api/src/Haddock/GhcUtils.hs - utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs - utils/haddock/haddock-api/src/Haddock/Types.hs - utils/hsc2hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1e3530939b9dbfe5b2335e07f053959... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1e3530939b9dbfe5b2335e07f053959... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help