Simon Jakobi pushed to branch wip/sjakobi/lazy-field-anns at Glasgow Haskell Compiler / GHC Commits: 67d41299 by Sebastian Graf at 2026-06-18T05:18:24-04:00 Desugar a `case` scrutinee only once (#27383, #20251) In `dsExpr` for `HsCase` we desugared the scrutinee /twice/: once to build the Core `case` itself, and again inside `matchWrapper`, which re-desugared the source scrutinee (via `addHsScrutTmCs`) purely to record long-distance information for the pattern-match checker. For a single `case` that is merely wasteful. But for nested cases it is catastrophic. Consider case (case (case e of ... ) of ... ) of ... Desugaring the outer scrutinee desugars the middle `case` twice, each of which desugars the inner `case` twice, and so on. The work doubles at every level, so desugaring takes O(2^n) time in the nesting depth. That is the blowup reported in #27383; it is also what makes the machine-generated program in #20251 take an age to compile. The fix is simple. `matchWrapper` is handed the scrutinee anyway, so we give it the Core expression we have /already/ desugared, and record the long-distance term constraint with `addCoreScrutTmCs` instead of re-desugaring from source. This is just what `matchSinglePatVar` already does for single-pattern matches. So: * `matchWrapper` now takes `Maybe [CoreExpr]` rather than `Maybe [LHsExpr GhcTc]`. * The `HsCase` equation of `dsExpr` passes the already-desugared `core_discrim`; the arrow desugarer passes its match variables. * `addHsScrutTmCs` had no other use, so it is gone. Desugaring is now linear in the nesting depth. (The coverage checker still runs `simpleOptExpr` over each scrutinee, which leaves the total at O(n^2); that is ample.) The long-distance information itself is unchanged: the checker sees precisely the Core that backs the generated code. Test: deSugar/should_compile/T27383 - - - - - fa5defde by Rodrigo Mesquita at 2026-06-18T05:19:11-04:00 fix: Save FastStrings in the PMC There is no point in adding the unique to the occurrence FastString we create, since it is part of the Id anyway. Adding it to the FastString, meant each FastString was unique unnecessarily! In a separate branch, running the compiler on test `InstanceMatching` observed 30000 `FastString`s created by this code path. Plus, `fsLit "pm"` follows the existing pattern in `mkPmId`. - - - - - 4efb4a66 by Alan Zimmerman at 2026-06-18T14:41:14-04:00 TTG: Add extension points to HsConDetails Extend HsConDetails as data HsConDetails p arg rec = PrefixCon !(XPrefixCon p) [arg] -- C @t1 @t2 p1 p2 p3 | RecCon !(XRecCon p) rec -- C { x = p1, y = p2 } | InfixCon !(XInfixCon p) arg arg -- p1 `C` p2 | XHsConDetails !(XXHsConDetails p) type family XPrefixCon p type family XRecCon p type family XInfixCon p type family XXHsConDetails p - - - - - c8d27dd4 by Simon Jakobi at 2026-06-18T14:41:59-04:00 CI: quiet submodule clean output in after_script and setup The clean and cleanup_submodules functions ran 'git submodule foreach git clean -xdf', flooding the job log with 'Entering ...' and 'Removing ...' lines. Pass --quiet to 'git submodule' and -q to 'git clean' to drop the success output; errors are still reported. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> - - - - - 09326ca6 by Matthew Pickering at 2026-06-20T23:41:12+02:00 Add missing req_interp modifier to T18441fail3 and T18441fail19 These tests require the interpreter but they were failing in a different way with the javascript backend because the interpreter was disabled and stderr is ignored by the test. - - - - - 521e55bf by Matthew Pickering at 2026-06-20T23:41:13+02:00 hadrian: Fill in more of the default.host toolchain file When you are building a cross compiler this file will be used to build stage1 and it's libraries, so we need enough information here to work accurately. There is still more work to be done (see for example, word size is still fixed). - - - - - 23c9b6c3 by Matthew Pickering at 2026-06-20T23:42:52+02:00 hadrian: Build stage 2 cross compilers * Most of hadrian is abstracted over the stage in order to remove the assumption that the target of all stages is the same platform. This allows the RTS to be built for two different targets for example. * Abstracts the bindist creation logic to allow building either normal or cross bindists. Normal bindists use stage 1 libraries and a stage 2 compiler. Cross bindists use stage 2 libararies and a stage 2 compiler. * hadrian: Make binary-dist-dir the default build target. This allows us to have the logic in one place about which libraries/stages to build with cross compilers. Fixes #24192 New hadrian target: * `binary-dist-dir-cross`: Build a cross compiler bindist (compiler = stage 1, libraries = stage 2) This commit also contains various changes to make stage2 compilers feasible. ------------------------- Metric Decrease: LinkableUsage02 ManyAlternatives ManyConstructors MultiComponentModulesRecomp MultiLayerModulesRecomp RecordUpdPerf T10421 T12150 T12227 T12425 T12707 T13035 T13379 T13820 T15703 T16577 T18140 T18282 T18698a T18698b T18923 T1969 T20049 T21839c T3294 T4801 T5030 T5321FD T5321Fun T5631 T5642 T6048 T783 T9020 T9198 T9233 T9630 T9872d T9961 parsing001 T3064 Metric Increase: T26989 hard_hole_fits ------------------------- Co-authored-by: Sven Tennie <sven.tennie@gmail.com> - - - - - 26fed8ab by Matthew Pickering at 2026-06-20T23:42:52+02:00 ci: Test cross bindists We remove the special logic for testing in-tree cross compilers and instead test cross compiler bindists, like we do for all other platforms. - - - - - 80c8910e by Matthew Pickering at 2026-06-20T23:42:52+02:00 ci: Introduce CROSS_STAGE variable In preparation for building and testing stage3 bindists we introduce the CROSS_STAGE variable which is used by a CI job to determine what kind of bindist the CI job should produce. At the moment we are only using CROSS_STAGE=2 but in the future we will have some jobs which set CROSS_STAGE=3 to produce native bindists for a target, but produced by a cross compiler, which can be tested on by another CI job on the native platform. CROSS_STAGE=2: Build a normal cross compiler bindist CROSS_STAGE=3: Build a stage 3 bindist, one which is a native compiler and library for the target - - - - - 8215573d by Sven Tennie at 2026-06-20T23:42:52+02:00 ci: Increase timeout for emulators Test runs with emulators naturally take longer than on native machines. Generate jobs.yml - - - - - 5acb7dbc by Matthew Pickering at 2026-06-20T23:42:52+02:00 ci: Javascript don't set CROSS_EMULATOR There is no CROSS_EMULATOR needed to run javascript binaries, so we don't set the CROSS_EMULATOR to some dummy value. - - - - - 48345343 by Sven Tennie at 2026-06-20T23:42:52+02:00 Javascript skip T23697 See #22355 about how HSC2HS and the Javascript target don't play well together. - - - - - 5e44fd05 by Sven Tennie at 2026-06-20T23:42:52+02:00 Mark T24602 as fragile It was skipped before (due to CROSS_EMULATOR being set, which changed for JS), so we don't make things worse by marking it as fragile. - - - - - ab349ec2 by Sven Tennie at 2026-06-20T23:42:52+02:00 Fix T22744 for GHCJS In fact, this test needs Template Haskell, not necessarily an interpreter. - - - - - c73352d8 by Sven Tennie at 2026-06-20T23:42:52+02:00 haddock-test: fix GHCJS haddock test failures Add --ghc-pkg-path flag support so haddock test runner can find cross-prefixed ghc-pkg (e.g. javascript-unknown-ghcjs-ghc-pkg) which is not on $PATH in cross install directories. Skip haddockHtmlTest on GHCJS: Threaded.hs uses forkOS in a TH splice, which GHCJS RTS doesn't support. Mark with js_skip in all.T. - - - - - 5e814e76 by Andreas Klebinger at 2026-06-22T23:00:24-04:00 compiler: Deduplicate hscTidy This function was accidentally duplicated during a refactor. Fixes #27351 - - - - - 473b97eb by sheaf at 2026-06-22T23:01:22-04:00 Avoid mkTick in Core Prep breaking ANF (part II) Hotfix for 2f9579765f55b3920ceb2e04995ff41a9d0e2d4e fixing a small oversight in the call to tickTickedExpr from mkTick, in which we improperly recursively called mkTick without passing on the preserve_anf flag. Fixes #27386 - - - - - 9284a1f7 by Simon Hengel at 2026-06-23T05:55:33-04:00 Don't use global variables to address concurrency bugs! (fixes #27234) This was originally introduce with 88f38b03025386f0f1e8f5861eed67d80495168a to address #17922. In this specific case a better fix would have been to synchronize on stderr: withHandle_ "stderrSupportsAnsiColors" stderr $ \ _ -> do ... But apparently the dependency on `terminfo` was removed in 32ab07bf3d6ce45e8ea5b55e8095174a6b42a7f0, preventing #17922 in the first place. - - - - - 44309cd3 by Alan Zimmerman at 2026-06-23T05:56:20-04:00 EPA: remove LocatedL / SrcSpanAnnL and LocatedLI / SrcSpanAnnLI This is part of a refactor towards only having LocatedA / SrcSpanAnnA It removes the stated items, but has to add back one for BooleanFormula, LocatedBF / SrcSpanAnnBF This commit also use the HsConDetails RecCon extension point to capture the braces in a record constructor - - - - - dc63db45 by Simon Jakobi at 2026-06-24T13:40:25+02:00 Add -XLazyFieldAnnotations Unbundle the prefix `~` lazy field annotation syntax from StrictData. The new LazyFieldAnnotations extension controls only whether `~` is accepted on data and GADT constructor fields; StrictData (and hence Strict) implies it but continues to own the default strictness of unannotated fields. This lets hand-written and generated code write an explicit lazy annotation without flipping the module-wide default. The validity check in checkValidDataCon now keys off LazyFieldAnnotations instead of StrictData. Implements ghc-proposals #752. Closes #24455. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> - - - - - 184 changed files: - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - + changelog.d/T27386 - + changelog.d/fix-exponential-case-desugar-27383 - + changelog.d/stage2-cross-compilers - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main/Interactive.hs - compiler/GHC/Driver/Main/Passes.hs - compiler/GHC/Driver/Main/Passes.hs-boot - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Dump.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Stats.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Match.hs-boot - compiler/GHC/HsToCore/Match/Constructor.hs - compiler/GHC/HsToCore/Pmc.hs - compiler/GHC/HsToCore/Pmc/Desugar.hs - compiler/GHC/HsToCore/Pmc/Solver.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Annotation.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/SysTools/Terminal.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax.hs - compiler/Language/Haskell/Syntax/Binds.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/ImpExp.hs - compiler/Language/Haskell/Syntax/Pat.hs - compiler/Language/Haskell/Syntax/Type.hs - configure.ac - distrib/configure.ac.in - + docs/users_guide/changelog.d/lazy-field-annotations - docs/users_guide/exts/strict.rst - ghc/GHCi/UI.hs - hadrian/README.md - hadrian/bindist/config.mk.in - hadrian/cfg/default.host.target.in - + hadrian/cfg/system.config.host.in - hadrian/cfg/system.config.in - + hadrian/cfg/system.config.target.in - hadrian/hadrian.cabal - hadrian/src/Base.hs - + hadrian/src/BindistConfig.hs - hadrian/src/Builder.hs - hadrian/src/Context.hs - hadrian/src/Expression.hs - hadrian/src/Flavour.hs - hadrian/src/Flavour/Type.hs - hadrian/src/Hadrian/Builder.hs - hadrian/src/Hadrian/Haskell/Hash.hs - hadrian/src/Hadrian/Oracles/TextFile.hs - hadrian/src/Main.hs - hadrian/src/Oracles/Flag.hs - hadrian/src/Oracles/Flavour.hs - hadrian/src/Oracles/Setting.hs - hadrian/src/Oracles/TestSettings.hs - hadrian/src/Packages.hs - hadrian/src/Rules.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Changelog.hs - hadrian/src/Rules/Compile.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/Gmp.hs - hadrian/src/Rules/Library.hs - hadrian/src/Rules/Program.hs - hadrian/src/Rules/Register.hs - hadrian/src/Rules/Rts.hs - hadrian/src/Rules/Test.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Builders/Common.hs - hadrian/src/Settings/Builders/Configure.hs - hadrian/src/Settings/Builders/DeriveConstants.hs - hadrian/src/Settings/Builders/Ghc.hs - hadrian/src/Settings/Builders/Hsc2Hs.hs - hadrian/src/Settings/Builders/RunTest.hs - hadrian/src/Settings/Builders/SplitSections.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Flavours/GhcInGhci.hs - hadrian/src/Settings/Flavours/Performance.hs - hadrian/src/Settings/Flavours/QuickCross.hs - hadrian/src/Settings/Packages.hs - hadrian/src/Settings/Program.hs - hadrian/src/Settings/Warnings.hs - libraries/base/tests/all.T - libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs - m4/fp_find_nm.m4 - m4/prep_target_file.m4 - testsuite/ghc-config/ghc-config.hs - + testsuite/tests/deSugar/should_compile/T27383.hs - testsuite/tests/deSugar/should_compile/all.T - + testsuite/tests/deSugar/should_run/LazyFieldAnnotationsSemantics.hs - + testsuite/tests/deSugar/should_run/LazyFieldAnnotationsSemantics.stdout - testsuite/tests/deSugar/should_run/all.T - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/ghc-e/should_fail/all.T - testsuite/tests/haddock/haddock_testsuite/Makefile - testsuite/tests/haddock/haddock_testsuite/all.T - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/javascript/closure/all.T - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr - testsuite/tests/parser/should_compile/T20846.stderr - testsuite/tests/parser/should_compile/T23315/T23315.stderr - testsuite/tests/perf/compiler/all.T - testsuite/tests/printer/AnnotationNoListTuplePuns.stdout - testsuite/tests/printer/T18791.stderr - testsuite/tests/printer/Test10309.hs - testsuite/tests/printer/Test20297.stdout - testsuite/tests/printer/Test24533.stdout - + testsuite/tests/profiling/should_compile/T27386.hs - testsuite/tests/profiling/should_compile/all.T - + testsuite/tests/typecheck/should_compile/LazyFieldAnnotations.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/LazyFieldsDisabled.stderr - + testsuite/tests/typecheck/should_fail/LazyFieldsDisabledStrictData.hs - + testsuite/tests/typecheck/should_fail/LazyFieldsDisabledStrictData.stderr - testsuite/tests/typecheck/should_fail/all.T - utils/check-exact/ExactPrint.hs - utils/check-exact/Main.hs - utils/check-exact/Utils.hs - utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.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/GhcUtils.hs - utils/haddock/haddock-api/src/Haddock/Interface/Create.hs - utils/haddock/haddock-api/src/Haddock/Interface/LexParseRn.hs - utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs - utils/haddock/haddock-api/src/Haddock/Types.hs - utils/haddock/haddock-test/src/Test/Haddock/Config.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5bf8e92af16f5cb675594a4cf26afa1... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5bf8e92af16f5cb675594a4cf26afa1... You're receiving this email because of your account on gitlab.haskell.org.